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

📄 compiler.c

📁 basic.c */ /**//* Project:NeuroBasic, basic package*//**/ /* Survey:This is a simple Basic b-code
💻 C
📖 第 1 页 / 共 4 页
字号:
      case AND:		get_token();      			eval2();      			code_gen(b_pos++, CODE, B_AND);      			break;      default:		return;			/* not my token */    }  } } /* end of eval1() */static void eval_expr(void)/*=======================*//* Recursively evaluates Basic expressions.   Expects curr_token to be set.*/{  eval1();  while (!error_flag)  {    switch (curr_token)    {      case OR:		get_token();      			eval1();      			code_gen(b_pos++, CODE, B_OR);      			break;      case EXOR:	get_token();      			eval1();      			code_gen(b_pos++, CODE, B_EXOR);      			break;      default:		return;			/* not my token */    }  } } /* end of eval_expr() */static void eval_string(void)/*=========================*//* Evaluates string primaries. Expects curr_token to be set.*/{  if (error_flag) return;  switch (curr_token)  {    case LPAR:		get_token();		/* skip "(" */    			eval_string_expr();    			if (curr_token != RPAR)			  handle_e(em_rp);			else			  get_token();		/* skip ")" */    			break;    case STRING:	code_gen(b_pos++, CODE, B_PUSHC);			code_gen(b_pos++, VALUE,			 (MFLOAT)symbol_id(&tab_strconsts, curr_name));			get_token();		/* skip string */    			break;    case STRING_NAME:	code_gen(b_pos++, CODE, B_PUSHC);			code_gen(b_pos++, VALUE,				 (MFLOAT)str_id(curr_name));			get_token();		/* skip name */    			break;    case STRFCT_NAME:	eval_fct();			del_strstack = TRUE;			break;    default:		handle_e(em_strpr);    			break;  }} /* end of eval_string() */static void eval_string_expr(void)/*==============================*//* Evaluates string expressions. Expects curr_token to be set.*/{  eval_string();  while (!error_flag)  {    switch (curr_token)    {      case PLUS:	get_token();		/* skip "+" */      			eval_string();      			code_gen(b_pos++, CODE, B_STR_ADD);			del_strstack = TRUE;      			break;      default:		return;			/* not my token */    }  }  } /* end of eval_string_expr() */static void eval_if(void)/*=====================*//* Evaluates if/then condition. Expects curr_token to be set.*/{  const char	*p;  size_t	pos;    if (error_flag) return;  eval_expr();			/* evaluate condition */  if (curr_token != THEN) handle_e(em_nothen);  p = src_pos;			/* remember position */  get_token();  /* For historical reasons support a direct label or line number     after the keyword "then". This will be interpreted as "goto"     the line number or label.  */  if ((curr_token == NAME || curr_token == NUMBER)      && get_token() == END_LINE)  {				/* direct line number or label */    src_pos = p;		/* step back.. */    curr_token = GOTO;		/* ..and insert a "goto" */  }  else  {    src_pos = p;		/* step back.. */    get_token();		/* ..and refetch last token */  }  code_gen(b_pos++, CODE, B_NOT);     /* negate condition */  code_gen(b_pos++, CODE, B_PUSHC);  pos = b_pos++;		      /* fill in jump address later */  code_gen(b_pos++, CODE, B_JUMPC);  eval_commands();		      /* compile rest of line */  code_gen(pos, OFFSET, (MINT)b_pos); /* set jump address now */} /* end of eval_if() */static void eval_assign_array(void)/*===============================*/{  MINT		varnr;  if (error_flag) return;  varnr = symbol_id(&tab_arrays, curr_name);  eval_array();  if (curr_token != EQU) handle_e(em_assign);  get_token();				/* skip '=' */  eval_expr();  code_gen(b_pos++, CODE, B_ASSIGN_ARR);  code_gen(b_pos++, OFFSET, varnr);} /* end of eval_assign_array() */static void eval_assign(void)/*=========================*//* Evaluates an assignment to a variable. Expects curr_token to   be set to variable name.*/{  MINT			varnr;  char			*name;  token_value_t		token;  if (curr_token == ARRAY_NAME)  {    eval_assign_array();    return;  }  name = str_dup(curr_name);  token = curr_token;  get_token();					/* skip var name */  if (curr_token != EQU) handle_e(em_assign);  get_token();					/* skip '=' */  if (error_flag) goto end_assign;  switch (token)  {    case NAME:		eval_expr();			varnr = symbol_probe(&tab_locvars, name);			if (varnr >= 0)		/* a local variable? */			{			  varnr -= tab_locvars.pos;			  code_gen(b_pos++, CODE, B_LOCASSIGN);			}			else			{			/* a global variable */			  varnr = symbol_id(&tab_globvars, name);			  code_gen(b_pos++, CODE, B_ASSIGN);			}			code_gen(b_pos++, OFFSET, varnr);			break;    case STRING_NAME:	eval_string_expr();			code_gen(b_pos++, CODE, B_ASSIGN_STR);			code_gen(b_pos++, VALUE, (MFLOAT)str_id(name));			break;    case CONST:		handle_e(em_const);			break;    default:		handle_e(em_ass);			break;  } /* end switch */  end_assign:  if (name != NULL) free(name);} /* end of eval_assign() */static void eval_for(void)/*======================*//* Evaluates "for/to" statements. Expects curr_token to be set.*/{  if (curr_token != NAME && curr_token != CONST)    handle_e(em_name);  if (error_flag) return;  eval_assign();  if (curr_token != TO) handle_e(em_to);  get_token();					/* skip "to" */  eval_expr();  code_gen(b_pos++, CODE, B_PUSHC);  code_gen(b_pos, OFFSET, b_pos+1);		/* loop addr */  b_pos++;} /* end of eval_for() */static void eval_next(void)/*=======================*//* Evaluates a "next" statement. Expects curr_token to be set.*/{  MINT		varnr;  if (curr_token == CONST) handle_e(em_const);  if (curr_token != NAME) handle_e(em_name);  if (error_flag) return;  varnr = symbol_probe(&tab_locvars, curr_name);  if (varnr >= 0)				/* a local variable? */  {    varnr -= tab_locvars.pos;    code_gen(b_pos++, CODE, B_LOCNEXT);  }  else  {						/* a global variable */    varnr = symbol_id(&tab_globvars, curr_name);    code_gen(b_pos++, CODE, B_NEXT);  }  code_gen(b_pos++, OFFSET, varnr);  get_token();					/* skip var name */} /* end of eval next */static void eval_input(void)/*========================*/{  MINT		varnr;  if (curr_token == CONST) handle_e(em_const);  if (curr_token != NAME) handle_e(em_name);  if (error_flag) return;  varnr = symbol_probe(&tab_locvars, curr_name);  if (varnr >= 0)				/* a local variable? */  {    varnr -= tab_locvars.pos;    code_gen(b_pos++, CODE, B_LOCINPUT);  }  else  {						/* a global variable */    varnr = symbol_id(&tab_globvars, curr_name);    code_gen(b_pos++, CODE, B_INPUT);  }  code_gen(b_pos++, OFFSET, varnr);  get_token();					/* skip var name */} /* end of eval_input() */static void eval_print(void)/*========================*/{  token_value_t		last_token;  int			sf;  last_token = SEMICOLON;  while (!error_flag && curr_token!=END_LINE && curr_token!=COLON)  {    sf = (last_token != SEMICOLON && last_token != COMMA);    last_token = curr_token;		/* remember for later */    switch (curr_token)    {      case COMMA:	get_token();			code_gen(b_pos++, CODE, B_PRINTTAB);			break;      case SEMICOLON:	get_token();			break;      case STRING:      case STRING_NAME:      case STRFCT_NAME:	if (sf) handle_e(em_print);			eval_string_expr();			code_gen(b_pos++, CODE, B_PRINTS);			break;      default:		if (sf) handle_e(em_print);			eval_expr();			code_gen(b_pos++, CODE, B_PRINTF);			break;    } /* end switch */  }  if (last_token != SEMICOLON && last_token != COMMA)    code_gen(b_pos++, CODE, B_PRINTNL);} /* end of eval_print() */static void eval_label(void)/*========================*/{  switch (curr_token)  {    case NAME:		if (symbol_probe(&tab_labels, curr_name) != -1)			  handle_e(em_dupl);			if (tab_labels.pos < LABEL_MAX)			  {			    label_ref[tab_labels.pos] = b_pos;			    symbol_insert(&tab_labels, curr_name);			  }			else			  handle_e(em_mem);			break;    default:		handle_e(em_label);			break;  } /* end switch */  get_token();				/* skip label */} /* end of eval_label() */static void eval_goto(void)/*=======================*/{  if (reloc_pos >= RELOC_MAX) handle_e(em_mem);  if (error_flag) return;  code_gen(b_pos++, CODE, B_PUSHC);  reloc_tab[reloc_pos].b_pos = b_pos;  switch (curr_token)  {    case NUMBER: reloc_tab[reloc_pos].ref_line_nr = curr_value;		 reloc_tab[reloc_pos].name = NULL;		 break;    case NAME:	 reloc_tab[reloc_pos].ref_line_nr = -1;		 reloc_tab[reloc_pos].name = str_dup(curr_name);		 break;    default:     handle_e(em_goto);		 break;  } /* end switch */  code_gen(b_pos++, OFFSET, 0);	/* insert jmp-addr here later */  code_gen(b_pos++, CODE, B_JUMPA);  reloc_tab[reloc_pos++].src_line_nr = src_line_nr;  get_token();				/* skip label/line number */} /* end of eval_goto() */static void eval_deffn(void)/*========================*//* Evaluates user-defined Basic function headers. Expects curr_token   to be set.*/{  MINT	nargs = 0;    if (curr_token != FCT_NAME) handle_e(em_fct);  if (symbol_probe(&tab_functions, curr_name) != -1) handle_e(em_dupf);  symbol_insert(&tab_functions, curr_name);  if (tab_locvars.pos > 0) handle_e(em_endfn);  if (error_flag) return;  symbol_insert(&tab_locvars, curr_name);	/* for return value */  get_token();					/* skip fct name */  while (curr_token != RPAR && !error_flag)  {    if (curr_token != NAME) handle_e(em_name);    if (symbol_probe(&tab_locvars, curr_name) != -1) handle_e(em_dupn);    symbol_insert(&tab_locvars, curr_name);    nargs++;    get_token();				/* skip arg */    if (curr_token != COMMA && curr_token != RPAR)      handle_e(em_fnarg);    if (curr_token == COMMA) get_token();	/* skip ',' */  }  get_token();					/* skip ')' */  fct_ref[tab_functions.pos-1].b_pos = b_pos;  fct_ref[tab_functions.pos-1].nargs = nargs;  code_gen(b_pos++, CODE, B_MKFRAMEP);  code_gen(b_pos++, OFFSET, nargs);} /* end of eval_deffn() */static void eval_endfn(void)/*========================*/{  if (error_flag) return;  code_gen(b_pos++, CODE, B_RETURNFN);  code_gen(b_pos++, OFFSET, tab_locvars.pos-1);  symbol_reset(&tab_locvars);} /* end of eval_endfn() */static void eval_dim(void)/*======================*/{  MINT		varnr;			/* array index */    while (!error_flag)  {    if (curr_token != ARRAY_NAME) handle_e(em_array);    varnr = symbol_id(&tab_arrays, curr_name);    eval_array();    code_gen(b_pos++, CODE, B_DIM);    code_gen(b_pos++, OFFSET, varnr);    if (curr_token != COMMA) break;    get_token();			/* skip ',' */  }} /* end of eval_dim() */static void eval_commands(void)/*===========================*//* Evaluate all commands of the remaining source line (commands are   separated by a ':' in the source code). Expecting the global   variable "curr_token" to be set.*/{  while (!error_flag && curr_token != END_LINE)  {    switch (curr_token)    {      case LABEL:	get_token();			eval_label();			break;      case GOSUB:	/* insert return address */			code_gen(b_pos++, OFFSET, B_PUSHC);			code_gen(b_pos, OFFSET, b_pos + 4);			b_pos++;      case GOTO:	get_token();			eval_goto();			break;      case RETURN:	get_token();			code_gen(b_pos++, CODE, B_JUMPA);			break;      case IF:	 	get_token();			eval_if();			break;      case FOR:		get_token();			eval_for();

⌨️ 快捷键说明

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