示例#1
0
文件: lc.c 项目: Henry/Leda
struct symbolRecord* newClassSymbol
(
    struct symbolTableRecord* syms,
    struct symbolTableRecord* gsyms,
    char* name
)
{
    // Make sure name is unique or forward referenced
    struct symbolRecord* s = lookupLocal(syms, name);
    struct typeRecord* t = 0;
    if (s == 0) // new name
    {
        s = newSymbolRecord(name, classDefSymbol);
        s->u.c.location = syms->size++;
        addNewSymbol(syms, s);
        t = newTypeRecord(classType);
        s->u.c.typ = t;
    }
    else        // already defined
    {
        if (s->styp != classDefSymbol)
        {
            yyserror
            (
                "non class name %s used to define class",
                s->name
            );
        }
        t = s->u.c.typ;
        if (t == 0)
        {
            yyserror
            (
                "compiler error, missing type in class %s",
                s->name
            );
        }
        if (t->ttyp != classType)
        {
            yyserror("class %s has non class type field", s->name);
        }
        if (t->u.c.symbols)
        {
            yyserror("class %s multiply defined", s->name);
        }
    }

    struct symbolTableRecord* ns = newSymbolTable(classTable, syms);
    t->u.c.symbols = ns;
    ns->definingType = t;

    return s;
}
示例#2
0
文件: lc.c 项目: Henry/Leda
void uniqueName(struct symbolTableRecord* syms, char* name)
{
    if (lookupLocal(syms, name))
    {
        yyserror("name must be unique within context: %s", name);
    }
}
/* Make sure argument is OK */
static int check_arg(node_ptr arg, int wantbool)
{
    if (!arg) {
	yyerror("Null node encountered");
	return 0;
    }
    if (arg->type == N_VAR) {
	node_ptr qval = find_symbol(arg->sval);
	if (!qval) {
	    yyserror("Variable '%s' not found", arg->sval);
	    return 0;
	}
	if (wantbool != qval->isbool) {
	    if (wantbool)
		yyserror("Variable '%s' not Boolean", arg->sval);
	    else
		yyserror("Variable '%s' not integer", arg->sval);
	    return 0;
	}
	return 1;
    }
    if (arg->type == N_NUM) {
        if (wantbool && strcmp(arg->sval,"0") != 0 &&
	    strcmp(arg->sval,"1") != 0) {
	    yyserror("Value '%s' not Boolean", arg->sval);
	    return 0;
        }
	return 1;
    }
    if (wantbool && !arg->isbool)
	yyserror("Non Boolean argument '%s'", show_expr(arg));
    if (!wantbool && arg->isbool)
	yyserror("Non integer argument '%s'", show_expr(arg));
    return (wantbool == arg->isbool);
}
示例#4
0
void check_ast_var(node_ptr vnode)
{
    if (vnode->ntype == E_VAR)
	yyserror("Invalid variable '%s'", vnode->name);
    if (vnode->ntype == E_AREF) {
      check_ast_var(vnode->children[0]);
      return;
    }
    if (vnode->ntype != E_LVAR && vnode->ntype != E_AVAR && vnode->ntype != E_LAVAR) {
      fprintf(ERRFILE, "Error (check_ast_var).  Expected variable.  Got node of type %s\n", node_type_name(vnode->ntype));
      exit(1);
    }
}
static node_ptr find_symbol(char *name)
{
    int i;
    for (i = 0; i < sym_count; i++) {
	if (strcmp(name, sym_tab[0][i]->sval) == 0) {
	    node_ptr result = sym_tab[1][i];
	    sym_tab[0][i]->ref++;
	    return result;
	}
    }
    yyserror("Symbol %s not found", name);
    return NULL;
}
示例#6
0
文件: lc.c 项目: Henry/Leda
struct symbolRecord* lookupSymbol
(
    struct symbolTableRecord* syms,
    char* name
)
{
    for (; syms; syms = syms->surroundingContext)
    {
        struct symbolRecord* s = lookupLocal(syms, name);
        if (s) return s;
    }

    yyserror("unknown identifier: %s", name);

    return 0;
}
示例#7
0
/* Look for self-reference in assignment to newly declared variable */
void self_check(node_ptr dnode, node_ptr enode)
{
  int i;
  node_ptr vnode = dnode;
  if (!enode)
    return;
  /* First find variable node (in case of array) */
  while (vnode && vnode->ntype != E_LVAR && vnode->ntype != E_LAVAR)
    vnode = vnode->children[0];
  if (!vnode) {
    fprintf(ERRFILE, "Error (self_check).  No declared variable found\n");
    exit(1);
  }
  if ((enode->ntype == E_LVAR || enode->ntype == E_AVAR || enode->ntype == E_LAVAR) &&
      !strcmp(enode->name, vnode->name))
    yyserror("Invalid reference to newly-declared variable '%s'", vnode->name);
  for (i = 0; i < enode->degree; i++)
    self_check(vnode, enode->children[i]);
}
示例#8
0
node_ptr make_ast_num(char *sval)
{
  node_ptr result = new_node0(E_CONST, IOP_NONE);
  data_t dtype = DATA_SIGNED;
  int long_cnt = 0;
  int pos = strlen(sval)-1;
  int wsize = ISIZE;
  int i;
  int isdecimal = 1;
  char *endptr;
  ullong val = 0;
  float fval = 0.0;

/* Promotion rules for decimal integer constants */
promo_rec dec_int_promo[] =
  { { ISIZE-2, DATA_SIGNED, ISIZE },     /* int */
    { LSIZE-2, DATA_SIGNED, LSIZE },     /* long int */
    { LSIZE-1, DATA_UNSIGNED, LSIZE },   /* long unsigned */
    { LLSIZE-2, DATA_SIGNED, LLSIZE },   /* long long int */
    { LLSIZE-1, DATA_UNSIGNED, LLSIZE }, /* long long unsigned */
    { 0, 0, 0 }}; /* Too big */

promo_ptr dec_long_promo = &dec_int_promo[1];
promo_ptr dec_llong_promo = &dec_int_promo[3];

/* Promotion rules for hex/octal integer constants */
promo_rec hex_int_promo[] =
  { { ISIZE-2, DATA_SIGNED, ISIZE },     /* int */
    { ISIZE-1, DATA_UNSIGNED, ISIZE },   /* unsigned */
    { LSIZE-2, DATA_SIGNED, LSIZE },     /* long int */
    { LSIZE-1, DATA_UNSIGNED, LSIZE },   /* long unsigned */
    { LLSIZE-2, DATA_SIGNED, LLSIZE },   /* long long int */
    { LLSIZE-1, DATA_UNSIGNED, LLSIZE }, /* long long unsigned */
    { 0, 0, 0 }}; /* Too big */

promo_ptr hex_long_promo = &hex_int_promo[2];
promo_ptr hex_llong_promo = &hex_int_promo[4];

/* Promotion rules for unsigned integer constants */
promo_rec unsigned_int_promo[] =
  { { ISIZE-1, DATA_UNSIGNED, ISIZE }, /* unsigned */
    { LSIZE-1, DATA_UNSIGNED, LSIZE }, /* long unsigned */
    { LLSIZE-1, DATA_UNSIGNED, LLSIZE }, /* long long unsigned */
    { 0, 0, 0 }}; /* Too big */


promo_ptr unsigned_long_promo = &dec_int_promo[1];
promo_ptr unsigned_llong_promo = &dec_int_promo[2];

promo_ptr all_dec_promo[3] = { dec_int_promo, dec_long_promo, dec_llong_promo };
promo_ptr all_hex_promo[3] = { hex_int_promo, hex_long_promo, hex_llong_promo };
promo_ptr all_unsigned_promo[3] = { unsigned_int_promo, unsigned_long_promo, unsigned_llong_promo };

  /* See if suffixed with u, U, l, or L */
  int c = sval[pos];
  while (!isxdigit(c)) {
    switch (c) {
    case 'u':
    case 'U':
      dtype = DATA_UNSIGNED;
      break;
    case 'l':
    case 'L':
      long_cnt++;
      break;
    default:
      yyserror("Invalid number: '%s'", sval);
      break;
    }
    sval[pos] = 0;
    c = sval[--pos];
  }
  if (sval[0] == '0')
    isdecimal = 0;
  /* See if contains ., e, or E, but is not in hex */
  for (i = 0; sval[i]; i++) {
    char c = sval[i];
    if (c == 'x' || c == 'X') {
      break; /* hex */
    }
    if (c == '.' || c == 'e' || c == 'E') {
      dtype = DATA_FLOAT;
      isdecimal = 0;
      break;
    }
  }
  if (dtype == DATA_FLOAT) {
    fval = strtof(sval, &endptr);
    wsize = FSIZE;
  } else {
#if HAVE_LONGLONG
    val = strtoull(sval, &endptr, 0);
#else
    val = strtoul(sval, &endptr, 0);
#endif
  }
  if (*endptr)
    yyserror("Invalid number '%s'", sval);

  if (dtype != DATA_FLOAT) {
    ullong bits;
    /* Find the most significant 1 position */
    int msone = -1;
    for (bits = val; bits; bits >>= 1)
      msone++;
    if (long_cnt > 2)
      yyserror("Invalid number: '%s'", sval);
    else {
      /* Apply rules for sizing/typing integer constants */
      promo_ptr rules =
	dtype == DATA_UNSIGNED ? all_unsigned_promo[long_cnt] :
	isdecimal ? all_dec_promo[long_cnt] : all_hex_promo[long_cnt];
      int ok = 0;
      for (i = 0; !ok && rules[i].maxpos != 0; i++) {
	if (msone <= rules[i].maxpos) {
	  /* Debugging */
#ifdef DEBUG
	  data_t old_dtype = dtype;
	  int old_wsize = wsize;
#endif
	  /* Change to this data type */
	  dtype = rules[i].dtype;
	  wsize = rules[i].wsize;
#ifdef DEBUG
	  if (old_dtype != dtype || old_wsize != wsize) {
	    printf("Changing '%s' to data type %s, word size %d (msb at %d)\n",
		   sval, dtype == DATA_UNSIGNED ? "unsigned" : "int", wsize, msone);
	  }
#endif
	  ok = 1;
	}
      }
      if (!ok) {
	yyserror("Number too large for data type: '%s'", sval);
      }
    }
  }
/* Recursively generate code for function */
static void gen_expr(node_ptr expr)
{
    node_ptr ele;
    switch(expr->type) {
    case N_QUOTE:
	yyserror("Unexpected quoted string", expr->sval);
	break;
    case N_VAR:
	{
	    node_ptr qstring = find_symbol(expr->sval);
	    if (qstring)
#if defined(VLOG) || defined(UCLID)
		outgen_print("%s", expr->sval);
#else
		outgen_print("(%s)", qstring->sval);
#endif
	    else
		yyserror("Invalid variable '%s'", expr->sval);
#ifdef UCLID
	    check_for_arg(expr->sval);
#endif
	    
	}
	break;
    case N_NUM:
#ifdef UCLID
      {
	long long int val = atoll(expr->sval);
	if (val < -1)
	  outgen_print("pred^%d(CZERO)", -val);
	else if (val == -1)
	  outgen_print("pred(CZERO)");
	else if (val == 0)
	  outgen_print("CZERO");
	else if (val == 1)
	  outgen_print("succ(CZERO)");
	else
	  outgen_print("succ^%d(CZERO)", val);
      }
#else /* !UCLID */
 	fputs(expr->sval, outfile);
#endif /* UCLID */
	break;
    case N_AND:
	outgen_print("(");
	outgen_upindent();
	gen_expr(expr->arg1);
	outgen_print(" & ");
	gen_expr(expr->arg2);
	outgen_print(")");
	outgen_downindent();
	break;
    case N_OR:
	outgen_print("(");
	outgen_upindent();
	gen_expr(expr->arg1);
	outgen_print(" | ");
	gen_expr(expr->arg2);
	outgen_print(")");
	outgen_downindent();
	break;
    case N_NOT:
#if defined(VLOG) || defined(UCLID)
	outgen_print("~");
#else
	outgen_print("!");
#endif
	gen_expr(expr->arg1);
	break;
    case N_COMP:
	outgen_print("(");
	outgen_upindent();
	gen_expr(expr->arg1);
#ifdef UCLID
	{
	  char *cval = expr->sval;
	  if (strcmp(cval, "==") == 0)
	    cval = "=";
	  outgen_print(" %s ", cval);
	}
#else /* !UCLID */
	outgen_print(" %s ", expr->sval);
#endif /* UCLID */
	gen_expr(expr->arg2);
	outgen_print(")");
	outgen_downindent();
	break;
    case N_ELE:
	outgen_print("(");
	outgen_upindent();
	for (ele = expr->arg2; ele; ele=ele->next) {
	    gen_expr(expr->arg1);
#ifdef UCLID
	    outgen_print(" = ");
#else
	    outgen_print(" == ");
#endif
	    gen_expr(ele);
	    if (ele->next)
#if defined(VLOG) || defined(UCLID)
		outgen_print(" | ");
#else
		outgen_print(" || ");
#endif
	}
	outgen_print(")");
	outgen_downindent();
	break;
    case N_CASE:
#ifdef UCLID
      outgen_print("case");
      outgen_terminate();
      {
	  /* Use this to keep track of last case when no default is given */
	  node_ptr last_arg2 = NULL;
	  for (ele = expr; ele; ele=ele->next) {
	      outgen_print("      ");
	      if (ele->arg1->type == N_NUM && atoll(ele->arg1->sval) == 1) {
		  outgen_print("default");
		  last_arg2 = NULL;
	      }
	      else {
		  gen_expr(ele->arg1);
		  last_arg2 = ele->arg2;
	      }
	      outgen_print(" : ");
	      gen_expr(ele->arg2);
	      outgen_print(";");
	      outgen_terminate();
	  }
	  if (last_arg2) {
	      /* Use final case as default */
	      outgen_print("      default : ");
	      gen_expr(last_arg2);
	      outgen_print(";");
	      outgen_terminate();
	  }
      }
      outgen_print("    esac");
#else /* !UCLID */
	outgen_print("(");
	outgen_upindent();
	int done = 0;
	for (ele = expr; ele && !done; ele=ele->next) {
	  if (ele->arg1->type == N_NUM && atoll(ele->arg1->sval) == 1) {
	    gen_expr(ele->arg2);
	    done = 1;
	  } else {
	    gen_expr(ele->arg1);
	    outgen_print(" ? ");
	    gen_expr(ele->arg2);
	    outgen_print(" : ");
	  }
	}
	if (!done)
	  outgen_print("0");
	outgen_print(")");
	outgen_downindent();
#endif
	break;
    default:
	yyerror("Unknown node type");
	break;
    }