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

📄 symbol.c

📁 Linux下VB解释器
💻 C
📖 第 1 页 / 共 4 页
字号:
  int ftype;  struct stackentry *s;  /* test if there is something on the stack */  if (stackhead == stackroot)    {      error (FATAL, "Popped too much.");      return stackhead;    }  stackhead = stackhead->prev;	/* move down in stack */  ftype = stackhead->type;  if (etype == ftype || etype == stANY ||      (etype == stSTRING_OR_NUMBER       && (ftype == stNUMBER || ftype == stSTRING))      || (etype == stSTRING_OR_NUMBER_ARRAYREF	  && (ftype == stSTRINGARRAYREF || ftype == stNUMBERARRAYREF)))    return stackhead;		/* this is your value; use it quickly ! */  /* expected and found don't match */  stackdesc (etype, expected);  stackdesc (ftype, found);  sprintf (string, "expected %s but found %s", expected, found);  if (etype == stNUMBER || etype == stSTRING      || etype == stSTRING_OR_NUMBER)    {      s = push ();      if (etype == stNUMBER)	{	  s->type = stNUMBER;	  s->value = 0.0;	}      else	{	  s->type = stSTRING;	  s->pointer = my_strdup ("");	}      error (ERROR, string);      return s;    }  else    {      error (FATAL, string);    }  return stackhead;}static voidstackdesc (int type, char *desc)	/* give back string describing stackentry */{  switch (type)    {    case stGOTO:      strcpy (desc, "a goto");      break;    case stSTRING:      strcpy (desc, "a string");      break;    case stSTRINGARRAYREF:      strcpy (desc, "a reference to a string array");      break;    case stNUMBER:      strcpy (desc, "a number");      break;    case stNUMBERARRAYREF:      strcpy (desc, "a reference to a numeric array");      break;    case stLABEL:      strcpy (desc, "a label");      break;    case stRETADD:      strcpy (desc, "a return address for gosub");      break;    case stRETADDCALL:      strcpy (desc, "a return address for a subroutine");      break;    case stFREE:      strcpy (desc, "nothing");      break;    case stROOT:      strcpy (desc, "the root of the stack");      break;    case stANY:      strcpy (desc, "anything");      break;    case stSTRING_OR_NUMBER:      strcpy (desc, "a string or a number");      break;    case stSTRING_OR_NUMBER_ARRAYREF:      strcpy (desc, "reference to a string or an array");      break;    case stSWITCH_STRING:      strcpy (desc, "number for switch");      break;    case stSWITCH_NUMBER:      strcpy (desc, "string for switch");      break;    default:      sprintf (desc, "type %d", type);      break;    }}voidpushname (char *name)		/* bison: push a name on stack */{  struct stackentry *s;  s = push ();  s->pointer = my_strdup (name);  s->type = stSTRING;}voidpushlabel ()			/* bison: generate goto and push label on stack */{  char *st;  struct stackentry *en;  st = (char *) my_malloc (sizeof (char) * 20);  sprintf (st, "***%d", labelcount);  labelcount++;  create_goto (st);  en = push ();  en->type = stLABEL;  en->pointer = st;}voidpoplabel ()			/* bison: pops a label and generates the matching command */{  create_label (pop (stLABEL)->pointer, cLABEL);	/* and create it */}voidpushgoto ()			/* bison: generate label and push goto on stack */{  char *st;  struct stackentry *en;  st = (char *) my_malloc (sizeof (char) * 20);  sprintf (st, "***%d", labelcount);  labelcount++;  create_label (st, cLABEL);  en = push ();  en->type = stGOTO;  en->pointer = st;}voidpopgoto ()			/* bison: pops a goto and generates the matching command */{  create_goto (pop (stGOTO)->pointer);	/* and create it */}voidstorelabel ()			/* bison: push label on stack */{  char *st;  struct stackentry *en;  st = (char *) my_malloc (sizeof (char) * 20);  sprintf (st, "***%d", labelcount);  labelcount++;  en = push ();  en->type = stLABEL;  en->pointer = st;}voidmatchgoto ()			/* bison: generate goto matching label on stack */{  create_goto (stackhead->prev->pointer);}voidcreate_pushdbl (double value)	/* create command 'cPUSHDBL' */{  struct command *cmd;  cmd = add_command (cPUSHDBL, NULL);  cmd->pointer = my_malloc (sizeof (double));  *(double *) (cmd->pointer) = value;}voidpushdbl (struct command *cmd){  /* push double onto stack */  struct stackentry *p;  p = push ();  p->value = *(double *) cmd->pointer;  p->type = stNUMBER;}voidpushdblsym (struct command *cmd){  /* push double symbol onto stack */  struct stackentry *p;  p = push ();  if (!cmd->name)    error (WARNING, "invalid pushdblsym");  if (!cmd->symbol)    cmd->symbol = &(get_sym (cmd->name, syNUMBER, amADD_GLOBAL)->value);  p->value = *(double *) cmd->symbol;  p->type = stNUMBER;}voidpopdblsym (struct command *cmd)	/* pop double from stack */{  double d;  d = pop (stNUMBER)->value;  if (!cmd->symbol)    cmd->symbol = &(get_sym (cmd->name, syNUMBER, amADD_GLOBAL)->value);  *(double *) (cmd->symbol) = d;}voidcreate_makelocal (char *name, int type)	/* create command 'cMAKELOCAL' */{  struct command *cmd;  cmd = add_command (cMAKELOCAL, name);  cmd->args = type;}voidmakelocal (struct command *cmd)	/* makes symbol local */{  if (get_sym (cmd->name, cmd->args, amSEARCH_VERY_LOCAL))    {      sprintf (string,	       "local variable '%s' already defined within this subroutine",	       strip (cmd->name));      error (ERROR, string);      return;    }  get_sym (cmd->name, cmd->args, amADD_LOCAL);}voidcreate_numparam (void)		/* create command 'cNUMPARAM' */{  struct command *cmd;  /* dotifying numparams at compiletime (as opposed to runtime) is essential,      because the function name is not known at runtime */  cmd = add_command (cNUMPARAM, dotify ("numparams", FALSE));}voidnumparam (struct command *cmd)	/* count number of function parameters */{  struct symbol *sym;  sym = get_sym (cmd->name, syNUMBER, amADD_LOCAL);  sym->value = abs (count_args (FALSE));}voidcreate_makestatic (char *name, int type)	/* create command 'cMAKESTATIC' */{  struct command *cmd;  cmd = add_command (cMAKESTATIC, name);  cmd->args = type;}voidmakestatic (struct command *cmd)	/* makes symbol static */{  struct symbol *l, *g;  char *at = NULL;  /* mask function name */  if ((at = strchr (cmd->name, '@')) != NULL)    *at = '\0';  if (get_sym (cmd->name, cmd->args, amSEARCH_VERY_LOCAL))    {      sprintf (string,	       "static variable '%s' already defined within this subroutine",	       strip (cmd->name));      error (ERROR, string);      return;    }  /* create global variable with unique name */  if (at)    *at = '@';  g = get_sym (cmd->name, cmd->args, amADD_GLOBAL);  if (at)    *at = '\0';  /* create local variable */  l = get_sym (cmd->name, cmd->args, amADD_LOCAL);  if (at)    *at = '@';  /* link those two together */  link_symbols (l, g);}voidcreate_arraylink (char *name, int type)	/* create command 'cARRAYLINK' */{  struct command *cmd;  cmd = add_command (cARRAYLINK, name);  cmd->pointer = current_function;  cmd->args = type;}voidarraylink (struct command *cmd)	/* link a local symbol to a global array */{  struct symbol *l, *g;  struct array *ar;  if (get_sym (cmd->name, cmd->args, amSEARCH_VERY_LOCAL))    {      sprintf (string, "'%s()' already defined within this subroutine",	       strip (cmd->name));      error (ERROR, string);      return;    }  /* get globally defined array */  g = get_sym (pop (cmd->args)->pointer, syARRAY, amSEARCH_PRE);  /* create local array */  l = get_sym (cmd->name, syARRAY, amADD_LOCAL);  if (!l)    return;  if (!g || !g->pointer)    {				/* no global array supplied, create one */      error (DEBUG, "creating dummy array");      ar = create_array ((cmd->args == stNUMBERARRAYREF) ? 'd' : 's', 0);      l->pointer = ar;      if (infolevel >= DEBUG)	{	  sprintf (string, "creating 0-dimensional dummy array '%s()'",		   cmd->name);	  error (DEBUG, string);	}    }  else    {      /* link those two together */      link_symbols (l, g);    }}voidcreate_pusharrayref (char *name, int type)	/* create command 'cPUSHARRAYREF' */{  struct command *cmd;  cmd = add_command (cPUSHARRAYREF, name);  cmd->args = type;}voidpusharrayref (struct command *cmd)	/* push an array reference onto stack */{  struct stackentry *s;  s = push ();  s->type = cmd->args;  s->pointer = my_strdup (cmd->name);}voidcreate_require (int type)	/* create command 'cREQUIRE' */{  struct command *cmd;  cmd = add_command (cREQUIRE, NULL);  cmd->args = type;}voidrequire (struct command *cmd)	/* check, that item on stack has right type */{  char *expected, *supplied;  struct stackentry *s;  if (stackhead->prev->type == cmd->args)    return;			/* okay, they match */  if (stackhead->prev->type == stFREE)    {				/* no argument supplied, create it */      s = push ();      if (cmd->args == stSTRING)	{	  s->type = stSTRING;	  s->pointer = my_strdup ("");	  return;	}      else if (cmd->args == stNUMBER)	{	  s->type = stNUMBER;	  s->value = 0.0;	  return;	}      else	{	  /* create array */	  s->type = cmd->args;	  s->pointer = NULL;	  return;	}    }  s = stackhead->prev;  if (s->type == stSTRING)    supplied = "string";  else if (s->type == stNUMBER)    supplied = "number";  else if (s->type == stSTRINGARRAYREF)    supplied = "string array";  else if (s->type == stNUMBERARRAYREF)    supplied = "numeric array";  else if (s->type == stFREE)    supplied = "nothing";  else    supplied = "something strange";  if (cmd->args == stSTRING)    expected = "string";  else if (cmd->args == stNUMBER)    expected = "number";  else if (cmd->args == stSTRINGARRAYREF)    expected = "string array";  else if (cmd->args == stNUMBERARRAYREF)    expected = "numeric array";  else if (cmd->args == stFREE)    expected = "nothing";  else    expected = "something strange";  sprintf (string, "invalid subroutine call: %s expected, %s supplied",	   expected, supplied);  error (ERROR, string);}voidcreate_dblbin (char c)		/* create command for binary double operation */{  switch (c)    {    case '+':      add_command (cDBLADD, NULL);      break;    case '-':      add_command (cDBLMIN, NULL);      break;    case '*':      add_command (cDBLMUL, NULL);      break;    case '/':      add_command (cDBLDIV, NULL);      break;    case '^':      add_command (cDBLPOW, NULL);      break;    }  /* no specific information needed */}voiddblbin (struct command *cmd)	/* compute with two numbers from stack */{  struct stackentry *d;  double a, b, c;  b = pop (stNUMBER)->value;  a = pop (stNUMBER)->value;  d = push ();  switch (cmd->type)    {    case (cDBLADD):      c = a + b;      break;    case (cDBLMIN):      c = a - b;      break;    case (cDBLMUL):      c = a * b;      break;    case (cDBLDIV):      if (fabs (b) < DBL_MIN)	{	  sprintf (string, "Division by zero, set to %g", DBL_MAX);	  error (NOTE, string);	  c = DBL_MAX;	}      else	c = a / b;      break;    case (cDBLPOW):      if ((a == 0 && b <= 0) || (a < 0 && b != (int) b))	{	  error (ERROR, "result is not a real number");	  return;	}      else	{	  c = pow (a, b);	}      break;    }  d->value = c;  d->type = stNUMBER;}voidnegate ()			/* negates top of stack */{

⌨️ 快捷键说明

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