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

📄 symbol.c

📁 Linux下VB解释器
💻 C
📖 第 1 页 / 共 4 页
字号:
  stackhead->prev->value = -stackhead->prev->value;}voidpushstrptr (struct command *cmd)	/* push string-pointer onto stack */{  struct stackentry *p;  p = push ();  if (!cmd->symbol)    cmd->symbol = &(get_sym (cmd->name, sySTRING, amADD_GLOBAL)->pointer);  p->pointer = *(char **) cmd->symbol;  if (!p->pointer)    p->pointer = my_strdup ("");  p->type = stSTRING;}voidpushstrsym (struct command *cmd)	/* push string-symbol onto stack */{  struct stackentry *p;  p = push ();  if (!cmd->symbol)    cmd->symbol = &(get_sym (cmd->name, sySTRING, amADD_GLOBAL)->pointer);  p->pointer = my_strdup (*(char **) cmd->symbol);  p->type = stSTRING;}voidpopstrsym (struct command *cmd)	/* pop string from stack */{  if (!cmd->name)    return;  if (!cmd->symbol)    cmd->symbol = &(get_sym (cmd->name, sySTRING, amADD_GLOBAL)->pointer);  if (*(char **) cmd->symbol != NULL)    my_free (*(char **) cmd->symbol);  *(char **) cmd->symbol = my_strdup (pop (stSTRING)->pointer);}voidcreate_pushstr (char *s)	/* creates command pushstr */{  struct command *cmd;  cmd = add_command (cPUSHSTR, NULL);  cmd->pointer = my_strdup (s);	/* store string */}voidpushstr (struct command *cmd){  /* push string onto stack */  struct stackentry *p;  p = push ();  p->pointer = my_strdup ((char *) cmd->pointer);  p->type = stSTRING;}voidduplicate (void)		/* duplicate topmost element of stack */{  struct stackentry *s;  double actual;  actual = stackhead->prev->value;  s = push ();  s->type = stNUMBER;  s->value = actual;}voidcreate_goto (char *label)	/* creates command goto */{  struct command *cmd;  cmd = add_command (cGOTO, NULL);  /* specific info */  cmd->pointer = my_strdup (label);}voidcreate_gosub (char *label)	/* creates command gosub */{  struct command *cmd;  cmd = add_command (cGOSUB, NULL);  /* specific info */  cmd->pointer = my_strdup (label);}voidcreate_call (char *label)	/* creates command function call */{  struct command *cmd;  cmd = add_command (cCALL, NULL);  /* specific info */  cmd->pointer = my_strdup (label);}static voidlink_label (struct command *cmd)	/* link label into list of labels */{  if (!labelroot)    labelroot = cmd;  else    labelhead->nextassoc = cmd;  labelhead = cmd;}struct command *search_label (char *name, int type)	/* search label */{  struct command *curr;  char *at = NULL;  curr = labelroot;  if (type & smGLOBAL)    {      at = strchr (name, '@');      if (at)	*at = '\0';    }  while (curr)    {      if ((type & smSUB) && curr->type == cUSER_FUNCTION	  && !strcmp (curr->pointer, name))	{	  if (at)	    *at = '@';	  return curr;	}      if ((type & smLINK) && curr->type == cSUBLINK	  && !strcmp (curr->pointer, name))	{	  if (at)	    *at = '@';	  return curr->next;	}      if ((type & smLABEL) && curr->type == cLABEL	  && !strcmp (curr->pointer, name))	{	  if (at)	    *at = '@';	  return curr;	}      curr = curr->nextassoc;    }  return NULL;}voidjump (struct command *cmd)/* jump to specific Label; used as goto, gosub or function call */{  struct command *label;  struct stackentry *ret;  int type;  char *dot;  type = cmd->type;  if (type == cGOSUB || type == cQGOSUB || type == cCALL || type == cQCALL)    {      /* leave return address for return */      ret = push ();      ret->pointer = current;      if (type == cGOSUB || type == cQGOSUB)	{	  ret->type = stRETADD;	}      else	{	  ret->type = stRETADDCALL;	  reshufflestack (ret);	}    }  if (type == cQGOSUB || type == cQGOTO || type == cQCALL)    {      current = (struct command *) cmd->jump;	/* use remembered address */      return;    }  label = search_label (cmd->pointer, smSUB | smLINK | smLABEL);  if (!label && type == cCALL && (dot = strchr (cmd->pointer, '.')))    {      strcpy (string, "main");      strcat (string, dot);      label = search_label (string, smLINK);    }  if (label)    {      /* found right label */      current = label;		/* jump to new location */      /* use the address instead of the name next time */      cmd->jump = label;      switch (cmd->type)	{	case cGOTO:	  cmd->type = cQGOTO;	  break;	case cGOSUB:	  cmd->type = cQGOSUB;	  break;	case cCALL:	  cmd->type = cQCALL;	  break;	}    }  else    {      /* label not found */      sprintf (string, "can't find %s '%s'",	       (type == cCALL) ? "subroutine" : "label",	       strip ((char *) cmd->pointer));      if (strchr (cmd->pointer, '@'))	strcat (string, " (not in this sub)");      error (ERROR, string);    }  /* check, if goto enters or leaves a switch_statement */  if (cmd->type == cQGOTO)    {      if (label->switch_id && !cmd->switch_id)	error (ERROR, "cannot jump into switch-statement");      else if (!label->switch_id && cmd->switch_id)	error (ERROR, "cannot jump out of switch-statement");      else if (label->switch_id != cmd->switch_id)	error (ERROR, "cannot jump between switch statements");    }}voidreshufflestack (struct stackentry *ret)	/* reorganize stack for function call */{  struct stackentry *a, *b, *c;  struct stackentry *top, *bot;  struct stackentry *ttop, *bbot;  int args;  /* this is a function call; revert stack and shuffle return address to bottom */  /* push address below parameters */  args = 0;  top = a = ret->prev;  while (a->type != stFREE)    {      a = a->prev;      args++;    }  bot = a->next;  b = a->prev;  /* remove ret */  ret->prev->next = ret->next;  ret->next->prev = ret->prev;  /* squeeze ret between a and b */  ret->next = a;  a->prev = ret;  b->next = ret;  ret->prev = b;  /* revert stack between top and bot */  if (args > 1)    {      a = bot;      b = a->next;      bbot = bot->prev;      ttop = top->next;      for (; args > 1; args--)	{	  a->prev = b;	  c = b->next;	  b->next = a;	  a = b;	  b = c;	}      bot->next = ttop;      bot->next->prev = bot;      top->prev = bbot;      top->prev->next = top;    }}voidmyreturn (struct command *cmd)	/* return from gosub of function call */{  struct stackentry *address;  address = pop (stANY);  if (cmd->type == cRET_FROM_FUN)    {      if (address->type != stRETADDCALL)	{	  error (ERROR, "RETURN from a subroutine without CALL");	  return;	}    }  else    {      if (address->type != stRETADD)	{	  error (ERROR, "RETURN without GOSUB");	  return;	}    }  current = (struct command *) address->pointer;  return;}voidcreate_label (char *label, int type)	/* creates command label */{  struct command *cmd;  /* check, if label is duplicate */  if (search_label (label, smSUB | smLINK | smLABEL))    {      sprintf (string, "duplicate %s '%s'",	       (type == cLABEL) ? "label" : "subroutine", strip (label));      error (ERROR, string);      return;    }  cmd = add_command (type, NULL);  /* store label */  cmd->pointer = my_strdup (label);  link_label (cmd);}voidcreate_sublink (char *label)	/* create link to subroutine */{  char global[200];  char *dot;  struct command *cmd;  if (!inlib)    return;  dot = strchr (label, '.');  strcpy (global, "main");  strcat (global, dot);  /* check, if label is duplicate */  if (search_label (global, smSUB | smLINK | smLABEL))    {      sprintf (string, "duplicate subroutine '%s'", strip (global));      error (ERROR, string);      return;    }  cmd = add_command (cSUBLINK, NULL);  /* store label */  cmd->pointer = my_strdup (global);  link_label (cmd);}voiddecide ()			/*  skips next command, if not 0 on stack */{  if (pop (stNUMBER)->value != 0)    current = current->next;	/* skip one command */}voidcreate_dim (char *name, char type)	/* create command 'dim' *//* type can be 's'=string or 'd'=double Array */{  struct command *cmd;  cmd = add_command (cDIM, name);  cmd->tag = type;		/* type: string or double */  cmd->args = -1;}voiddim (struct command *cmd)	/* get room for array */{  struct array *nar, *oar;  char *nul;  int ntotal, ototal, esize, i, j;  int ind[10], nbounds[10], larger;  struct symbol *s;  int local;  local = ((cmd->tag == tolower (cmd->tag)) ? TRUE : FALSE);  if (cmd->args < 0)    cmd->args = count_args (FALSE);  if (cmd->args < 0)    {      error (ERROR, "only numerical indices allowed for arrays");      return;    }  s = get_sym (cmd->name, syARRAY, local ? amADD_LOCAL : amADD_GLOBAL);  if (search_label (cmd->name, smSUB | smLINK))    {      sprintf (string, "array '%s()' conflicts with user subroutine",	       strip (cmd->name));      error (ERROR, string);      return;    }  /* check for dimensions */  if (cmd->args > 10)    {      error (ERROR, "more than 10 indices");      return;    }  oar = s->pointer;  if (oar)    {      /* check, if old and new array are compatible */      if (cmd->args != oar->dimension)	{	  sprintf (string,		   "cannot change dimension of '%s()' from %d to %d",		   strip (cmd->name), oar->dimension, cmd->args);	  error (ERROR, string);	}    }  /* check, if redim is actually needed */  for (i = 0; i < 10; i++)    nbounds[i] = 0;  larger = FALSE;  for (i = 0; i < cmd->args; i++)    {      nbounds[i] = 1 + (int) pop (stNUMBER)->value;      if (nbounds[i] <= 1)	{	  sprintf (string, "array index %d is less or equal zero",		   cmd->args - i);	  error (ERROR, string);	  return;	}      if (oar)	{	  if (nbounds[i] > oar->bounds[i])	    larger = TRUE;	  else	    nbounds[i] = oar->bounds[i];	}    }  pop (stFREE);			/* remove left over stFREE */  if (oar && !larger)    return;			/* new array won't be larger than old one */  /* create array */  nar = create_array (tolower (cmd->tag), cmd->args);  /* count needed memory */  ntotal = 1;  for (i = 0; i < nar->dimension; i++)    {      (nar->bounds)[i] = nbounds[i];      ntotal *= nbounds[i];    }  esize = (nar->type == 's') ? sizeof (char *) : sizeof (double);	/* size of one array element */  nar->pointer = my_malloc (ntotal * esize);  if (oar)    {				/* array already exists, get its size */      ototal = 1;      for (i = 0; i < oar->dimension; i++)	ototal *= (oar->bounds)[i];    }  /* initialize Array */  for (i = 0; i < ntotal; i++)    {      if (nar->type == 's')	{	  nul = my_malloc (sizeof (char));	  *nul = '\0';	  ((char **) nar->pointer)[i] = nul;	}      else	{	  ((double *) nar->pointer)[i] = 0.0;	}    }  if (oar)    {				/* copy contents of old array onto new */      for (i = 0; i < ototal; i++)	{	  off_to_ind (i, oar->bounds, ind);	  j = ind_to_off (ind, nar->bounds);	  if (nar->type == 's')	    {	      my_free (((char **) nar->pointer)[j]);	      ((char **) nar->pointer)[j] = ((char **) oar->pointer)[i];	    }	  else	    {	      ((double *) nar->pointer)[j] = ((double *) oar->pointer)[i];	    }	}      my_free (oar->pointer);      my_free (oar);    }  s->pointer = nar;  cmd->symbol = nar;}static intind_to_off (int *ind, int *bound)	/* convert array of indices to single offset */{  int i;  int cur, off;  off = 0;  cur = 1;  for (i = 0; i < 10 && bound[i]; i++)    {      off += ind[i] * cur;      cur *= bound[i];    }  return off;}static voidoff_to_ind (int off, int *bound, int *ind)	/* convert a single offset to an array of indices */{  int i;  int cur;

⌨️ 快捷键说明

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