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

📄 symbol.c

📁 Linux下VB解释器
💻 C
📖 第 1 页 / 共 4 页
字号:
  cur = 1;  for (i = 0; i < 10; i++)    {      if (bound[i])	cur *= bound[i];      ind[i] = 0;    }  for (i = 9; i >= 0; i--)    {      if (bound[i])	{	  cur /= bound[i];	  ind[i] = off / cur;	  off -= ind[i] * cur;	}      else	{	  ind[i] = 0;	}    }}voidquery_array (struct command *cmd)	/* query array */{  int index;  struct stackentry *s;  struct array *ar;  struct symbol *sym;  if (cmd->type == cARSIZE)    index = (int) pop (stNUMBER)->value;  s = pop (stSTRING_OR_NUMBER_ARRAYREF);  if (!cmd->symbol)    {      sym = get_sym (s->pointer, syARRAY, amSEARCH);      if (!sym || !sym->pointer)	{	  sprintf (string, "array '%s()' is not defined",		   strip (s->pointer));	  error (ERROR, string);	  return;	}      cmd->symbol = sym;    }  ar = ((struct symbol *) cmd->symbol)->pointer;  if (cmd->type == cARSIZE && (index < 1 || index > ar->dimension))    {      sprintf (string, "only indices between 1 and %d allowed",	       ar->dimension);      error (ERROR, string);      return;    }  s = push ();  s->type = stNUMBER;  if (cmd->type == cARSIZE)    s->value = ar->bounds[ar->dimension - index] - 1;  else    s->value = ar->dimension;  return;}voidcreate_doarray (char *symbol, int command)	/* creates array-commands */{  struct command *cmd;  cmd = add_command (cDOARRAY, symbol);  cmd->tag = command;		/* operation to perform */  cmd->args = -1;}voiddoarray (struct command *cmd)	/* call an array */{  struct array *ar;  struct stackentry *stack;  struct symbol *sym;  void *p;  char **str;  double *dbl;  int i, j, bnd, index, cur, rval;  if (!cmd->symbol)    {      sym = get_sym (cmd->name, syARRAY, amSEARCH);      if (!sym || !sym->pointer)	{	  sprintf (string, "'%s()' is neither array nor subroutine",		   strip (cmd->name));	  error (ERROR, string);	  return;	}      cmd->symbol = sym;    }  rval = (current->tag == CALLARRAY || current->tag == CALLSTRINGARRAY	  || current->tag == GETSTRINGPOINTER);  if (cmd->args < 0)    cmd->args = count_args (!rval);  if (cmd->args < 0)    {      error (ERROR, "only numerical indices allowed for arrays");      return;    }  cmd->args = abs (cmd->args);  if (!cmd->args)    {				/* no indizes supplied, create a reference to an array */      pop (stFREE);		/* remove left over stFREE */      stack = push ();      if (cmd->tag == CALLARRAY)	stack->type = stNUMBERARRAYREF;      else	stack->type = stSTRINGARRAYREF;      stack->pointer = my_strdup (cmd->name);      return;    }  ar = ((struct symbol *) cmd->symbol)->pointer;  if (!ar->dimension)    {      sprintf (string, "array parameter '%s()' has not been supplied",	       strip (cmd->name));      error (ERROR, string);      return;    }  if (cmd->args != ar->dimension)    {      sprintf (string, "%d indices supplied, %d expected for '%s()'",	       cmd->args, ar->dimension, strip (cmd->name));      error (ERROR, string);      return;    }  if (!rval)    stack = pop (stSTRING_OR_NUMBER);  index = 0;  cur = 1;  for (i = 0; i < ar->dimension; i++)    {      bnd = (ar->bounds[i]);      j = (int) pop (stNUMBER)->value;      if (j < 0 || j >= bnd)	{	  sprintf (string, "index %d (=%d) out of range",		   ar->dimension - i, j);	  error (ERROR, string);	  return;	}      index += j * cur;      cur *= bnd;    }  pop (stFREE);			/* remove left over stFREE */  if (rval)    stack = push ();  p = ar->pointer;  switch (current->tag)    {    case CALLARRAY:      dbl = (double *) p + index;      stack->value = *dbl;      stack->type = stNUMBER;      break;    case ASSIGNARRAY:      dbl = (double *) p + index;      *dbl = stack->value;      break;    case CALLSTRINGARRAY:      str = ((char **) p + index);      stack->pointer = my_strdup (*str);      stack->type = stSTRING;      break;    case ASSIGNSTRINGARRAY:      str = ((char **) p + index);      if (*str != NULL)	my_free (*str);      *str = my_strdup (stack->pointer);      break;    case GETSTRINGPOINTER:      str = ((char **) p + index);      stack->pointer = *str;      stack->type = stSTRING;      break;    }}struct array *create_array (int type, int dimension)	/* create an array */{  int i;  struct array *ar;  ar = my_malloc (sizeof (struct array));  ar->type = type;  ar->dimension = dimension;  ar->pointer = NULL;  for (i = 0; i < 10; i++)    ar->bounds[i] = 0;  return ar;}static intcount_args (int skipfirst)	/* count number of numeric arguments on stack */{  int i = 0;  int sign = 1;  struct stackentry *curr;  curr = stackhead->prev;  if (skipfirst)    curr = curr->prev;  while (curr)    {      if (curr->type == stFREE)	return i * sign;      if (curr->type != stNUMBER)	sign = -1;      curr = curr->prev;      i++;    }  return -1;}voidskipper ()/* used for on_goto/gosub, skip specified number of commands */{  int i, len;  struct command *ahead;	/* command to follow */  len = (int) pop (stNUMBER)->value;  i = 1;  current = current->next;	/* advance to first goto/gosub */  for (i = 1; i < len; i++)    {      ahead = current->next->next;	/* skip interleaving findnop statement */      if (ahead->type == cNOP)	break;      else	current = ahead;    }}voidskiponce (struct command *cmd)	/* skip next command exectly once */{  if (cmd->tag)    current = current->next;  cmd->tag = 0;}voidresetskiponce (struct command *cmd)	/* find and reset next skip */{  struct command *c;  c = cmd;  while (c->type != cSKIPONCE)    c = c->next;  c->tag = 1;}voidcreate_break_mark (int minor, int major)	/* create marks for break */{  struct command *cmd;  in_loop += major;  cmd = add_command (cBREAK_MARK, NULL);  cmd->tag = (major + 2) * 16 + minor + 2;}voidnext_case (void)		/* go to next case in switch statement */{  if (stackhead->prev->type == stSTRING      || stackhead->prev->type == stSWITCH_STRING)    stackhead->prev->type = stSWITCH_STRING;  else    stackhead->prev->type = stSWITCH_NUMBER;}voidpush_switch_id (void)		/* generate a new switch id */{  static int max_switch_id = 0;  static int switch_stack_depth = 1;  struct switch_id *new_id;  if (switch_id_stackhead == NULL || switch_id_stackhead->next == NULL)    {      if (switch_id_stackroot && switch_id_stackhead == NULL)	{	  new_id = switch_id_stackroot;	}      else	{	  new_id = my_malloc (sizeof (struct switch_id));	  new_id->next = NULL;	  new_id->depth = switch_stack_depth++;	}    }  else    {      new_id = switch_id_stackhead->next;    }  max_switch_id++;  new_id->id = max_switch_id;  if (switch_id_stackhead == NULL)    {      switch_id_stackhead = new_id;      switch_id_stackhead->prev = NULL;    }  else    {      switch_id_stackhead->next = new_id;      new_id->prev = switch_id_stackhead;      switch_id_stackhead = new_id;    }}voidpop_switch_id (void)		/* get previous switch id */{  if (switch_id_stackhead)    switch_id_stackhead = switch_id_stackhead->prev;}intget_switch_id (void)		/* get current switch id */{  return switch_id_stackhead ? switch_id_stackhead->id : 0;}intget_switch_depth (void)		/* get current depth of switch id stack */{  return switch_id_stackhead ? switch_id_stackhead->depth : 0;}voidpush_switch_mark (void)		/* push a switch mark */{  push ()->type = stSWITCH_MARK;}voidcreate_clean_switch_mark (int keep, int ret)	/* add command clean_switch_mark */{  struct command *cmd;  cmd = add_command (cCLEAN_SWITCH_MARK, NULL);  cmd->args = keep;  cmd->tag = ret;}voidclean_switch_mark (struct command *cmd)	/* pop everything up to (and including) first switch_mark from stack */{  struct stackentry *t, *tt, *b, *bb, *s;  int keep, k, ret;  k = keep = cmd->args;  ret = cmd->tag;  s = stackhead->prev;  while (k && s != stackroot)    {      k--;      s = s->prev;    }  t = s;  tt = s->next;  while (((ret && s->type != stRETADDCALL)	  || (!ret && s->type != stSWITCH_MARK)) && s != stackroot)    {      s = s->prev;    }  if (ret)    {      bb = s;      b = s->next;    }  else    {      b = s;      bb = s->prev;    }  /* cut part between (and including) b and t out of stack */  bb->next = tt;  tt->prev = bb;  /* insert cut-out part between stackhead and stackhead->prev */  stackhead->prev->next = b;  b->prev = stackhead->prev;  t->next = stackhead;  stackhead->prev = t;  if (keep)    stackhead = tt->next;  else    stackhead = bb->next;}voidmybreak (struct command *cmd)	/* find break_here statement */{  struct command *curr;  int major, minor;  int major_nesting = 0;  int minor_nesting = 0;  if (cmd->type == cBREAK)    major_nesting = 1;  else    minor_nesting = 0;  curr = cmd;  while (curr->type != cBREAK_HERE || major_nesting || minor_nesting)    {      if (curr->type == cBREAK_MARK)	{	  minor = (curr->tag & 15) - 2;	  major = ((curr->tag & 240) / 16) - 2;	  if (!major_nesting)	    minor_nesting += minor;	  major_nesting += major;	  if (infolevel >= DEBUG)	    {	      sprintf (string,		       "searching break-mark: diff(%d,%d), total(%d,%d)",		       minor, major, minor_nesting, major_nesting);	      error (DEBUG, string);	    }	}      curr = curr->next;      if (!curr)	error (FATAL, "break has left program");    }  cmd->type = cQGOTO;  if (infolevel >= DEBUG)    error (DEBUG, "converting cBREAK to cQGOTO");  cmd->jump = current = curr;}voidmycontinue (struct command *cmd)	/* find continue_here statement */{  struct command *curr;  int major;  int major_nesting = -1;  curr = cmd;  while (curr->type != cCONTINUE_HERE || major_nesting)    {      if (curr->type == cBREAK_MARK)	{	  major = ((curr->tag & 240) >> 4) - 2;	  major_nesting += major;	}      if (curr->type == cCONTINUE_CORRECTION)	major_nesting--;      curr = curr->prev;      if (!curr)	error (FATAL, "continue has left program");    }  cmd->type = cQGOTO;  if (infolevel >= DEBUG)    error (DEBUG, "converting cCONTINUE to cQGOTO");  cmd->jump = current = curr;}voidfindnop ()/* used for on_gosub, find trailing nop command */{  while (current->type != cNOP)    {      current = current->next;	/* next label */    }}voidforcheck (void)			/* check, if for-loop is done */{  double start, bound, step, val;  val = pop (stNUMBER)->value;  step = pop (stNUMBER)->value;  bound = pop (stNUMBER)->value;  start = stackhead->prev->value;  if ((val <= bound && val >= start && step >= 0)      || (val <= start && val >= bound && step <= 0))    stackhead->prev->value = 1.;  else    stackhead->prev->value = 0.;}voidforincrement (void)		/* increment value on stack */{/* expecting on stack: BOUND,STEP,VAL,stackhead  where for VAL=START to BOUND step STEP */  stackhead->prev->value += stackhead->prev->prev->value;}voidstartfor (void)			/* compute initial value of for-variable */{  struct stackentry *p;  p = push ();  p->value =      stackhead->prev->prev->prev->prev->value -      stackhead->prev->prev->value;  p->type = stNUMBER;  return;}

⌨️ 快捷键说明

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