Exemple #1
0
//check parametertypes of funcall and give type of function to info_type
	node *CTfuncall(node *arg_node, info *arg_info){
		DBUG_ENTER("CTfuncall");

	//check parameter types, if there are any
		if(FUNCALL_ARGS(arg_node)!=NULL){
			node *args = FUNCALL_ARGS(arg_node);
		//check param type against expression type
			node * param = FUNDEF_PARAMS(FSYMBOL_FUNCTION(FUNCALL_DECL(arg_node)));
			EXPRS_EXPRS(args) = TRAVdo(EXPRS_EXPRS(args), arg_info);
			type exprtype = INFO_TYPE(arg_info);
			type paramtype = PARAM_TYPE(param);
			if(exprtype != paramtype){
				CTIerrorLine(NODE_LINE(arg_node), "argument type does not match function definition");
			}

		//keep checking till there are no parameters left
			while(EXPRS_NEXT(args)!=NULL){
				args = EXPRS_NEXT(args);
				param = PARAM_NEXT(param);
				EXPRS_EXPRS(args) = TRAVdo(EXPRS_EXPRS(args), arg_info);
				exprtype = INFO_TYPE(arg_info);
				paramtype = PARAM_TYPE(param);
				if(exprtype != paramtype){
					CTIerrorLine(NODE_LINE(arg_node), "argument type does not match function definition");
				}
			}
		}

	//set info_type to return type of the function
		INFO_TYPE(arg_info) = FUNDEF_TYPE(FSYMBOL_FUNCTION(FUNCALL_DECL(arg_node)));

		DBUG_RETURN(arg_node);
	}
Exemple #2
0
node *LVARglobaldef( node *arg_node, info *arg_info)
{
    char *var_name;

    DBUG_ENTER("LVARglobaldef");

    var_name = VAR_NAME(GLOBALDEF_ID( arg_node));

    /* set declaration of this global variable */
    VAR_DECL(GLOBALDEF_ID( arg_node) ) = arg_node;

    /* check for duplicated variable declaration */
    if(hashmap_contains(arg_info->global, var_name)) {
        CTIerror(":%d: error: '%s' has already been defined in this context",
                NODE_LINE(arg_node), var_name);

        CTIerror(":%d: error: location of earlier definition",
                NODE_LINE((node *)hashmap_get(arg_info->global, var_name)));
        DBUG_RETURN(arg_node);
    }

    /* add global variabele declaration to hashmap */
    hashmap_add(arg_info->global, var_name, arg_node);

    DBUG_RETURN( arg_node);
}
Exemple #3
0
//check type of monop with operand
node *CTmonop(node *arg_node, info *arg_info){
	DBUG_ENTER("CTmonop");

	//get type of operand in info_type
	MONOP_OPERAND(arg_node) = TRAVdo(MONOP_OPERAND(arg_node), arg_info);
	

	//check if type is boolean.

	if(MONOP_OP(arg_node) == MO_not && INFO_TYPE(arg_info) != T_boolean){
		CTIerrorLine(NODE_LINE(arg_node), "!(not) can only be used with a boolean operand");
	}
	else{
		MONOP_OPTYPE(arg_node) = T_boolean;
	}
	if(MONOP_OP(arg_node) == MO_neg && INFO_TYPE(arg_info) == T_boolean){
		CTIerrorLine(NODE_LINE(arg_node), "-(neg) can only be used with a boolean operand");
	}
	else if(INFO_TYPE(arg_info) == T_int){
		MONOP_OPTYPE(arg_node) = T_int;
	}
	else{
		MONOP_OPTYPE(arg_node) = T_float;
	}

	DBUG_RETURN(arg_node);
}
Exemple #4
0
	node *CTfor(node *arg_node, info *arg_info){
		DBUG_ENTER("CTfor");

		FOR_START(arg_node) = TRAVdo(FOR_START(arg_node), arg_info);
		if (INFO_TYPE(arg_info) != T_int){
			CTIerrorLine(NODE_LINE(arg_node), "Start type does not match int");
		}
		FOR_STOP(arg_node) = TRAVdo(FOR_STOP(arg_node), arg_info);
		if(INFO_TYPE(arg_info) != T_int){
			CTIerrorLine(NODE_LINE(arg_node), "Stop type does not match int");
		}
		if(FOR_STEP(arg_node) != NULL){
			FOR_STEP(arg_node) = TRAVdo(FOR_STEP(arg_node), arg_info);
			if(INFO_TYPE(arg_info) != T_int){
				CTIerrorLine(NODE_LINE(arg_node), "Step type does not match int");
			}
		}

		if(FOR_BLOCK(arg_node) != NULL){
			FOR_BLOCK(arg_node) = TRAVdo(FOR_BLOCK(arg_node), arg_info);
		} else if (FOR_BLOCKSINGLE(arg_node) != NULL){
			FOR_BLOCKSINGLE(arg_node) = TRAVdo(FOR_BLOCKSINGLE(arg_node), arg_info);
		}

		DBUG_RETURN(arg_node);

	}
Exemple #5
0
//check types of operands of binop and rewrite binop if neccessary
	node * CTbinop(node *arg_node, info *arg_info){
		DBUG_ENTER("CTbinop");
		node *leftexpr = BINOP_LEFT(arg_node);
		node *rightexpr = BINOP_RIGHT(arg_node);
		
	//compare types of operands
		BINOP_LEFT(arg_node) = TRAVdo(BINOP_LEFT(arg_node), arg_info);
		type typeleft = INFO_TYPE(arg_info);
		BINOP_RIGHT(arg_node) = TRAVdo(BINOP_RIGHT(arg_node), arg_info);
		type typeright = INFO_TYPE(arg_info);
		if(typeleft != typeright){
			CTIerrorLine(NODE_LINE(arg_node), "Types of left and right expressions of the binop do not match");
		}

	//check if the right type of operands are used with the right operators
		if((BINOP_OP(arg_node) == BO_and || BINOP_OP(arg_node) == BO_or)&&INFO_TYPE(arg_info)!=T_boolean){
			CTIerrorLine(NODE_LINE(arg_node), "The used &&(and) or ||(or) operator can only compare two booleans");
		}
		if((BINOP_OP(arg_node) == BO_lt || BINOP_OP(arg_node) == BO_le ||BINOP_OP(arg_node) == BO_gt || BINOP_OP(arg_node) == BO_ge) 
			&& INFO_TYPE(arg_info) == T_boolean){
			CTIerrorLine(NODE_LINE(arg_node), "The used operator can only compare two integers or floats");
	}
	if(BINOP_OP(arg_node) == BO_add ||BINOP_OP(arg_node) == BO_mul ||BINOP_OP(arg_node) == BO_sub ||BINOP_OP(arg_node) == BO_div ||
		BINOP_OP(arg_node) == BO_mod ){
		BINOP_OPTYPE(arg_node) = typeleft;
}

	//set info_type to boolean
if(BINOP_OP(arg_node) == BO_lt || BINOP_OP(arg_node) == BO_le ||BINOP_OP(arg_node) == BO_gt || BINOP_OP(arg_node) == BO_ge ||
	BINOP_OP(arg_node) == BO_eq || BINOP_OP(arg_node) == BO_ne || BINOP_OP(arg_node) == BO_and || BINOP_OP(arg_node) == BO_or){
	INFO_TYPE(arg_info) = T_boolean;
BINOP_OPTYPE(arg_node) = typeleft;
}
else{
	BINOP_OPTYPE(arg_node) = typeleft;
}

	//rewrite and
if(BINOP_OP(arg_node)==BO_and){

	node *then = TBmakeBool(0);
	arg_node = TBmakeConditionexpr(leftexpr, then, rightexpr);
}

  	//rewrite or
else if(BINOP_OP(arg_node) == BO_or){
	node *orthen = TBmakeBool(1);
	arg_node = TBmakeConditionexpr(leftexpr, rightexpr, orthen);
}
DBUG_RETURN(arg_node);
}
Exemple #6
0
node *TRAVdo(node *arg_node, info *arg_info)
{
  DBUG_ASSERT( (arg_node != NULL),
                 "Trav: tried to traverse into subtree NULL !");
  
  DBUG_ASSERT( (NODE_TYPE( arg_node) <= MAX_NODES),
               "Trav: illegal node type !");

  DBUG_ASSERT( (travstack != NULL),
      "no traversal on stack!");

  global.line = NODE_LINE( arg_node);

  if (pretable[ travstack->traversal] != NULL) {
    arg_node = pretable[ travstack->traversal]( arg_node, arg_info);
  }

  arg_node = (travstack->funs[ NODE_TYPE( arg_node)])( arg_node, arg_info);

  if (posttable[ travstack->traversal] != NULL) {
    arg_node = posttable[ travstack->traversal]( arg_node, arg_info);
  }

  return( arg_node);
}
Exemple #7
0
//check type assign
	node *CTassign(node *arg_node, info *arg_info){
		DBUG_ENTER("CTassign");

	//compare varlet type with assignent expression type
		ASSIGN_LET(arg_node) = TRAVdo(ASSIGN_LET(arg_node), arg_info);
		type vartype = INFO_TYPE(arg_info);
		ASSIGN_EXPR(arg_node) = TRAVdo(ASSIGN_EXPR(arg_node), arg_info);
		type exprtype = INFO_TYPE(arg_info);
		if(vartype != exprtype){
			CTIerrorLine(NODE_LINE(arg_node), "The expression type of the assign does not match the variable type");
		}

		DBUG_RETURN(arg_node);
	}
Exemple #8
0
	//check type of return of function against function type
	node *CTfundef(node *arg_node, info *arg_info){
		DBUG_ENTER("CTfundef");
		INFO_HASRETURN(arg_info) = 0;
		INFO_FUNTYPE(arg_info) = 999;

		FUNDEF_FUNBODY(arg_node) = TRAVopt(FUNDEF_FUNBODY(arg_node), arg_info);

		if(INFO_HASRETURN(arg_info) == 0){
			INFO_FUNTYPE(arg_info) = T_unknown;
		}
		if(FUNDEF_TYPE(arg_node) != INFO_FUNTYPE(arg_info) && FUNDEF_EXTERN(arg_node) == FALSE){
			CTIerrorLine(NODE_LINE(arg_node), "Return type does not match function type fun: %d ret:  %d", FUNDEF_TYPE(arg_node), INFO_TYPE(arg_info));
		}
		DBUG_RETURN(arg_node);
	}
Exemple #9
0
//check vardec type with initialisation
	node *CTvardec(node *arg_node, info *arg_info){
		DBUG_ENTER("CTvardec");

	//only check if there is a initialisation
		if(VARDEC_INIT(arg_node)!= NULL){
			VARDEC_INIT(arg_node) = TRAVdo(VARDEC_INIT(arg_node), arg_info);
			type vartype = INFO_TYPE(arg_info);
			if(vartype != VARDEC_TYPE(arg_node)){
				CTIerrorLine(NODE_LINE(arg_node), "Initialisation value does not match the type of the declared variable");
			}
		}
	//ga verder met traversal
		VARDEC_NEXT(arg_node) = TRAVopt(VARDEC_NEXT(arg_node), arg_info);

		DBUG_RETURN(arg_node);
	}
Exemple #10
0
node *TRAVdo(node *arg_node, info *arg_info)
{
  nodetype arg_node_type;
  char *old_file = global.nodefile;
  int old_line = global.nodeline;
  int old_col = global.nodecol;

  /*
   * check whether the node is non null as this
   * is a common reason for segfaults
   */
  DBUG_ASSERT( (arg_node != NULL),
               "tried to traverse a node which is NULL!");

  /*
   * Make sure the location will be set
   * correctly in case MakeXxx is called.
   */
  global.nodefile = NODE_FILE(arg_node);
  global.nodeline = NODE_LINE(arg_node);
  global.nodecol  = NODE_COL( arg_node);

  /*
   * Save node type as it might be modified during traversal
   */
  arg_node_type = NODE_TYPE( arg_node);

  if (pretable[ travstack->traversal] != NULL) {
    arg_node = pretable[ travstack->traversal]( arg_node, arg_info);
  }

  arg_node = (travstack->funs[ arg_node_type])( arg_node, arg_info);

  if (posttable[ travstack->traversal] != NULL) {
    arg_node = posttable[ travstack->traversal]( arg_node, arg_info);
  }

  global.nodefile = old_file;
  global.nodeline = old_line;
  global.nodecol  = old_col;

  return( arg_node);
}
Exemple #11
0
node *LVARvar( node *arg_node, info *arg_info)
{
    char *var_name;
    node *var_dec;

    DBUG_ENTER("LVARvar");

    var_name = VAR_NAME(arg_node);

    /* check for local variable declaration */
    var_dec = hashmap_get(arg_info->local, var_name);

    /* check for global variable declaration */
    if(!var_dec)
        var_dec = hashmap_get(arg_info->global, var_name);

    if(var_dec)
        VAR_DECL(arg_node) = var_dec;
    else
        CTIerror(":%d: error: unknown identifier '%s'", NODE_LINE(arg_node), var_name);

    DBUG_RETURN( arg_node);
}