⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 execute.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* execute.c - run a bc program. *//*  This file is part of bc written for MINIX.    Copyright (C) 1991, 1992 Free Software Foundation, Inc.    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License , or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; see the file COPYING.  If not, write to    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.    You may contact the author by:       e-mail:  phil@cs.wwu.edu      us-mail:  Philip A. Nelson                Computer Science Department, 9062                Western Washington University                Bellingham, WA 98226-9062       *************************************************************************/#include "bcdefs.h"#include <signal.h>#include "global.h"#include "proto.h"/* The SIGINT interrupt handling routine. */int had_sigint;voidstop_execution (sig)     int sig;{  had_sigint = TRUE;  printf ("\n");  rt_error ("interrupted execution");}/* Get the current byte and advance the PC counter. */unsigned charbyte (pc)     program_counter *pc;{  int seg, offset;      seg = pc->pc_addr >> BC_SEG_LOG;  offset = pc->pc_addr++ % BC_SEG_SIZE;  return (functions[pc->pc_func].f_body[seg][offset]);}/* The routine that actually runs the machine. */voidexecute (){  int label_num, l_gp, l_off;  bc_label_group *gp;    char inst, ch;  int  new_func;  int  var_name;  int const_base;  bc_num temp_num;  arg_list *auto_list;  /* Initialize this run... */  pc.pc_func = 0;  pc.pc_addr = 0;  runtime_error = FALSE;  init_num (&temp_num);  /* Set up the interrupt mechanism for an interactive session. */  if (interactive)    {      signal (SIGINT, stop_execution);      had_sigint = FALSE;    }     while (pc.pc_addr < functions[pc.pc_func].f_code_size && !runtime_error)    {      inst = byte(&pc);#if DEBUG > 3      { /* Print out address and the stack before each instruction.*/	int depth; estack_rec *temp = ex_stack;		printf ("func=%d addr=%d inst=%c\n",pc.pc_func, pc.pc_addr, inst);	if (temp == NULL) printf ("empty stack.\n", inst);	else	  {	    depth = 1;	    while (temp != NULL)	      {		printf ("   %d = ", depth);		out_num (temp->s_num, 10, out_char);		depth++;		temp = temp->s_next;	      }	  }      }#endif    switch ( inst )      {      case 'A' : /* increment array variable (Add one). */	var_name = byte(&pc);	if ((var_name & 0x80) != 0)	  var_name = ((var_name << 8) & 0x7f) + byte(&pc);	incr_array (var_name);	break;      case 'B' : /* Branch to a label if TOS != 0. Remove value on TOS. */      case 'Z' : /* Branch to a label if TOS == 0. Remove value on TOS. */	c_code = !is_zero (ex_stack->s_num);	pop ();      case 'J' : /* Jump to a label. */	label_num = byte(&pc);  /* Low order bits first. */	label_num += byte(&pc) << 8;	if (inst == 'J' || (inst == 'B' && c_code)	    || (inst == 'Z' && !c_code)) {	  gp = functions[pc.pc_func].f_label;	  l_gp  = label_num >> BC_LABEL_LOG;	  l_off = label_num % BC_LABEL_GROUP;	  while (l_gp-- > 0) gp = gp->l_next;	  pc.pc_addr = gp->l_adrs[l_off];	}	break;      case 'C' : /* Call a function. */	/* Get the function number. */	new_func = byte(&pc);	if ((new_func & 0x80) != 0) 	  new_func = ((new_func << 8) & 0x7f) + byte(&pc);	/* Check to make sure it is defined. */	if (!functions[new_func].f_defined)	  {	    rt_error ("Function %s not defined.", f_names[new_func]);	    break;	  }	/* Check and push parameters. */	process_params (&pc, new_func);	/* Push auto variables. */	for (auto_list = functions[new_func].f_autos;	     auto_list != NULL;	     auto_list = auto_list->next)	  auto_var (auto_list->av_name);	/* Push pc and ibase. */	fpush (pc.pc_func);	fpush (pc.pc_addr);	fpush (i_base);	/* Reset pc to start of function. */	pc.pc_func = new_func;	pc.pc_addr = 0;	break;      case 'D' : /* Duplicate top of stack */	push_copy (ex_stack->s_num);	break;      case 'K' : /* Push a constant */	/* Get the input base and convert it to a bc number. */	if (pc.pc_func == 0) 	  const_base = i_base;	else	  const_base = fn_stack->s_val;	if (const_base == 10)	  push_b10_const (&pc);	else	  push_constant (prog_char, const_base);	break;      case 'L' : /* load array variable */	var_name = byte(&pc);	if ((var_name & 0x80) != 0)	  var_name = ((var_name << 8) & 0x7f) + byte(&pc);	load_array (var_name);	break;      case 'M' : /* decrement array variable (Minus!) */	var_name = byte(&pc);	if ((var_name & 0x80) != 0)	  var_name = ((var_name << 8) & 0x7f) + byte(&pc);	decr_array (var_name);	break;      case 'O' : /* Write a string to the output with processing. */	while ((ch = byte(&pc)) != '"')	  if (ch != '\\')	    out_char (ch);	  else	    {	      ch = byte(&pc);	      if (ch == '"') break;	      switch (ch)		{		case 'n':  out_char ('\n'); break;		case 't':  out_char ('\t'); break;		case 'r':  out_char ('\r'); break;		case 'b':  out_char (007); break;		case 'f':  out_char ('\f'); break;		case '\\': out_char ('\\'); break;		default:  break;		}	    }	if (interactive) fflush (stdout);	break;      case 'R' : /* Return from function */	if (pc.pc_func != 0)	  {	    /* "Pop" autos and parameters. */	    pop_vars(functions[pc.pc_func].f_autos);	    pop_vars(functions[pc.pc_func].f_params);	    /* reset the pc. */	    fpop ();	    pc.pc_addr = fpop ();	    pc.pc_func = fpop ();	  }	else	  rt_error ("Return from main program.");	break;      case 'S' : /* store array variable */	var_name = byte(&pc);	if ((var_name & 0x80) != 0)	  var_name = ((var_name << 8) & 0x7f) + byte(&pc);	store_array (var_name);	break;      case 'T' : /* Test tos for zero */	c_code = is_zero (ex_stack->s_num);	assign (c_code);	break;      case 'W' : /* Write the value on the top of the stack. */      case 'P' : /* Write the value on the top of the stack.  No newline. */	out_num (ex_stack->s_num, o_base, out_char);	if (inst == 'W') out_char ('\n');	store_var (3);  /* Special variable "last". */	if (interactive) fflush (stdout);	break;      case 'c' : /* Call special function. */	new_func = byte(&pc);      switch (new_func)	{	case 'L':  /* Length function. */	  /* For the number 0.xxxx,  0 is not significant. */	  if (ex_stack->s_num->n_len == 1 &&	      ex_stack->s_num->n_scale != 0 &&	      ex_stack->s_num->n_value[0] == 0 )	    int2num (&ex_stack->s_num, ex_stack->s_num->n_scale);	  else	    int2num (&ex_stack->s_num, ex_stack->s_num->n_len		     + ex_stack->s_num->n_scale);	  break;			case 'S':  /* Scale function. */ 	  int2num (&ex_stack->s_num, ex_stack->s_num->n_scale);	  break;	case 'R':  /* Square Root function. */	  if (!bc_sqrt (&ex_stack->s_num, scale))	    rt_error ("Square root of a negative number");	  break;	case 'I': /* Read function. */	  push_constant (input_char, i_base);	  break;	}	break;      case 'd' : /* Decrement number */	var_name = byte(&pc);	if ((var_name & 0x80) != 0)	  var_name = ((var_name << 8) & 0x7f) + byte(&pc);	decr_var (var_name);	break;            case 'h' : /* Halt the machine. */	exit (0);      case 'i' : /* increment number */	var_name = byte(&pc);	if ((var_name & 0x80) != 0)	  var_name = ((var_name << 8) & 0x7f) + byte(&pc);	incr_var (var_name);	break;      case 'l' : /* load variable */	var_name = byte(&pc);	if ((var_name & 0x80) != 0)	  var_name = ((var_name << 8) & 0x7f) + byte(&pc);	load_var (var_name);	break;      case 'n' : /* Negate top of stack. */	bc_sub (_zero_, ex_stack->s_num, &ex_stack->s_num);	break;      case 'p' : /* Pop the execution stack. */	pop ();	break;      case 's' : /* store variable */	var_name = byte(&pc);	if ((var_name & 0x80) != 0)	  var_name = ((var_name << 8) & 0x7f) + byte(&pc);	store_var (var_name);	break;      case 'w' : /* Write a string to the output. */	while ((ch = byte(&pc)) != '"') out_char (ch);	if (interactive) fflush (stdout);	break;		         case 'x' : /* Exchange Top of Stack with the one under the tos. */	if (check_stack(2)) {	  bc_num temp = ex_stack->s_num;	  ex_stack->s_num = ex_stack->s_next->s_num;	  ex_stack->s_next->s_num = temp;	}	break;      case '0' : /* Load Constant 0. */	push_copy (_zero_);	break;      case '1' : /* Load Constant 0. */	push_copy (_one_);	break;      case '!' : /* Negate the boolean value on top of the stack. */	c_code = is_zero (ex_stack->s_num);	assign (c_code);	break;      case '&' : /* compare greater than */	if (check_stack(2))	  {	    c_code = !is_zero (ex_stack->s_next->s_num)	      && !is_zero (ex_stack->s_num);	    pop ();	    assign (c_code);	  }	break;      case '|' : /* compare greater than */	if (check_stack(2))	  {	    c_code = !is_zero (ex_stack->s_next->s_num)	      || !is_zero (ex_stack->s_num);	    pop ();	    assign (c_code);	  }	break;      case '+' : /* add */	if (check_stack(2))	  {	    bc_add (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num);	    pop();	    pop();	    push_num (temp_num);	    init_num (&temp_num);	  }	break;      case '-' : /* subtract */	if (check_stack(2))	  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -