Пример #1
0
const_type make_literal_message(id_type id)
{
   const_type c = (const_type) SafeMalloc(sizeof(const_struct));

   lookup_id(id);		
   switch (id->type)
   {
   case I_MESSAGE:
      break;

   case I_MISSING:
      if (id->source != I_MESSAGE)
	 action_error("Identifier %s was referenced earlier with different type", id->name);
      break;

   default: 
      add_identifier(id, I_MISSING);
      id->source = I_MESSAGE;
      break;     
   }
   /* Make a constant expression whose value is the id # */
   c->type = C_MESSAGE;
   c->value.numval = id->idnum; 

   return c;
}
Пример #2
0
const_type make_number_from_constant_id(id_type id)
{
   const_type c = (const_type) SafeMalloc(sizeof(const_struct));

   lookup_id(id);
   switch(id->type)
   {

   case I_CONSTANT:
      c->type = C_NUMBER;
      c->value.numval = id->source;  /* Value is stored in source field */
      break;

   case I_RESOURCE:
      /* Turn resource id reference into the resource # itself */
      c->type = C_RESOURCE;
      c->value.numval = id->idnum;       
      break;

   default:
      action_error("Identifier %s can only be a constant here", id->name);
      return NULL;      
   }
      
   return c;
}
Пример #3
0
resource_type make_resource(id_type id, const_type c)
{
   resource_type r = (resource_type) SafeMalloc(sizeof(resource_struct));
   id_type old_id;

   id->ownernum = st.curclass;

   /* Left-hand side must not have appeared before, except maybe in dbase */
   old_id = lookup_id(id);
   switch(id->type) {
   case I_UNDEFINED:
      id->source = COMPILE;
      add_identifier(id, I_RESOURCE);
      break;

   case I_RESOURCE:
      /* Allow redefinition of resources listed in database file */
      if (id->source == COMPILE)
	 action_error("Resource %s is defined twice", id->name);
      else
	 old_id->source = COMPILE;

      id->source = COMPILE;
      break;
      
   default:
      action_error("Duplicate identifier %s", id->name);
   }

   r->lhs = id;
   r->rhs = c;
   return r;
}
Пример #4
0
void parse_macro(char* line){
	uint8_t action, length, i, j = 0;
	if(memcmp(line,"[MACRO_",7)==0){
		macro_idx = line[7] - '0' - 1;
	} else { 
		ptr = line;
		j=0;
		while((token = strtok_r(ptr, ",", &rest)) != NULL) {
			ptr2 = token;
			i = length = action = 0;
			while((token2 = strtok_r(ptr2, ":", &rest2)) != NULL) {
				if(i==0){
					length = atoi(token2);
				} else if(i == 1){
					action = lookup_id(token2);
				}
				i++;
				ptr2 = rest2;
			}
			phex(action); phex(length); print("\n");
			macro_steps[macro_idx][(j*2)] = action;
			macro_steps[macro_idx][(j*2)+1] = length;
			ptr = rest;
			j++;
		}
		macro_sizes[macro_idx] = j;
		//for(j=0;j<macro_sizes[macro_idx];){
		//	phex(j);phex(macro_steps[macro_idx][j++]); phex(macro_steps[macro_idx][j++]);print(" ");
		//}
	}
}
Пример #5
0
expr_type make_expr_from_id(id_type id)
{
   expr_type e = (expr_type) SafeMalloc(sizeof(expr_struct));
   
   /* Id must be a parameter, local, property, constant, or resource */
   lookup_id(id);		
   switch(id->type)
   {
   case I_LOCAL:
   case I_PROPERTY:
   case I_CLASSVAR:
      e->type = E_IDENTIFIER;
      e->value.idval = id;
      break;

   case I_RESOURCE:
   {
      const_type c = (const_type) SafeMalloc(sizeof(const_struct));

      /* Turn resource id reference into the resource # itself */
      c->type = C_RESOURCE;
      c->value.numval = id->idnum; 

      e->type = E_CONSTANT;
      e->value.constval = c;
      return e;
   }

   case I_CONSTANT:
   {
      const_type c = (const_type) SafeMalloc(sizeof(const_struct));
      id_type temp;

      /* Turn constant id reference into the constant itself */
      c->type = C_NUMBER;

      temp = (id_type) list_find_item(st.constants, id, id_compare);
      c->value.numval = temp->source; /* Value is stored in source field */

      e->type = E_CONSTANT;
      e->value.constval = c;
      break;
   }
   case I_UNDEFINED:
   case I_MISSING:
      action_error("Unknown identifier %s", id->name);
      /* Put in something so that compilation can continue */
      e = make_expr_from_constant(make_nil_constant());
      break;

   default:
      action_error("Identifier %s in expression has wrong type", id->name);
      /* Put in something so that compilation can continue */
      e = make_expr_from_constant(make_nil_constant());
      break;
   }
   e->lineno = lineno;
   return e;
}
Пример #6
0
struct scope_tree_node * traverse_identifier(struct node * n, struct scope_tree_node * parent_scope) { 
  #ifdef DEBUG
  printf("traverse_identifier\n");
  #endif

  lookup_id(n->data.identifier.name);
  return parent_scope;
}
Пример #7
0
int sd_genl_message_new(sd_netlink *nl, sd_genl_family family, uint8_t cmd, sd_netlink_message **ret) {
        int r;
        uint16_t id = GENL_ID_CTRL;

        if (family != SD_GENL_ID_CTRL) {
                r = lookup_id(nl, family, &id);
                if (r < 0)
                        return r;
        }

        return genl_message_new(nl, family, id, cmd, ret);
}
Пример #8
0
param_type make_parameter(id_type id, expr_type e)
{
   param_type p = (param_type) SafeMalloc(sizeof(param_struct));

   if (e->type != E_CONSTANT)
   {
      action_error("Parameter can only be initialized to a constant");
      return p;
   }

   lookup_id(id);

   /* Left-hand side must not have appeared before, except perhaps as a parameter */
   switch (id->type) {
   case I_MISSING:
      /* The parameter has been referenced in a function call, but not declared anywhere 
       * We should use the existent id # and remove the id from the missing list.
       * First we must make sure that the missing id is supposed to be a missing parameter.
       */
      if (id->source != I_PARAMETER)
      {
	 action_error("Parameter %s was referenced elsewhere with different type", id->name);
	 break;
      }
      
      /* Insert directly into global table to preserve id # */
      id->type = I_PARAMETER;
      id->source = COMPILE;
      table_insert(st.globalvars, (void *) id, id_hash, id_compare);

      /* Remove from missing list */
      table_delete_item(st.missingvars, id, id_hash, id_compare);
      break;

   case I_UNDEFINED:   /* New parameter # */
      id->ownernum = st.curmessage;
      add_identifier(id, I_PARAMETER);
      break;

   case I_PARAMETER:
      /* Legal only if it hasn't yet appeared in this message */
      if (id->ownernum == st.curmessage && id->source == COMPILE)
	 action_error("Parameter %s appears twice", id->name);
      break;

   default:            /* Other types indicate name already used */
      action_error("Duplicate identifier %s", id->name);
   }

   p->lhs = id;
   p->rhs = e->value.constval;
   return p;
}
Пример #9
0
static int
sfs_idbyname (const char *id, bool_t gid, dev_t dev)
{
  struct id_cache *ic_elm;

  ic_elm = lookup_ic (dev);
  
  if (!ic_elm)
    return -1;

  return lookup_id (ic_elm, gid, (char *)id);
}
Пример #10
0
id_type make_var(id_type id)
{
   /* Add to list of local variables, if it hasn't been defined */
   lookup_id(id);

   switch(id->type)
   {
   case I_LOCAL:
      action_error("Duplicate identifier %s", id->name);

   default:
      id->ownernum = st.curmessage;
      add_identifier(id, I_LOCAL);
      break;

   }
   return id;
}
Пример #11
0
classvar_type make_classvar(id_type id, expr_type e)
{
   classvar_type cv;

   cv = (classvar_type) SafeMalloc(sizeof(classvar_struct));

   if (e->type != E_CONSTANT)
   {
      action_error("Classvar can only be initialized to a constant");
      return cv;
   }

   lookup_id(id);
   switch(id->type) 
   {
   case I_CONSTANT:
   case I_PROPERTY:
      action_error("Duplicate identifier %s", id->name);
      break;
      
      /* Legal if it hasn't yet appeared in this class */
   case I_CLASSVAR:
      if (id->ownernum == st.curclass && id->source == COMPILE)
	 action_error("Class variable %s appears twice", id->name);
      else 
      {
	 id->ownernum = st.curclass;
	 id->source = COMPILE;
	 add_identifier(id, I_CLASSVAR);
      }
      break;

   default:
      id->source = COMPILE;
      id->ownernum = st.curclass;
      add_identifier(id, I_CLASSVAR);
      break;
   }

   cv->id = id;
   cv->rhs = e->value.constval;
   return cv;   
}
Пример #12
0
stmt_type make_for_stmt(id_type id, expr_type expr, list_type stmts)
{
   stmt_type stmt = (stmt_type) SafeMalloc(sizeof(stmt_struct));
   for_stmt_type s = (for_stmt_type) SafeMalloc(sizeof(for_stmt_struct));

   /* Loop variable must be a local, property or parameter */
   lookup_id(id);
   if (id->type == I_UNDEFINED || id->type == I_MISSING)
      action_error("Unknown identifier %s", id->name);
   else
      if (id->type != I_LOCAL && id->type != I_PROPERTY)
	 action_error("Loop variable %s has wrong type", id->name);

   s->id = id;
   s->condition = expr;
   s->body = stmts;

   stmt->type = S_FOR;
   stmt->value.for_stmt_val = s;
   return stmt;
}
Пример #13
0
stmt_type make_assign_stmt(id_type id, expr_type expr)
{
   stmt_type stmt = (stmt_type) SafeMalloc(sizeof(stmt_struct));
   assign_stmt_type s = (assign_stmt_type) SafeMalloc(sizeof(assign_stmt_struct));

   /* Left-hand side must be a local or property */
   lookup_id(id);
   if (id->type == I_UNDEFINED || id->type == I_MISSING)
      action_error("Unknown identifier %s", id->name);
   else
      if (id->type != I_PROPERTY && id->type != I_LOCAL)
	 action_error("Identifier %s cannot be assigned to", id->name);

   /* Can't assign to SELF */
   if (id->type == I_PROPERTY && id->idnum == 0)
      action_error("Can't assign to self");

   s->lhs = id;
   s->rhs = expr;

   stmt->type = S_ASSIGN;
   stmt->value.assign_stmt_val = s;
   return stmt;
}
Пример #14
0
stmt_type make_call(id_type function_id, list_type args)
{
   stmt_type stmt = (stmt_type) SafeMalloc(sizeof(stmt_struct));
   call_stmt_type s = (call_stmt_type) SafeMalloc(sizeof(call_stmt_struct));
   int argnum = 0, argtype, continuation = ANONE, minargs = 0, i, index;
   const char *fname;
   arg_type arg;
   id_type id, new_id;

   s->args = NULL;

   /* Verify that id is the name of a built-in function */
   lookup_id(function_id);

   if (function_id->type != I_FUNCTION)
   {
      action_error("Expecting a function name; found %s", function_id->name);
      return stmt;
   }

   index = function_id->idnum;  /* index # of function to call */

   fname = Functions[index].name;
   s->function = Functions[index].opcode;
      
   /* Check that types of arguments match "function prototype" in table */
   for ( ; args != NULL; args = args->next)
   {
      argtype = Functions[index].params[argnum];

      /* See if we are looking for one or more expressions or parameters */
      if (continuation != ANONE)
	 argtype = continuation;

      arg = (arg_type) args->data;
      switch (argtype) 
      {
      case ANONE:
	 action_error("Extra argument #%d to function %s", argnum+1, fname);
	 return stmt; /* Ignore additional extra arguments */
	 break;

      case AEXPRESSIONS:
	 continuation = AEXPRESSION;
	 /* fall through */
      case AEXPRESSION:
	 /* Must have an expression here */
	 if (arg->type != ARG_EXPR)
	    action_error("Expecting expression in argument #%d",
			 argnum+1, fname);
	 else
	    s->args = list_add_item(s->args, (void *) arg);
	 break;

      case ASETTINGS:
	 continuation = ASETTING;
	 /* fall through */
      case ASETTING:
	 if (arg->type != ARG_SETTING)
	 {
	    action_error("Expecting setting (i.e. #a=b ) in argument #%d",
			 argnum+1, fname);
	    break;
	 }
	 
	 /* Find parameter id */
	 id = arg->value.setting_val->id;
	 lookup_id(id);
	 
	 switch(id->type)
	 {
	 case I_UNDEFINED:
	    /* If parameter hasn't been defined yet, put on missing list */
	    add_identifier(id, I_MISSING);

	    /* Use source field to indicate where id came from for later checking */
	    id->source = I_PARAMETER;

	    s->args = list_add_item(s->args, (void *) arg);
	    break;
	    
	 case I_MISSING:
	    if (id->source != I_PARAMETER)
	    {
	       action_error("Duplicate identifier %s", id->name);
	       break;
	    }
	    s->args = list_add_item(s->args, (void *) arg);
	    break;

	    /* The tag here should be I_PARAMETER, but parameters also inserted as locals.
	     */
	 case I_LOCAL: 
	    /* Unfortunately, we want the parameter id #, and not the local id #.  So
	     * we have to look up the id again in the global table. */
	    new_id = (id_type) table_lookup(st.globalvars, (void *) id, id_hash, id_compare);

	    /* If it isn't there, then there happens to be a local variable of the same
	     * name as this parameter, and the parameter hasn't appeared before.  Thus the
	     * parameter id should be added as a missing variable.  We can't use the normal
	     * lookup_id and add_identifier procs, since the local variable will mask
	     * the missing one.
	     */
	    if (new_id == NULL)
	    {
	       /* Of course, the id might already have been inserted as a missing var */
	       new_id = (id_type) table_lookup(st.missingvars, (void *) id, id_hash, id_compare);
	       if (new_id == NULL)
	       {
		  id->source = I_PARAMETER;
		  id->type = I_MISSING;
		  id->idnum = ++st.maxid;
		  table_insert(st.missingvars, (void *) id, id_hash, id_compare);
	       }
	       else 
	       {
		  /* If it was already there, make sure that it was a parameter */
		  if (new_id->source != I_PARAMETER)
		     action_error("Duplicate identifier %s", id->name);
		  id->source = new_id->source;
		  id->type = I_MISSING;
		  id->source = I_PARAMETER;
		  id->idnum = new_id->idnum;
	       }
	       
	    }
	    else 
	    {
	       id = new_id;
	       if (id->type != I_PARAMETER)
		  action_error("Can't find parameter %s", id->name);
	    }

	    arg->value.setting_val->id = id;
	    /* If literal exists, proceed normally */
	    s->args = list_add_item(s->args, (void *) arg);
	    break;

	    /* But if the identifier is from another handler, might not be local */
	 case I_PARAMETER:
	    s->args = list_add_item(s->args, (void *) arg);
	    break;

	 default:
	    action_error("Literal %s is a duplicate identifier", id->name);
	 }
	 break;
      }
      
      argnum++;
   }
   /* Check that no arguments left out */
   for (i=0; i < MAXARGS; i++)
   {
      argtype = Functions[index].params[i];
      if (argtype == ANONE || argtype == ASETTINGS || argtype == AEXPRESSIONS)
	 break; /* Zero or more arguments follow */
      
      minargs++;
   }
   if (argnum < minargs)
      action_error("Expecting %d arguments to %s; found %d", minargs, fname, argnum);

   /* Sort parameter arguments in increasing order for server efficiency */
   s->args = SortArgumentList(s->args);

   stmt->type = S_CALL;
   stmt->value.call_stmt_val = s;
   return stmt;
}
Пример #15
0
property_type make_property(id_type id, expr_type e)
{
   property_type p = (property_type) SafeMalloc(sizeof(property_struct));

   if (e->type != E_CONSTANT)
   {
      action_error("Property can only be initialized to a constant");
      return p;
   }

   /* Left-hand side must not have appeared as a property before, except possibly as a
    * property of one of our superclasses.  Properties shadow other global names. */
   lookup_id(id);
   switch(id->type) {

   case I_CONSTANT:
      action_error("Duplicate identifier %s", id->name);
      break;
      
      /* Legal if it hasn't yet appeared in this class */
   case I_PROPERTY:
      if (id->ownernum == st.curclass && id->source == COMPILE)
	 action_error("Property %s appears twice", id->name);
      else 
      {
	 id->ownernum = st.curclass;
	 id->source = COMPILE;
	 add_identifier(id, I_PROPERTY);
      }
      break;

   case I_CLASSVAR:
      if (id->ownernum == st.curclass && id->source == COMPILE)
	 action_error("Property and classvar %s both appear in same class\n", id->name);
      else
      {
	 classvar_type new_cv;
	 id_type new_id;
	 const_type new_const;
	 
	 // Override classvar with special tag value
	 new_cv = (classvar_type) SafeMalloc(sizeof(classvar_struct));
	 new_const = (const_type) SafeMalloc(sizeof(const_struct));
	 new_id = duplicate_id(id);

	 new_cv->id = new_id;
	 new_cv->rhs = new_const;
	 new_id->ownernum = st.curclass;
	 new_id->source = COMPILE;
	 new_const->type = C_OVERRIDE;
	 
	 // Replace classvar with property in table
	 table_delete_item(st.classvars, id, id_hash, id_compare);
	 id->ownernum = st.curclass;
	 id->source = COMPILE;
	 add_identifier(id, I_PROPERTY);

	 // Store # of property in class var
	 new_const->value.numval = id->idnum;

	 st.override_classvars = list_add_item(st.override_classvars, new_cv);	 
      }
      break;

   default:
      id->source = COMPILE;
      id->ownernum = st.curclass;
      add_identifier(id, I_PROPERTY);
      break;
   }

   p->id = id;
   p->rhs = e->value.constval;
   return p;   
}
Пример #16
0
id_type make_constant_id(id_type id, expr_type expr)
{
   int numeric_val;

   /* Right hand side must be a number or a negative number */
   switch (expr->type)
   {
   case E_CONSTANT:
   {
      const_type c = (const_type) expr->value.constval;
      if (c->type == C_NUMBER)
	 numeric_val = c->value.numval;
      else action_error("Right hand side must be a numeric constant");
      break;
   }
   case E_UNARY_OP:
   {
      const_type c;
      expr_type sub_expr = expr->value.unary_opval.exp;
      int op = expr->value.unary_opval.op;
      
      if (op != NEG_OP || sub_expr->type != E_CONSTANT)
      {
         action_error("Right hand side must be a numeric constant");
         break;
      }
      
      c = (const_type) sub_expr->value.constval;
      if (c->type == C_NUMBER)
         numeric_val = - c->value.numval;
      else action_error("Right hand side must be a numeric constant");
      break;
   }
   default:
      action_error("Right hand side must be a numeric constant");
   }
   

   lookup_id(id);

   /* Left hand side cannot have appeared before */
   switch (id->type)
   {
   case I_UNDEFINED:
      id->ownernum = st.curclass;
      /* Store value in source field.  This is kind of a hack, but now we can 
	 insert just the id in st.constants, making it easy to find later. */
      id->source = numeric_val;
      add_identifier(id, I_CONSTANT);
      break;
      
   default:
      action_error("Duplicate identifier %s", id->name);
      break;
   }

   /* Add to list of constants in this class */
   st.constants = list_add_item(st.constants, id);
   
   return id;
}
Пример #17
0
static int post_cb(int op, int id, int subid, void *ex)
{
    const char *idstr, *exstr = "";
    char asctmp[20];
    int keytype = -1;
#ifdef FIPS_POST_TIME
    static struct timespec start, end, tstart, tend;
#endif
    switch(id)
    {
    case FIPS_TEST_INTEGRITY:
        idstr = "Integrity";
        break;

    case FIPS_TEST_DIGEST:
        idstr = "Digest";
        exstr = lookup_id(subid);
        break;

    case FIPS_TEST_CIPHER:
        exstr = lookup_id(subid);
        idstr = "Cipher";
        break;

    case FIPS_TEST_SIGNATURE:
        if (ex)
        {
            EVP_PKEY *pkey = ex;
            keytype = pkey->type;
            exstr = lookup_id(keytype);
        }
        idstr = "Signature";
        break;

    case FIPS_TEST_HMAC:
        exstr = lookup_id(subid);
        idstr = "HMAC";
        break;

    case FIPS_TEST_CMAC:
        idstr = "CMAC";
        exstr = lookup_id(subid);
        break;

    case FIPS_TEST_GCM:
        idstr = "GCM";
        break;

    case FIPS_TEST_XTS:
        idstr = "XTS";
        exstr = lookup_id(subid);
        break;

    case FIPS_TEST_CCM:
        idstr = "CCM";
        break;

    case FIPS_TEST_X931:
        idstr = "X9.31 PRNG";
        sprintf(asctmp, "keylen=%d", subid);
        exstr = asctmp;
        break;

    case FIPS_TEST_DRBG:
        idstr = "DRBG";
        if (*(int *)ex & DRBG_FLAG_CTR_USE_DF)
        {
            sprintf(asctmp, "%s DF", lookup_id(subid));
            exstr = asctmp;
        }
        else
            exstr = lookup_id(subid);
        break;

    case FIPS_TEST_PAIRWISE:
        if (ex)
        {
            EVP_PKEY *pkey = ex;
            keytype = pkey->type;
            exstr = lookup_id(keytype);
        }
        idstr = "Pairwise Consistency";
        break;

    case FIPS_TEST_CONTINUOUS:
        idstr = "Continuous PRNG";
        break;

    default:
        idstr = "Unknown";
        break;

    }

    switch(op)
    {
    case FIPS_POST_BEGIN:
#ifdef FIPS_POST_TIME
        clock_getres(CLOCK_REALTIME, &tstart);
        printf("\tTimer resolution %ld s, %ld ns\n",
               (long)tstart.tv_sec, (long)tstart.tv_nsec);
        clock_gettime(CLOCK_REALTIME, &tstart);
#endif
        printf("\tPOST started\n");
        break;

    case FIPS_POST_END:
        printf("\tPOST %s\n", id ? "Success" : "Failed");
#ifdef FIPS_POST_TIME
        clock_gettime(CLOCK_REALTIME, &tend);
        printf("\t\tTook %f seconds\n",
               (double)((tend.tv_sec+tend.tv_nsec*1e-9)
                        - (tstart.tv_sec+tstart.tv_nsec*1e-9)));
#endif
        break;

    case FIPS_POST_STARTED:
        printf("\t\t%s %s test started\n", idstr, exstr);
#ifdef FIPS_POST_TIME
        clock_gettime(CLOCK_REALTIME, &start);
#endif
        break;

    case FIPS_POST_SUCCESS:
        printf("\t\t%s %s test OK\n", idstr, exstr);
#ifdef FIPS_POST_TIME
        clock_gettime(CLOCK_REALTIME, &end);
        printf("\t\t\tTook %f seconds\n",
               (double)((end.tv_sec+end.tv_nsec*1e-9)
                        - (start.tv_sec+start.tv_nsec*1e-9)));
#endif
        break;

    case FIPS_POST_FAIL:
        printf("\t\t%s %s test FAILED!!\n", idstr, exstr);
        break;

    case FIPS_POST_CORRUPT:
        if (fail_id == id
                && (fail_key == -1 || fail_key == keytype)
                && (fail_sub == -1 || fail_sub == subid))
        {
            printf("\t\t%s %s test failure induced\n", idstr, exstr);
            return 0;
        }
        break;

    }
    return 1;
}
Пример #18
0
enum datatype resolve_datatype(struct ast* expr, struct ast* function){
	if(expr == NULL){
		return NONE;
	}
	switch(expr->type){
		case ASSIGN:
			return resolve_datatype(expr->_assign.expr, function);
		break;
		case LITERAL:
			return expr->_literal.type;
		break;
		case IDENT:
		{
			struct lookup_result l = lookup_id(function, expr->_ident.name);
			if(l.ast != NULL && (l.ast->type == VARDEC || l.ast->type == PARAM)){
				return resolve_decalaration_type(l.ast,function);
			}else{
				return INVALID_DATATYPE;
			}
		}
		case CALL:
		{
			struct lookup_result l = lookup_id(function, expr->_ident.name);
			if(l.ast != NULL && l.ast->type == FUNCDEC){
				return resolve_decalaration_type(l.ast,function);
			}else{
				return INVALID_DATATYPE;
			}
		}
		break;
		case BINARY:
		{
			enum datatype lhs_type = resolve_datatype(expr->_binary.lhs, function);
			enum datatype rhs_type = resolve_datatype(expr->_binary.rhs, function);
			switch(expr->_binary.op){
				case ADD:
				case SUB:
				case DIV:
				case MUL:
					switch(lhs_type){
						case DOUBLE:
							switch(rhs_type){
								case DOUBLE: return DOUBLE;
								case INT: return DOUBLE;
								default: return INVALID_DATATYPE;
							}
						break;
						case INT:
							switch(rhs_type){
								case DOUBLE: return DOUBLE;
								case INT: return INT;
								default: return INVALID_DATATYPE;
							}
						break;
						default: return INVALID_DATATYPE;
						break;
					}
				break;
				case LE:
				case LT:
				case EQ:
				case NE:
				case GT:
				case GE:
					switch(lhs_type){
						case DOUBLE:
							switch(rhs_type){
								case DOUBLE: return INT;
								case INT: return INT;
								default: return INVALID_DATATYPE;
							}
						break;
						case INT:
							switch(rhs_type){
								case DOUBLE: return INT;
								case INT: return INT;
								default: return INVALID_DATATYPE;
							}
						break;
						default: return INVALID_DATATYPE;
						break;
					}
				break;
				case MOD:
					switch(lhs_type){
						case DOUBLE:
							switch(rhs_type){
								case DOUBLE: return INVALID_DATATYPE;
								case INT: return INVALID_DATATYPE;
								default: return INVALID_DATATYPE;
							}
						break;
						case INT:
							switch(rhs_type){
								case DOUBLE: return INVALID_DATATYPE;
								case INT: return INT;
								default: return INVALID_DATATYPE;
							}
						break;
						default: return INVALID_DATATYPE;
						break;
					}
				break;
				default: return INVALID_DATATYPE;
			}
		}
		break;
		case UNARY:
		{
			enum datatype operand = resolve_datatype(expr->_unary.operand, function);
			switch(expr->_unary.op){
				case CHS:
					switch(operand){
						case INT: return INT;
						case DOUBLE: return DOUBLE;
						default: return INVALID_DATATYPE;
					}
				break;
				case NOT:
					switch(operand){
						case INT: return INT;
						case DOUBLE: return INVALID_DATATYPE;
						default: return INVALID_DATATYPE;
					}
				break;
				default: return INVALID_DATATYPE;
			}
		}
		break;
		case LIST:
		{
			struct ast* last = expr;
			while(last->_list.next != NULL){
				last = last->_list.next;
			}
			return resolve_datatype(last->_list.item, function);
		}
		break;
		case IF:
		{
			enum datatype then_type = resolve_datatype(expr->_if.thenstmt, function);
			enum datatype else_type = then_type;
			if(expr->_if.elsestmt != NULL){
				else_type = resolve_datatype(expr->_if.elsestmt, function);
			}
			switch(then_type){
				case DOUBLE:
					switch(else_type){
						case DOUBLE: return DOUBLE;
						case INT: return DOUBLE;
						case NONE: return NONE;
						default: return INVALID_DATATYPE;
					}
				break;
				case INT:
					switch(else_type){
						case DOUBLE: return DOUBLE;
						case INT: return INT;
						case NONE: return NONE;
						default: return INVALID_DATATYPE;
					}
				break;
				case NONE:
					return NONE;
				break;
				default: return INVALID_DATATYPE;
				break;
			}
		}
		break;
		case WHILE:
			return NONE;
		break;
		default: return INVALID_DATATYPE;
	}
}
Пример #19
0
class_type make_class_signature(id_type class_id, id_type superclass_id)
{
   list_type l;
   id_type old_id;
   class_type c = (class_type) SafeMalloc(sizeof(class_struct));
   c->superclass = NULL;  /* Will be set for real below */

   c->class_id = class_id;

   /* Class name must not have appeared before */
   old_id = lookup_id(class_id);

   switch(class_id->type)
   {
   case I_MISSING:
      /* The class has been referenced in a function call, but not declared anywhere 
       * We should use the existent class # and remove the id from the missing list 
       */
      if (class_id->source != I_CLASS)
      {
	 action_error("Class %s was referenced elsewhere with different type", class_id->name);
	 break;
      }

      /* Insert directly into global table to preserve id # */
      class_id->type = I_CLASS;
      class_id->source = COMPILE;
      table_insert(st.globalvars, (void *) class_id, id_hash, id_compare);

      /* Remove from missing list */
      table_delete_item(st.missingvars, class_id, id_hash, id_compare);

      break;
      
   case I_UNDEFINED:
      /* New class name--continue normally */
      add_identifier(class_id, I_CLASS);
      break;

   case I_CLASS:
      /* We are recompiling a previously existing class.  This is rather ugly, since
       * we want to replace all the old class's data with our new data.  However, to give
       * previously compiled subclasses a chance of working with the new version, we
       * should try to match class numbers, message #s, etc. with the old class.
       *   At this point, all the old class's data have been inserted into our hash
       * tables.  The new class will be inserted into st.globalvars.  We must remove the old class 
       * from the class list.
       */

      /* If class is given twice in source files, that's an error */
      if (class_id->source == COMPILE)
	 action_error("Class %s is given twice", class_id->name);
      else 
	 /* Change the existent class id to reflect the fact that the class has now
	  * been recompiled. */
	 old_id->source = COMPILE;

      class_id->source = COMPILE;

      /* Delete self from list of existent classes.  Give warnings for subclasses. */
	 
      for (l = st.classes; l != NULL; l = l->next)
	 if (is_parent(c, (class_type) l->data))
	 {
	    if (((class_type) l->data)->class_id->idnum == c->class_id->idnum)
	       st.classes = list_delete_item(st.classes, l->data, class_compare);
	    else
	       /* Don't give warning if deleted self from list */
	    {
	       recompile_type recompile_info = 
		  (recompile_type) SafeMalloc(sizeof(recompile_struct));
	       recompile_info->class_id = ((class_type) (l->data))->class_id;
	       recompile_info->superclass = c->class_id;
	       
	       /* Only add to list if it isn't already there */
	       if (list_find_item(st.recompile_list, recompile_info->class_id, 
				  recompile_compare) == NULL)
		  st.recompile_list = list_add_item(st.recompile_list, (void *) recompile_info);
	    }
	    
	 }
      break;
      
   default:
      action_error("Duplicate identifier %s", class_id->name);
   }

   /* Delete this class from list of those that need to be recompiled */
   st.recompile_list = 
      list_delete_item(st.recompile_list, (void *) c->class_id, recompile_compare);

   c->resources  = NULL;
   c->properties = NULL;
   c->messages   = NULL;
   c->is_new = True; /* We should generate code for this class */

   /* Superclass must be defined, if one is given */
   if (superclass_id != NULL)
   {
      lookup_id(superclass_id);
      if (superclass_id->type != I_CLASS)
	 action_error("Can't find superclass %s", superclass_id->name);
      else if (class_id->idnum == superclass_id->idnum)
	 action_error("Can't subclass from self", superclass_id->name);	 
      else 
      {
	 /* Find superclass's data and store a pointer to it. */
	 for (l = st.classes; l != NULL; l = l->next)
	    if (superclass_id->idnum == ((class_type) (l->data))->class_id->idnum)
	    {
	       c->superclass = (class_type) l->data;
	       break;
	    }

	 if (c->superclass == NULL)
	    action_error("Unable to find superclass %s", superclass_id->name);
      }
      
   }
   else c->superclass = NULL;

   st.curclass = class_id->idnum;

   /* Now add superclasses' properties to our own property table, but delete
    * them from our property list.  This way the table will hold all properties 
    * that can be referenced in the class, but the property list will only 
    * hold those that were declared in this class (need to know this for code gen) */
   add_parent_properties(c, c->superclass);

   /* Similarly, add superclasses' classvars.  This must be done AFTER adding the properties,
    * since some properties in a superclass could be overriding classvars in a superclass */
   add_parent_classvars(NULL, c, c->superclass);

   /* Add to list of classes */
   st.classes = list_add_item(st.classes, (void *) c);

   return c;   
}
Пример #20
0
message_header_type make_message_header(id_type id, list_type args)
{
   message_header_type s = (message_header_type) SafeMalloc(sizeof(message_header_struct));
   id_type old_id, temp_id;
   param_type param;
   list_type l;

   /* Messsage name must be unique in this class, but may be the same
    * as a message in a different class. */
   old_id = lookup_id(id);

   switch (id->type) {
   case I_MISSING:
      /* The message has been referenced in a function call, but not declared anywhere.
       * We should use the existent message # and remove the id from the missing list 
       */
      if (id->source != I_MESSAGE)
      {
	 action_error("Message %s was referenced elsewhere with different type", id->name);
	 break;
      }

      /* Insert directly into global table to preserve id # */
      id->type = I_MESSAGE;
      id->ownernum = st.curclass;
      id->source = COMPILE;
      table_insert(st.globalvars, (void *) id, id_hash, id_compare);

      /* Remove from missing list */
      table_delete_item(st.missingvars, id, id_hash, id_compare);

      break;

   case I_UNDEFINED:   /* New message # */
      id->ownernum = st.curclass;
      add_identifier(id, I_MESSAGE);
      break;

   case I_MESSAGE:     /* Make sure message hasn't appeared in this class */
      if (id->ownernum == st.curclass && id->source == COMPILE)
	 action_error("Message handler %s defined twice in same class", id->name);
      old_id->ownernum = st.curclass;
      old_id->source = COMPILE;
      break;

   default:            /* Other types indicate name already used */
      action_error("Duplicate identifier %s", id->name);
   }

   s->message_id = id;
   /* Sort parameters in increasing id # order */
   s->params = SortParameterList(args);

   /* Add parameters as handler's local variables--this must be done AFTER sorting */
   for (l = s->params; l != NULL; l = l->next)
   {
      param = (param_type) l->data;
      
      /* Make a copy of the id for the local table */
      temp_id = duplicate_id(param->lhs);
      temp_id->type = I_LOCAL;

      if (table_insert(st.localvars, (void *) temp_id, id_hash, id_compare) == 0)
	 temp_id->idnum = ++st.maxlocals;      
   }

   st.curmessage = id->idnum;

   return s;
}