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

📄 libexo.cc

📁 linux下基于c++的处理器仿真平台。具有处理器流水线
💻 CC
📖 第 1 页 / 共 2 页
字号:
      exo->as_string.str = NULL;      break;    case ec_list:      {	struct exo_term_t *ent, *next_ent;	for (ent=exo->as_list.head; ent != NULL; ent = next_ent)	  {	    next_ent = ent->next;	    exo_delete(ent);	  }	exo->as_list.head = NULL;      }      break;    case ec_array:      {	int i;	for (i=0; i < exo->as_array.size; i++)	  {	    if (exo->as_array.array[i] != NULL)	      exo_delete(exo->as_array.array[i]);	  }	free(exo->as_array.array);	exo->as_array.array = NULL;	exo->as_array.size = 0;      }      break;    case ec_token:      /* no extra storage */      exo->as_token.ent = NULL;      break;    case ec_blob:      /* free the blob data */      free(exo->as_blob.data);      exo->as_blob.data = NULL;      break;    case ec_null:      /* no extra storage */      break;    default:      panic("bogus EXO class");    }  exo->ec = (enum exo_class_t)0;  /* release the node */  free(exo);}/* chain two EXO lists together, FORE is attached on the end of AFT */struct exo_term_t *exo_chain(struct exo_term_t *fore, struct exo_term_t *aft){  struct exo_term_t *exo, *prev;  if (!fore && !aft)    return NULL;  if (!fore)    return aft;  /* find the tail of FORE */  for (prev=NULL,exo=fore; exo != NULL; prev=exo,exo=exo->next)    /* nada */;  assert(prev);  /* link onto the tail of FORE */  prev->next = aft;  return fore;}/* copy an EXO node */struct exo_term_t *exo_copy(struct exo_term_t *exo){  struct exo_term_t *new_exo;  /* NULL copy */  if (!exo)    return NULL;  new_exo = exo_alloc(exo->ec);  *new_exo = *exo;  /* the next link is always blown away on a copy */  new_exo->next = NULL;  switch (new_exo->ec)    {    case ec_integer:    case ec_address:    case ec_float:    case ec_char:    case ec_string:    case ec_list:    case ec_token:      /* no internal parts to copy */      break;    case ec_array:      {	int i;	/* copy the array */	new_exo->as_array.array = (struct exo_term_t **)	  calloc(new_exo->as_array.size, sizeof(struct exo_term_t *));	for (i=0; i<new_exo->as_array.size; i++)	  {	    SET_EXO_ARR(new_exo, i, EXO_ARR(exo, i));	  }      }      break;    case ec_blob:      new_exo->as_blob.data = (unsigned char *)malloc(new_exo->as_array.size);      memcpy(new_exo->as_blob.data, exo->as_blob.data, new_exo->as_array.size);      break;    default:      panic("bogus EXO class");    }  return new_exo;}/* deep copy an EXO structure */struct exo_term_t *exo_deepcopy(struct exo_term_t *exo){  struct exo_term_t *new_exo;  /* NULL copy */  if (!exo)    return NULL;  new_exo = exo_copy(exo);  switch (new_exo->ec)    {    case ec_integer:    case ec_address:    case ec_float:    case ec_char:    case ec_token:      /* exo_copy() == exo_deepcopy() for these node classes */      break;    case ec_string:      /* copy the referenced string */      new_exo->as_string.str =	(unsigned char *)strdup((char *)exo->as_string.str);      break;    case ec_list:      /* copy all list elements */      {	struct exo_term_t *elt, *new_elt, *new_list;	new_list = NULL;	for (elt=new_exo->as_list.head; elt != NULL; elt=elt->next)	  {	    new_elt = exo_deepcopy(elt);	    new_list = exo_chain(new_list, new_elt);	  }	new_exo->as_list.head = new_list;      }      break;    case ec_array:      /* copy all array elements */      {	int i;	for (i=0; i<new_exo->as_array.size; i++)	  {	    SET_EXO_ARR(new_exo, i, exo_deepcopy(EXO_ARR(exo, i)));	  }      }      break;    case ec_blob:      new_exo->as_blob.data = (unsigned char *)malloc(new_exo->as_array.size);      memcpy(new_exo->as_blob.data, exo->as_blob.data, new_exo->as_array.size);      break;    default:      panic("bogus EXO class");    }  return new_exo;}/* print an EXO term */voidexo_print(struct exo_term_t *exo, ostream &stream){    switch (exo->ec) {      case ec_integer:	ccprintf(stream, "%u", exo->as_integer.val);	break;      case ec_address:	ccprintf(stream, "%#x", exo->as_integer.val);	break;      case ec_float:	ccprintf(stream, "%f", exo->as_float.val);	break;      case ec_char:	stream << "'";	print_char(exo->as_char.val, stream);	stream << "'";	break;      case ec_string:	stream << "\"";	print_string(exo->as_string.str, stream);	stream << "\"";	break;      case ec_list:	{	    struct exo_term_t *ent;	    stream << "(";	    for (ent=exo->as_list.head; ent != NULL; ent=ent->next) {		exo_print(ent, stream);		if (ent->next)		    stream << ", ";	    }	    stream << ")";	}	break;      case ec_array:	{	    int i, last;	    /* search for last first non-NULL entry */	    for (last=exo->as_array.size-1; last >= 0; last--)		if (EXO_ARR(exo, last) != NULL)		    break;	    /* LAST == index of last non-NULL array entry */	    ccprintf(stream, "{%d}[", exo->as_array.size);	    for (i = 0; i < exo->as_array.size && i <= last; i++) {		if (exo->as_array.array[i] != NULL)		    exo_print(exo->as_array.array[i], stream);		else		    stream << " ";		if (i != exo->as_array.size-1 && i != last)		    stream << ", ";	    }	    stream << "]";	}	break;      case ec_token:	stream << exo->as_token.ent->str;	break;      case ec_blob:	{	    int i, cr = 0;	    ccprintf(stream, "{%d}<\n", exo->as_blob.size);	    for (i = 0; i < exo->as_blob.size; i++) {		cr = false;		if (i != 0 && (i % 38) == 0) {		    stream << "\n";		    cr = true;		}		ccprintf(stream, "%02x", exo->as_blob.data[i]);	    }	    if (!cr)		stream << "\n";	    stream << ">";	}	break;      default:	panic("bogus EXO class");    }}/* (f)lex external defs */extern int yylex(void);extern int yy_nextchar(void);extern char *yytext;extern FILE *yyin;static voidexo_err(char *err){  extern int line;  ccprintf(cerr, "EXO parse error: line %d: %s\n", line, err);  exit(1);}/* read one EXO term from STREAM */struct exo_term_t *exo_read(FILE *stream){  int tok;  char tok_buf[1024], *endp;  struct exo_term_t *ent = NULL;  extern void yy_setstream(FILE *);  /* make sure we have a valid stream */  if (!stream)    stream = stdin;  yy_setstream(stream);  /* make local copies of everything, allows arbitrary recursion */  tok = yylex();  strcpy(tok_buf, yytext);  switch (tok)    {    case lex_integer:      {	exo_integer_t int_val;	/* attempt integer conversion */	errno = 0;	int_val = myatoq(tok_buf, &endp, /* parse base */10);	if (!errno && !*endp)	  {	    /* good conversion */	    ent = exo_new(ec_integer, int_val);	  }	else	  exo_err("cannot parse integer literal");      }      break;    case lex_address:      {	exo_address_t addr_val;	/* attempt address conversion */	errno = 0;	addr_val = myatoq(tok_buf, &endp, /* parse base */16);	if (!errno && !*endp)	  {	    /* good conversion */	    ent = exo_new(ec_address, addr_val);	  }	else	  exo_err("cannot parse address literal");      }      break;    case lex_float:      {	exo_float_t float_val;	/* attempt double conversion */	errno = 0;	float_val = strtod(tok_buf, &endp);	if (!errno && !*endp)	  {	    /* good conversion */	    ent = exo_new(ec_float, float_val);	  }	else	  exo_err("cannot parse floating point literal");      }      break;    case lex_char:      {	int c;	c = intern_char(tok_buf, &endp);	if (!endp)	  exo_err("cannot convert character literal");	ent = exo_new(ec_char, c);      }      break;    case lex_string:      {	char *s;	s = intern_string(tok_buf);	ent = exo_new(ec_string, s);	free(s);      }      break;    case lex_token:      ent = exo_new(ec_token, tok_buf);      break;    case lex_byte:      exo_err("unexpected blob byte encountered");      break;    case '(':      {	struct exo_term_t *elt;	ent = exo_new(ec_list, NULL);	if (yy_nextchar() != ')')	  {	    /* not an empty list */	    do {	      elt = exo_read(stream);	      if (!elt)		exo_err("unexpected end-of-file");	      ent->as_list.head =		exo_chain(ent->as_list.head, elt);	      /* consume optional commas */	      if (yy_nextchar() == ',')		yylex();	    } while (yy_nextchar() != ')');	  }	/* read tail delimiter */	tok = yylex();	if (tok != ')')	  exo_err("expected ')'");      }      break;    case ')':      exo_err("unexpected ')' encountered");      break;    case '<':      exo_err("unexpected '<' encountered");      break;    case '>':      exo_err("unexpected '>' encountered");      break;    case '{':      {	int cnt, size;	struct exo_term_t *elt;	/* get the size */	elt = exo_read(stream);	if (!elt || elt->ec != ec_integer)	  exo_err("badly formed array size");	/* record the size of the array/blob */	size = (int)elt->as_integer.val;	/* done with the EXO integer */	exo_delete(elt);	/* read the array delimiters */	tok = yylex();	if (tok != '}')	  exo_err("expected '}'");	tok = yylex();	switch (tok)	  {	  case '[': /* array definition */	    /* allocate an array definition */	    ent = exo_new(ec_array, size, NULL);	    /* read until array is full or tail delimiter encountered */	    if (yy_nextchar() != ']')	      {		/* not an empty array */		cnt = 0;		do {		  if (cnt == ent->as_array.size)		    exo_err("too many initializers for array");		  /* NULL element? */		  if (yy_nextchar() == ',')		    {		      elt = NULL;		    }		  else		    {		      elt = exo_read(stream);		      if (!elt)			exo_err("unexpected end-of-file");		    }		  SET_EXO_ARR(ent, cnt, elt);		  cnt++;		  /* consume optional commas */		  if (yy_nextchar() == ',')		    yylex();		} while (yy_nextchar() != ']');	      }	    /* read tail delimiter */	    tok = yylex();	    if (tok != ']')	      exo_err("expected ']'");	    break;	  case '<': /* blob definition */	    /* allocate an array definition */	    ent = exo_new(ec_blob, size, /* zero contents */NULL);	    /* read until blob is full */	    if (yy_nextchar() != '>')	      {		unsigned int byte_val;		/* not an empty array */		cnt = 0;		for (;;) {		  /* read next blob byte */		  tok = yylex();		  if (tok == lex_byte)		    {		      if (cnt == ent->as_blob.size)			exo_err("too many initializers for blob");		      /* attempt hex conversion */		      errno = 0;		      byte_val = strtoul(yytext, &endp, /* parse base */16);		      if (errno != 0 || *endp != '\0')			exo_err("cannot parse blob byte literal");		      if (byte_val > 255)			panic("bogus byte value");		      ent->as_blob.data[cnt] = byte_val;		      cnt++;		    }		  else if (tok == '>')		    break;		  else		    exo_err("unexpected character in blob");		}	      }#if 0 /* zero tail is OK... */	    if (cnt != ent->as_blob.size)	      exo_err("not enough initializers for blob");#endif	    break;	  default:	    exo_err("expected '[' or '<'");	  }      }      break;    case '}':      exo_err("unexpected '}' encountered");      break;    case ',':      exo_err("unexpected ',' encountered");      break;    case '[':      {	int i, cnt;	struct exo_term_t *list, *elt, *next_elt;	/* compute the array size */	list = NULL;	if (yy_nextchar() == ']')	  exo_err("unsized array has no initializers");	cnt = 0;	do {	  /* NULL element? */	  if (yy_nextchar() == ',')	    {	      elt = exo_new(ec_null);	    }	  else	    {	      elt = exo_read(stream);	      if (!elt)		exo_err("unexpected end-of-file");	    }	  cnt++;	  list = exo_chain(list, elt);	  /* consume optional commas */	  if (yy_nextchar() == ',')	    yylex();	} while (yy_nextchar() != ']');	/* read tail delimiter */	tok = yylex();	if (tok != ']')	  exo_err("expected ']'");	/* create the array */	assert(cnt > 0);	ent = exo_new(ec_array, cnt, NULL);	/* fill up the array */	for (i=0,elt=list; i<cnt; i++,elt=next_elt)	  {	    assert(elt != NULL);	    next_elt = elt->next;	    if (elt->ec == ec_null)	      {		SET_EXO_ARR(ent, cnt, NULL);		exo_delete(ent);	      }	    else	      {		SET_EXO_ARR(ent, cnt, elt);		elt->next = NULL;	      }	  }      }      break;    case ']':      exo_err("unexpected ']' encountered");      break;    case lex_eof:      /* nothing to read */      ent = NULL;      break;    default:      panic("bogus token");    }  return ent;}

⌨️ 快捷键说明

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