gasp.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 3,135 行 · 第 1/5 页

C
3,135
字号
	symbol t;	idx = level_1 (idx + 1, string, lhs);	lhs->value = -lhs->value;	t = lhs->add_symbol;	lhs->add_symbol = lhs->sub_symbol;	lhs->sub_symbol = t;	break;      }    case '(':      idx++;      idx = level_5 (sb_skip_white (idx, string), string, lhs);      if (string->ptr[idx] != ')')	ERROR ((stderr, _("misplaced closing parens.\n")));      else	idx++;      break;    default:      idx = level_0 (idx, string, lhs);      break;    }  return sb_skip_white (idx, string);}static intlevel_2 (idx, string, lhs)     int idx;     sb *string;     exp_t *lhs;{  exp_t rhs;  idx = level_1 (idx, string, lhs);  while (idx < string->len && (string->ptr[idx] == '*'			       || string->ptr[idx] == '/'))    {      char op = string->ptr[idx++];      idx = level_1 (idx, string, &rhs);      switch (op)	{	case '*':	  checkconst ('*', lhs);	  checkconst ('*', &rhs);	  lhs->value *= rhs.value;	  break;	case '/':	  checkconst ('/', lhs);	  checkconst ('/', &rhs);	  if (rhs.value == 0)	    ERROR ((stderr, _("attempt to divide by zero.\n")));	  else	    lhs->value /= rhs.value;	  break;	}    }  return sb_skip_white (idx, string);}static intlevel_3 (idx, string, lhs)     int idx;     sb *string;     exp_t *lhs;{  exp_t rhs;  idx = level_2 (idx, string, lhs);  while (idx < string->len	 && (string->ptr[idx] == '+'	     || string->ptr[idx] == '-'))    {      char op = string->ptr[idx++];      idx = level_2 (idx, string, &rhs);      switch (op)	{	case '+':	  lhs->value += rhs.value;	  if (lhs->add_symbol.name && rhs.add_symbol.name)	    {	      ERROR ((stderr, _("can't add two relocatable expressions\n")));	    }	  /* Change nn+symbol to symbol + nn.  */	  if (rhs.add_symbol.name)	    {	      lhs->add_symbol = rhs.add_symbol;	    }	  break;	case '-':	  lhs->value -= rhs.value;	  lhs->sub_symbol = rhs.add_symbol;	  break;	}    }  return sb_skip_white (idx, string);}static intlevel_4 (idx, string, lhs)     int idx;     sb *string;     exp_t *lhs;{  exp_t rhs;  idx = level_3 (idx, string, lhs);  while (idx < string->len &&	 string->ptr[idx] == '&')    {      char op = string->ptr[idx++];      idx = level_3 (idx, string, &rhs);      switch (op)	{	case '&':	  checkconst ('&', lhs);	  checkconst ('&', &rhs);	  lhs->value &= rhs.value;	  break;	}    }  return sb_skip_white (idx, string);}static intlevel_5 (idx, string, lhs)     int idx;     sb *string;     exp_t *lhs;{  exp_t rhs;  idx = level_4 (idx, string, lhs);  while (idx < string->len	 && (string->ptr[idx] == '|' || string->ptr[idx] == '~'))    {      char op = string->ptr[idx++];      idx = level_4 (idx, string, &rhs);      switch (op)	{	case '|':	  checkconst ('|', lhs);	  checkconst ('|', &rhs);	  lhs->value |= rhs.value;	  break;	case '~':	  checkconst ('~', lhs);	  checkconst ('~', &rhs);	  lhs->value ^= rhs.value;	  break;	}    }  return sb_skip_white (idx, string);}/* Parse the expression at offset idx into string, fill up res with   the result.  Return the index of the first char past the   expression.  */static intexp_parse (idx, string, res)     int idx;     sb *string;     exp_t *res;{  return level_5 (sb_skip_white (idx, string), string, res);}/* Turn the expression at exp into text and glue it onto the end of   string.  */static voidexp_string (exp, string)     exp_t *exp;     sb *string;{  int np = 0;  int ad = 0;  sb_reset (string);  if (exp->add_symbol.len)    {      sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);      np = 1;      ad = 1;    }  if (exp->value)    {      char buf[20];      if (np)	sb_add_char (string, '+');      sprintf (buf, "%d", exp->value);      sb_add_string (string, buf);      np = 1;      ad = 1;    }  if (exp->sub_symbol.len)    {      sb_add_char (string, '-');      sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);      np = 0;      ad = 1;    }  if (!ad)    sb_add_char (string, '0');}/* Parse the expression at offset idx into sb in.  Return the value in   val.  If the expression is not constant, give ERROR emsg.  Return   the index of the first character past the end of the expression.  */static intexp_get_abs (emsg, idx, in, val)     const char *emsg;     int idx;     sb *in;     int *val;{  exp_t res;  idx = exp_parse (idx, in, &res);  if (res.add_symbol.len || res.sub_symbol.len)    ERROR ((stderr, "%s", emsg));  *val = res.value;  return idx;}/* Current label parsed from line.  */sb label;/* Hash table for all assigned variables.  */hash_table assign_hash_table;/* Hash table for keyword.  */hash_table keyword_hash_table;/* Hash table for eq variables.  */hash_table vars;#define in_comment ';'#if 0static voidstrip_comments (out)     sb *out;{  char *s = out->ptr;  int i = 0;  for (i = 0; i < out->len; i++)    {      if (ISCOMMENTCHAR (s[i]))	{	  out->len = i;	  return;	}    }}#endif/* Push back character ch so that it can be read again.  */static voidunget (ch)     int ch;{  if (ch == '\n')    {      sp->linecount--;    }  if (sp->pushback_index)    sp->pushback_index--;  else    sb_add_char (&sp->pushback, ch);}/* Push the sb ptr onto the include stack, with the given name, type   and index.  */static voidinclude_buf (name, ptr, type, index)     sb *name;     sb *ptr;     include_type type;     int index;{  sp++;  if (sp - include_stack >= MAX_INCLUDES)    FATAL ((stderr, _("unreasonable nesting.\n")));  sb_new (&sp->name);  sb_add_sb (&sp->name, name);  sp->handle = 0;  sp->linecount = 1;  sp->pushback_index = 0;  sp->type = type;  sp->index = index;  sb_new (&sp->pushback);  sb_add_sb (&sp->pushback, ptr);}/* Used in ERROR messages, print info on where the include stack is   onto file.  */static voidinclude_print_where_line (file)     FILE *file;{  struct include_stack *p = include_stack + 1;  while (p <= sp)    {      fprintf (file, "%s:%d ", sb_name (&p->name), p->linecount - 1);      p++;    }}/* Used in listings, print the line number onto file.  */static voidinclude_print_line (file)     FILE *file;{  int n;  struct include_stack *p = include_stack + 1;  n = fprintf (file, "%4d", p->linecount);  p++;  while (p <= sp)    {      n += fprintf (file, ".%d", p->linecount);      p++;    }  while (n < 8 * 3)    {      fprintf (file, " ");      n++;    }}/* Read a line from the top of the include stack into sb in.  */static intget_line (in)     sb *in;{  int online = 0;  int more = 1;  if (copysource)    {      putc (comment_char, outfile);      if (print_line_number)	include_print_line (outfile);    }  while (1)    {      int ch = get ();      while (ch == '\r')	ch = get ();      if (ch == EOF)	{	  if (online)	    {	      WARNING ((stderr, _("End of file not at start of line.\n")));	      if (copysource)		putc ('\n', outfile);	      ch = '\n';	    }	  else	    more = 0;	  break;	}      if (copysource)	{	  putc (ch, outfile);	}      if (ch == '\n')	{	  ch = get ();	  online = 0;	  if (ch == '+')	    {	      /* Continued line.  */	      if (copysource)		{		  putc (comment_char, outfile);		  putc ('+', outfile);		}	      ch = get ();	    }	  else	    {	      if (ch != EOF)		unget (ch);	      break;	    }	}      else	{	  sb_add_char (in, ch);	}      online++;    }  return more;}/* Find a label from sb in and put it in out.  */static intgrab_label (in, out)     sb *in;     sb *out;{  int i = 0;  sb_reset (out);  if (ISFIRSTCHAR (in->ptr[i]) || in->ptr[i] == '\\')    {      sb_add_char (out, in->ptr[i]);      i++;      while ((ISNEXTCHAR (in->ptr[i])	      || in->ptr[i] == '\\'	      || in->ptr[i] == '&')	     && i < in->len)	{	  sb_add_char (out, in->ptr[i]);	  i++;	}    }  return i;}/* Find all strange base stuff and turn into decimal.  Also   find all the other numbers and convert them from the default radix.  */static voidchange_base (idx, in, out)     int idx;     sb *in;     sb *out;{  char buffer[20];  while (idx < in->len)    {      if (in->ptr[idx] == '\\'	  && idx + 1 < in->len	  && in->ptr[idx + 1] == '(')	{	  idx += 2;	  while (idx < in->len		 && in->ptr[idx] != ')')	    {	      sb_add_char (out, in->ptr[idx]);	      idx++;	    }	  if (idx < in->len)	    idx++;	}      else if (idx < in->len - 1 && in->ptr[idx + 1] == '\'' && ! mri)	{	  int base;	  int value;	  switch (in->ptr[idx])	    {	    case 'b':	    case 'B':	      base = 2;	      break;	    case 'q':	    case 'Q':	      base = 8;	      break;	    case 'h':	    case 'H':	      base = 16;	      break;	    case 'd':	    case 'D':	      base = 10;	      break;	    default:	      ERROR ((stderr, _("Illegal base character %c.\n"), in->ptr[idx]));	      base = 10;	      break;	    }	  idx = sb_strtol (idx + 2, in, base, &value);	  sprintf (buffer, "%d", value);	  sb_add_string (out, buffer);	}      else if (ISFIRSTCHAR (in->ptr[idx]))	{	  /* Copy entire names through quickly.  */	  sb_add_char (out, in->ptr[idx]);	  idx++;	  while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))	    {	      sb_add_char (out, in->ptr[idx]);	      idx++;	    }	}      else if (isdigit ((unsigned char) in->ptr[idx]))	{	  int value;	  /* All numbers must start with a digit, let's chew it and	     spit out decimal.  */	  idx = sb_strtol (idx, in, radix, &value);	  sprintf (buffer, "%d", value);	  sb_add_string (out, buffer);	  /* Skip all undigsested letters.  */	  while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))	    {	      sb_add_char (out, in->ptr[idx]);	      idx++;	    }	}      else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')	{	  char tchar = in->ptr[idx];	  /* Copy entire names through quickly.  */	  sb_add_char (out, in->ptr[idx]);	  idx++;	  while (idx < in->len && in->ptr[idx] != tchar)	    {	      sb_add_char (out, in->ptr[idx]);	      idx++;	    }	}      else	{	  /* Nothing special, just pass it through.  */	  sb_add_char (out, in->ptr[idx]);	  idx++;	}    }}/* .end  */static voiddo_end (in)     sb *in;{  had_end = 1;  if (mri)    fprintf (outfile, "%s\n", sb_name (in));}/* .assign  */static voiddo_assign (again, idx, in)     int again;     int idx;     sb *in;{  /* Stick label in symbol table with following value.  */  exp_t e;  sb acc;  sb_new (&acc);  idx = exp_parse (idx, in, &e);  exp_string (&e, &acc);  hash_add_to_string_table (&assign_hash_table, &label, &acc, again);  sb_kill (&acc);}/* .radix [b|q|d|h]  */static voiddo_radix (ptr)     sb *ptr;{  int idx = sb_skip_white (0, ptr);  switch (ptr->ptr[idx])    {    case 'B':    case 'b':      radix = 2;      break;    case 'q':    case 'Q':      radix = 8;      break;    case 'd':    case 'D':      radix = 10;      break;    case 'h':    case 'H':      radix = 16;      break;    default:      ERROR ((stderr, _("radix is %c must be one of b, q, d or h"), radix));    }}/* Parse off a .b, .w or .l.  */static intget_opsize (idx, in, size)     int idx;     sb *in;     int *size;{  *size = 4;  if (in->ptr[idx] == '.')    {      idx++;    }  switch (in->ptr[idx])    {    case 'b':    case 'B':      *size = 1;      break;    case 'w':    case 'W':      *size = 2;

⌨️ 快捷键说明

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