📄 execute.c
字号:
bc_sub (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num); pop(); pop(); push_num (temp_num); init_num (&temp_num); } break; case '*' : /* multiply */ if (check_stack(2)) { bc_multiply (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num, scale); pop(); pop(); push_num (temp_num); init_num (&temp_num); } break; case '/' : /* divide */ if (check_stack(2)) { if (bc_divide (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num, scale) == 0) { pop(); pop(); push_num (temp_num); init_num (&temp_num); } else rt_error ("Divide by zero"); } break; case '%' : /* remainder */ if (check_stack(2)) { if (is_zero (ex_stack->s_num)) rt_error ("Modulo by zero"); else { bc_modulo (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num, scale); pop(); pop(); push_num (temp_num); init_num (&temp_num); } } break; case '^' : /* raise */ if (check_stack(2)) { bc_raise (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num, scale); if (is_zero (ex_stack->s_next->s_num) && is_neg (ex_stack->s_num)) rt_error ("divide by zero"); pop(); pop(); push_num (temp_num); init_num (&temp_num); } break; case '=' : /* compare equal */ if (check_stack(2)) { c_code = bc_compare (ex_stack->s_next->s_num, ex_stack->s_num) == 0; pop (); assign (c_code); } break; case '#' : /* compare not equal */ if (check_stack(2)) { c_code = bc_compare (ex_stack->s_next->s_num, ex_stack->s_num) != 0; pop (); assign (c_code); } break; case '<' : /* compare less than */ if (check_stack(2)) { c_code = bc_compare (ex_stack->s_next->s_num, ex_stack->s_num) == -1; pop (); assign (c_code); } break; case '{' : /* compare less than or equal */ if (check_stack(2)) { c_code = bc_compare (ex_stack->s_next->s_num, ex_stack->s_num) <= 0; pop (); assign (c_code); } break; case '>' : /* compare greater than */ if (check_stack(2)) { c_code = bc_compare (ex_stack->s_next->s_num, ex_stack->s_num) == 1; pop (); assign (c_code); } break; case '}' : /* compare greater than or equal */ if (check_stack(2)) { c_code = bc_compare (ex_stack->s_next->s_num, ex_stack->s_num) >= 0; pop (); assign (c_code); } break; default : /* error! */ rt_error ("bad instruction: inst=%c", inst); } } /* Clean up the function stack and pop all autos/parameters. */ while (pc.pc_func != 0) { pop_vars(functions[pc.pc_func].f_autos); pop_vars(functions[pc.pc_func].f_params); fpop (); pc.pc_addr = fpop (); pc.pc_func = fpop (); } /* Clean up the execution stack. */ while (ex_stack != NULL) pop(); /* Clean up the interrupt stuff. */ if (interactive) { signal (SIGINT, use_quit); if (had_sigint) printf ("Interruption completed.\n"); }}/* Prog_char gets another byte from the program. It is used for conversion of text constants in the code to numbers. */charprog_char (){ return byte(&pc);}/* Read a character from the standard input. This function is used by the "read" function. */charinput_char (){ char in_ch; /* Get a character from the standard input for the read function. */ in_ch = getchar(); /* Check for a \ quoted newline. */ if (in_ch == '\\') { in_ch = getchar(); if (in_ch == '\n') in_ch = getchar(); } /* Classify and preprocess the input character. */ if (isdigit(in_ch)) return (in_ch - '0'); if (in_ch >= 'A' && in_ch <= 'F') return (in_ch + 10 - 'A'); if (in_ch >= 'a' && in_ch <= 'f') return (in_ch + 10 - 'a'); if (in_ch == '.' || in_ch == '+' || in_ch == '-') return (in_ch); if (in_ch <= ' ') return (' '); return (':');}/* Push_constant converts a sequence of input characters as returned by IN_CHAR into a number. The number is pushed onto the execution stack. The number is converted as a number in base CONV_BASE. */voidpush_constant (in_char, conv_base) char (*in_char)(VOID); int conv_base;{ int digits; bc_num build, temp, result, mult, divisor; char in_ch, first_ch; char negative; /* Initialize all bc numbers */ init_num (&temp); init_num (&result); init_num (&mult); build = copy_num (_zero_); negative = FALSE; /* The conversion base. */ int2num (&mult, conv_base); /* Get things ready. */ in_ch = in_char(); while (in_ch == ' ') in_ch = in_char(); if (in_ch == '+') in_ch = in_char(); else if (in_ch == '-') { negative = TRUE; in_ch = in_char(); } /* Check for the special case of a single digit. */ if (in_ch < 16) { first_ch = in_ch; in_ch = in_char(); if (in_ch < 16 && first_ch >= conv_base) first_ch = conv_base - 1; int2num (&build, (int) first_ch); } /* Convert the integer part. */ while (in_ch < 16) { if (in_ch < 16 && in_ch >= conv_base) in_ch = conv_base-1; bc_multiply (build, mult, &result, 0); int2num (&temp, (int) in_ch); bc_add (result, temp, &build); in_ch = in_char(); } if (in_ch == '.') { in_ch = in_char(); if (in_ch >= conv_base) in_ch = conv_base-1; free_num (&result); free_num (&temp); divisor = copy_num (_one_); result = copy_num (_zero_); digits = 0; while (in_ch < 16) { bc_multiply (result, mult, &result, 0); int2num (&temp, (int) in_ch); bc_add (result, temp, &result); bc_multiply (divisor, mult, &divisor, 0); digits++; in_ch = in_char(); if (in_ch < 16 && in_ch >= conv_base) in_ch = conv_base-1; } bc_divide (result, divisor, &result, digits); bc_add (build, result, &build); } /* Final work. */ if (negative) bc_sub (_zero_, build, &build); push_num (build); free_num (&temp); free_num (&result); free_num (&mult);}/* When converting base 10 constants from the program, we use this more efficient way to convert them to numbers. PC tells where the constant starts and is expected to be advanced to after the constant. */voidpush_b10_const (pc) program_counter *pc;{ bc_num build; program_counter look_pc; int kdigits, kscale; char inchar; char *ptr; /* Count the digits and get things ready. */ look_pc = *pc; kdigits = 0; kscale = 0; inchar = byte (&look_pc); while (inchar != '.' && inchar != ':') { kdigits++; inchar = byte(&look_pc); } if (inchar == '.' ) { inchar = byte(&look_pc); while (inchar != ':') { kscale++; inchar = byte(&look_pc); } } /* Get the first character again and move the pc. */ inchar = byte(pc); /* Secial cases of 0, 1, and A-F single inputs. */ if (kdigits == 1 && kscale == 0) { if (inchar == 0) { push_copy (_zero_); inchar = byte(pc); return; } if (inchar == 1) { push_copy (_one_); inchar = byte(pc); return; } if (inchar > 9) { init_num (&build); int2num (&build, inchar); push_num (build); inchar = byte(pc); return; } } /* Build the new number. */ if (kdigits == 0) { build = new_num (1,kscale); ptr = build->n_value; *ptr++ = 0; } else { build = new_num (kdigits,kscale); ptr = build->n_value; } while (inchar != ':') { if (inchar != '.') if (inchar > 9) *ptr++ = 9; else *ptr++ = inchar; inchar = byte(pc); } push_num (build);}/* Put the correct value on the stack for C_CODE. Frees TOS num. */voidassign (c_code) char c_code;{ free_num (&ex_stack->s_num); if (c_code) ex_stack->s_num = copy_num (_one_); else ex_stack->s_num = copy_num (_zero_);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -