|
|
|
@ -106,7 +106,6 @@
|
|
|
|
|
|
|
|
|
|
program:
|
|
|
|
|
prototype_or_definition_list
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -116,15 +115,14 @@ prototype_or_definition_list:
|
|
|
|
|
| definition prototype_or_definition_list
|
|
|
|
|
| prototype
|
|
|
|
|
| definition
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
| prototype error { yyerrok; }
|
|
|
|
|
| definition error { yyerrok; }
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
prototype:
|
|
|
|
|
L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -258,7 +256,11 @@ definition:
|
|
|
|
|
TableNode *expected = getReturn(getTypeEntry(look_up(cur, $1)));
|
|
|
|
|
if ($8 == undefined) {
|
|
|
|
|
throw_error(ERROR_TYPE, "Expected %s as return type but got undefined (possibly NULL). Differing return types in function.", getName(expected));
|
|
|
|
|
} else if ($8 != expected) {
|
|
|
|
|
} else if (getAdInfoType(expected)==TYPE_ARRAY_TYPE && $8 == addr){
|
|
|
|
|
printdebug("CORRECT RETURN TYPE!!!");
|
|
|
|
|
} else if (getAdInfoType(expected)==TYPE_RECORD_TYPE && $8 == addr){
|
|
|
|
|
printdebug("CORRECT RETURN TYPE!!!");
|
|
|
|
|
}else if ($8 != expected) {
|
|
|
|
|
throw_error(ERROR_TYPE, "Expected %s as return type but got %s. Differing return types in function.", getName(expected), getName($8));
|
|
|
|
|
} else {
|
|
|
|
|
printdebug("CORRECT RETURN TYPE!!!");
|
|
|
|
@ -351,8 +353,6 @@ idlist:
|
|
|
|
|
printdebug("Type of entry is %s", getType(entry));
|
|
|
|
|
printdebug("tag is %d", getAdInfoType(entry));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -401,8 +401,6 @@ sblock:
|
|
|
|
|
}
|
|
|
|
|
R_BRACE
|
|
|
|
|
{$$ = $5;}
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -423,7 +421,6 @@ dblock:
|
|
|
|
|
}
|
|
|
|
|
declaration_list R_BRACKET
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -432,8 +429,7 @@ dblock:
|
|
|
|
|
declaration_list:
|
|
|
|
|
declaration SEMI_COLON declaration_list
|
|
|
|
|
| declaration
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
| error SEMI_COLON { yyerrok; } declaration_list //only perform error recovery once we see semi-colon
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -473,8 +469,6 @@ declaration:
|
|
|
|
|
CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -492,8 +486,6 @@ id_or_types:
|
|
|
|
|
printdebug("string of type is %s in types pattern of id_or_type rule.",getName((TableNode*)$1));
|
|
|
|
|
$$ = (TableNode*)$1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -507,8 +499,16 @@ compound_statement statement_list {
|
|
|
|
|
$$ = $1;
|
|
|
|
|
} else if ($1 == $2) {
|
|
|
|
|
$$ = $1;
|
|
|
|
|
}else if((getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE) && ((TableNode*)$2)==addr){
|
|
|
|
|
$$ = $1;
|
|
|
|
|
}else if((getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE) && ((TableNode*)$2)==addr){
|
|
|
|
|
$$ = $1;
|
|
|
|
|
}else if(((TableNode*)$1)==addr && (getAdInfoType((TableNode*)$2) == TYPE_ARRAY_TYPE)){
|
|
|
|
|
$$ = $2;
|
|
|
|
|
}else if(((TableNode*)$1)==addr && (getAdInfoType((TableNode*)$2) == TYPE_RECORD_TYPE)){
|
|
|
|
|
$$ = $2;
|
|
|
|
|
} else {
|
|
|
|
|
printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column);
|
|
|
|
|
printdebug("1 differing return types within same function at line %d, column %d", @1.first_line, @1.first_column);
|
|
|
|
|
$$ = undefined;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -522,14 +522,23 @@ compound_statement statement_list {
|
|
|
|
|
$$ = $1;
|
|
|
|
|
} else if ($1 == $3) {
|
|
|
|
|
$$ = $1;
|
|
|
|
|
}else if((getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE) && ((TableNode*)$3)==addr){
|
|
|
|
|
$$ = $1;
|
|
|
|
|
}else if((getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE) && ((TableNode*)$3)==addr){
|
|
|
|
|
$$ = $1;
|
|
|
|
|
}else if(((TableNode*)$1)==addr && (getAdInfoType((TableNode*)$3) == TYPE_ARRAY_TYPE)){
|
|
|
|
|
$$ = $3;
|
|
|
|
|
}else if(((TableNode*)$1)==addr && (getAdInfoType((TableNode*)$3) == TYPE_RECORD_TYPE)){
|
|
|
|
|
$$ = $3;
|
|
|
|
|
} else {
|
|
|
|
|
printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column);
|
|
|
|
|
printdebug("2 differing return types within same function at line %d, column %d", @1.first_line, @1.first_column);
|
|
|
|
|
$$ = undefined;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
| simple_statement SEMI_COLON {
|
|
|
|
|
$$ = $1;
|
|
|
|
|
}
|
|
|
|
|
| error SEMI_COLON { yyerrok; } statement_list { $$ = $4; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -546,8 +555,18 @@ WHILE L_PAREN expression R_PAREN sblock {
|
|
|
|
|
$$ = $6;
|
|
|
|
|
} else if ($6 == $8) {
|
|
|
|
|
$$ = $6;
|
|
|
|
|
}else if((getAdInfoType((TableNode*)$6) == TYPE_ARRAY_TYPE) && ((TableNode*)$8)==addr){
|
|
|
|
|
$$ = $6;
|
|
|
|
|
}else if((getAdInfoType((TableNode*)$6) == TYPE_RECORD_TYPE) && ((TableNode*)$8)==addr){
|
|
|
|
|
$$ = $6;
|
|
|
|
|
}else if(((TableNode*)$6)==addr && (getAdInfoType((TableNode*)$8) == TYPE_ARRAY_TYPE)){
|
|
|
|
|
$$ = $8;
|
|
|
|
|
}else if(((TableNode*)$6)==addr && (getAdInfoType((TableNode*)$8) == TYPE_RECORD_TYPE)){
|
|
|
|
|
$$ = $8;
|
|
|
|
|
} else {
|
|
|
|
|
printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column);
|
|
|
|
|
printdebug("3 differing return types within same function at line %d, column %d", @1.first_line, @1.first_column);
|
|
|
|
|
printf("%s\n", getName((TableNode*)$6));
|
|
|
|
|
printf("%s\n", getName((TableNode*)$8));
|
|
|
|
|
$$ = undefined;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -564,23 +583,36 @@ simple_statement:
|
|
|
|
|
assignable ASSIGN expression
|
|
|
|
|
{ printdebug("simple statement");
|
|
|
|
|
TableNode* node;
|
|
|
|
|
if((getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION)||
|
|
|
|
|
(getAdInfoType((TableNode*)$1) == TYPE_ARRAY)||
|
|
|
|
|
(getAdInfoType((TableNode*)$1) == TYPE_RECORD)||
|
|
|
|
|
(getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE)){
|
|
|
|
|
if((getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_FUNCTION_TYPE)||
|
|
|
|
|
(getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_ARRAY_TYPE)||
|
|
|
|
|
(getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_RECORD_TYPE)||
|
|
|
|
|
(getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_PRIMITIVE_TYPE)){
|
|
|
|
|
|
|
|
|
|
node = ((TableNode*)$1);
|
|
|
|
|
} else{
|
|
|
|
|
printdebug("Invalid type passed to assignable.");
|
|
|
|
|
node = undefined;
|
|
|
|
|
}
|
|
|
|
|
node = ((TableNode*)$1);
|
|
|
|
|
} else {
|
|
|
|
|
printf("%d\n",getAdInfoType((getTypeEntry((TableNode*)$1))));
|
|
|
|
|
throw_error(ERROR_TYPE, "Invalid type passed to assignable.");
|
|
|
|
|
printf("%d, %d\n", @1.first_line, @1.first_column);
|
|
|
|
|
printf("%s\n", getType(getTypeEntry((TableNode*)$1)));
|
|
|
|
|
printf("%s\n\n", getType(getTypeEntry((TableNode*)$3)));
|
|
|
|
|
node = undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){
|
|
|
|
|
emit_assignment($1, tn_or_const(NODE, $3));
|
|
|
|
|
printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3));
|
|
|
|
|
} else {
|
|
|
|
|
throw_error(ERROR_TYPE, "%s != %s", getName(node), getName((TableNode*)$3));
|
|
|
|
|
printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$3));
|
|
|
|
|
} else if (getTypeEntry(getTypeEntry(node)) == arrayprim && getTypeEntry((TableNode*)$3) == addr) {
|
|
|
|
|
emit_assignment($1, tn_or_const(NODE, $3));
|
|
|
|
|
printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$3));
|
|
|
|
|
} else if (getTypeEntry(getTypeEntry(node)) == recprime && getTypeEntry((TableNode*)$3) == addr) {
|
|
|
|
|
emit_assignment($1, tn_or_const(NODE, $3));
|
|
|
|
|
printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$3));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
throw_error(ERROR_TYPE, "Assignable Assign Expression - Object %s of type %s != Object %s of type %s", getName(node), getType(node), getName((TableNode*)$3), getType((TableNode*)$3));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$$ = undefined;
|
|
|
|
@ -588,8 +620,8 @@ simple_statement:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| RETURN expression {$$ = getTypeEntry((TableNode*)$2);}
|
|
|
|
|
|simple_statement error {yyerrok; printdebug("error in simple statement");}
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -598,7 +630,6 @@ simple_statement:
|
|
|
|
|
rec_op:
|
|
|
|
|
DOT
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -610,7 +641,6 @@ ablock:
|
|
|
|
|
printdebug("ablock is %d", $$);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -620,18 +650,17 @@ argument_list:
|
|
|
|
|
//NEED TO EMIT PARAMETERS HERE. MAYBE USE STACK STRUCTURE
|
|
|
|
|
expression COMMA argument_list
|
|
|
|
|
{
|
|
|
|
|
CreateEntry(cur,getAdInfoType((TableNode*)$1), (TableNode*)$1, getName((TableNode*)$1), NULL);
|
|
|
|
|
CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL);
|
|
|
|
|
$$ = $3 + 1;
|
|
|
|
|
printdebug("[ARGUMENT_LIST] argument list is %d", $$);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| expression
|
|
|
|
|
{
|
|
|
|
|
CreateEntry(cur,getAdInfoType((TableNode*)$1),(TableNode*)$1, getName((TableNode*)$1), NULL);
|
|
|
|
|
CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), getName((TableNode*)$1), NULL);
|
|
|
|
|
$$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -656,7 +685,7 @@ expression:
|
|
|
|
|
$$ = node;
|
|
|
|
|
} else {
|
|
|
|
|
$$=undefined;
|
|
|
|
|
throw_error(ERROR_TYPE, "%s != %s", getName(getTypeEntry((TableNode*)$2)), getName(integ));
|
|
|
|
|
throw_error(ERROR_TYPE, "Object %s of type %s is not of type integer and can't be negated", getName((TableNode*)$2), getType((TableNode*)$2));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -672,7 +701,7 @@ expression:
|
|
|
|
|
$$ = node;
|
|
|
|
|
} else {
|
|
|
|
|
$$=undefined;
|
|
|
|
|
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$2), getName(boo));
|
|
|
|
|
throw_error(ERROR_TYPE, "Object %s of type %s is not of type Boolean and can't be negated", getName((TableNode*)$2), getType((TableNode*)$2));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -687,6 +716,7 @@ expression:
|
|
|
|
|
} else {
|
|
|
|
|
$$=undefined;
|
|
|
|
|
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
|
|
|
|
|
throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -701,7 +731,7 @@ expression:
|
|
|
|
|
$$ = node;
|
|
|
|
|
} else {
|
|
|
|
|
$$=undefined;
|
|
|
|
|
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
|
|
|
|
|
throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -715,7 +745,7 @@ expression:
|
|
|
|
|
$$ = node;
|
|
|
|
|
} else {
|
|
|
|
|
$$=undefined;
|
|
|
|
|
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
|
|
|
|
|
throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -729,7 +759,7 @@ expression:
|
|
|
|
|
$$ = node;
|
|
|
|
|
} else {
|
|
|
|
|
$$=undefined;
|
|
|
|
|
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
|
|
|
|
|
throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -743,7 +773,7 @@ expression:
|
|
|
|
|
$$ = node;
|
|
|
|
|
} else {
|
|
|
|
|
$$=undefined;
|
|
|
|
|
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
|
|
|
|
|
throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -757,7 +787,7 @@ expression:
|
|
|
|
|
$$ = node;
|
|
|
|
|
} else {
|
|
|
|
|
$$=undefined;
|
|
|
|
|
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
|
|
|
|
|
throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be Boolean", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -771,7 +801,7 @@ expression:
|
|
|
|
|
$$ = node;
|
|
|
|
|
} else {
|
|
|
|
|
$$=undefined;
|
|
|
|
|
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
|
|
|
|
|
throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be Boolean", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -785,7 +815,7 @@ expression:
|
|
|
|
|
$$ = node;
|
|
|
|
|
} else {
|
|
|
|
|
$$=undefined;
|
|
|
|
|
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
|
|
|
|
|
throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -800,7 +830,7 @@ expression:
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
$$ = undefined;
|
|
|
|
|
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
|
|
|
|
|
throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be the same type", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -824,12 +854,10 @@ expression:
|
|
|
|
|
//NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK)
|
|
|
|
|
$$ = node;
|
|
|
|
|
} else {
|
|
|
|
|
throw_error(ERROR_TYPE, "Invalid memOp expression (%s).", getName((TableNode*)$2));
|
|
|
|
|
throw_error(ERROR_TYPE, "Invalid memOp expression with object %s of type %s.", getName((TableNode*)$2), getType((TableNode*)$2));
|
|
|
|
|
$$=undefined;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -852,6 +880,8 @@ assignable:
|
|
|
|
|
| assignable
|
|
|
|
|
{
|
|
|
|
|
printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN);
|
|
|
|
|
//Creating a dummy scope where we create entries for all the arguments of a function call
|
|
|
|
|
//Must also consider that we might be in an array access
|
|
|
|
|
cur = CreateScope(cur, -1,-1);
|
|
|
|
|
}
|
|
|
|
|
//we have to consider emmissions in ablocks
|
|
|
|
@ -864,65 +894,55 @@ assignable:
|
|
|
|
|
|
|
|
|
|
if (type == TYPE_FUNCTION_TYPE) {
|
|
|
|
|
printdebug("%sEntering function call", COLOR_LIGHTGREEN);
|
|
|
|
|
if (look_up(getParent(cur), getType((TableNode*)$1))->additionalinfo->FunDecAdInfo->regularoras) {
|
|
|
|
|
printdebug("as function");
|
|
|
|
|
//char *funtype = getType(look_up(cur, $1));
|
|
|
|
|
//printdebug("%s", getType(look_up(cur, getName((TableNode*)$1))));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TableNode * typeNode = getTypeEntry((TableNode*)$1);
|
|
|
|
|
TableNode *param = getParameter(typeNode);
|
|
|
|
|
printTableNode(param);
|
|
|
|
|
|
|
|
|
|
if (getAdInfoType(param) == TYPE_RECORD_TYPE) {
|
|
|
|
|
SymbolTable *recList = getRecList(param);
|
|
|
|
|
TableNode *lastCheckedRef = getFirstEntry(recList);
|
|
|
|
|
TableNode *lastCheckedAct = getFirstEntry(cur);
|
|
|
|
|
while (getNextEntry(lastCheckedRef) != NULL) {
|
|
|
|
|
lastCheckedRef = getNextEntry(lastCheckedRef);
|
|
|
|
|
//getting the parameter. The type of assignable is a function type so we need to access the paramater of the type
|
|
|
|
|
TableNode *expected = getParameter(getTypeEntry((TableNode*)$1));
|
|
|
|
|
//Jump into case where the parameter is a record type
|
|
|
|
|
if(getAdInfoType(expected) == TYPE_RECORD_TYPE){
|
|
|
|
|
//int argument_size = getRecSize(cur);
|
|
|
|
|
int parameter_size = getRecSize(getRecList(expected));
|
|
|
|
|
printdebug("argument size is %d\n", $3);
|
|
|
|
|
printdebug("parameter size is %d\n", parameter_size);
|
|
|
|
|
if ($3 != parameter_size) {
|
|
|
|
|
throw_error(ERROR_SYNTAX, "expected %d arguments for this function but got %d", parameter_size, $3);
|
|
|
|
|
}else{
|
|
|
|
|
TableNode* param_arg_type = getFirstEntry(getRecList(expected));
|
|
|
|
|
TableNode* arg_given = getFirstEntry(cur);
|
|
|
|
|
while(arg_given != NULL && getName(arg_given)[0]!='&'){
|
|
|
|
|
arg_given = getNextEntry(arg_given);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($3 != getRecLength(param)) {
|
|
|
|
|
printdebug("expected %d arguments but got %d", getRecLength(param), $3);
|
|
|
|
|
if(getTypeEntry(arg_given) != param_arg_type){
|
|
|
|
|
throw_error(ERROR_TYPE, "expected %s expression as first argument in function call but got %s", getName(param_arg_type), getType(arg_given));
|
|
|
|
|
}
|
|
|
|
|
//this isn't very efficient, but will hopefully work
|
|
|
|
|
while (lastCheckedAct != NULL && lastCheckedRef != NULL) {
|
|
|
|
|
if (getTypeEntry(lastCheckedRef) != getTypeEntry(lastCheckedAct)) {
|
|
|
|
|
printdebug("expected %s. expression in function call got %s. at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column);
|
|
|
|
|
|
|
|
|
|
param_arg_type = getNextEntry(param_arg_type);
|
|
|
|
|
arg_given = getNextEntry(arg_given);
|
|
|
|
|
while(arg_given != NULL && param_arg_type != NULL){
|
|
|
|
|
while(arg_given != NULL && getName(arg_given)[0]=='&'){
|
|
|
|
|
arg_given = getNextEntry(arg_given);
|
|
|
|
|
}
|
|
|
|
|
lastCheckedAct = getNextEntry(lastCheckedAct);
|
|
|
|
|
TableNode *tn = getFirstEntry(recList);
|
|
|
|
|
|
|
|
|
|
if (tn != lastCheckedRef) {
|
|
|
|
|
while (getNextEntry(tn) != lastCheckedRef) {
|
|
|
|
|
tn = getNextEntry(tn);
|
|
|
|
|
}
|
|
|
|
|
lastCheckedRef = tn;
|
|
|
|
|
} else {break;}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (strcmp(getName(param), getName(getFirstEntry(cur))) != 0) {
|
|
|
|
|
printdebug("expected %s expression in function call but got %s", getName(param), getName(getFirstEntry(cur)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (getNextEntry(getFirstEntry(cur)) != NULL) {
|
|
|
|
|
printdebug("expected 1 parameter, but got multiple in function call");
|
|
|
|
|
if(getTypeEntry(arg_given) != param_arg_type){
|
|
|
|
|
throw_error(ERROR_TYPE, "expected %s expression as argument in function call but got %s", getName(param_arg_type), getType(arg_given));
|
|
|
|
|
}
|
|
|
|
|
arg_given = getNextEntry(arg_given);
|
|
|
|
|
param_arg_type = getNextEntry(param_arg_type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
char *expected = getName(getParameter(look_up(getParent(cur), getType((TableNode*)$1))));
|
|
|
|
|
char *actual = getType(getFirstEntry(cur));
|
|
|
|
|
if (strcmp(expected, actual) != 0) {
|
|
|
|
|
printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column);
|
|
|
|
|
}
|
|
|
|
|
if ($3 != 1) {
|
|
|
|
|
printdebug("expected 1 argument but got %d", $3);
|
|
|
|
|
}else{
|
|
|
|
|
TableNode*actual_instance = getFirstEntry(cur);
|
|
|
|
|
while(actual_instance != NULL && getName(actual_instance)[0] =='&'){
|
|
|
|
|
actual_instance = getNextEntry(actual_instance);
|
|
|
|
|
}
|
|
|
|
|
if(actual_instance == NULL){
|
|
|
|
|
throw_error(ERROR_TYPE, "Invalid function call. No arguments passed");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
TableNode *actual = getTypeEntry(actual_instance);
|
|
|
|
|
if (expected != actual) {
|
|
|
|
|
throw_error(ERROR_TYPE, "expected %s expression in function call but got %s", getName(expected), getName(actual));
|
|
|
|
|
}
|
|
|
|
|
if ($3 != 1) {
|
|
|
|
|
throw_error(ERROR_SYNTAX, "expected 1 argument but got %d", $3); }
|
|
|
|
|
printTableNode(getReturn(getTypeEntry((TableNode*)$1)));
|
|
|
|
|
//
|
|
|
|
|
}
|
|
|
|
|
char* temp = temp_var_gen();
|
|
|
|
|
TableNode* typeNode2 = getReturn(getTypeEntry($1));
|
|
|
|
|
int t = -1;
|
|
|
|
@ -935,21 +955,21 @@ assignable:
|
|
|
|
|
else if(getAdInfoType(typeNode2) == TYPE_RECORD_TYPE){
|
|
|
|
|
t = TYPE_RECORD;
|
|
|
|
|
}
|
|
|
|
|
//this may need to be updated to provide the correct name of things
|
|
|
|
|
else if(getAdInfoType(typeNode2) == TYPE_FUNCTION_TYPE){
|
|
|
|
|
t = TYPE_FUNCTION_DECLARATION;
|
|
|
|
|
}else{
|
|
|
|
|
t= TYPE_UNDEFINED;
|
|
|
|
|
printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper.");
|
|
|
|
|
throw_error(ERROR_TYPE, "Undefined type returned by function.");
|
|
|
|
|
}
|
|
|
|
|
TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL);
|
|
|
|
|
$$ = node;
|
|
|
|
|
//NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK for function call)
|
|
|
|
|
printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName(typeNode2), getName((TableNode*)$1));
|
|
|
|
|
|
|
|
|
|
} else if (type == TYPE_ARRAY_TYPE) {
|
|
|
|
|
printdebug("%sEntering array call", COLOR_LIGHTGREEN);
|
|
|
|
|
if (getNumArrDim(look_up(getParent(cur), getType((TableNode*)$1))) != $<integ>2) {
|
|
|
|
|
printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $<integ>2, @2.first_line, @2.first_column);
|
|
|
|
|
throw_error(ERROR_SYNTAX, "expected %d arguments for this array but got %d", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $<integ>2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char* temp = temp_var_gen();
|
|
|
|
@ -968,7 +988,7 @@ assignable:
|
|
|
|
|
t = TYPE_FUNCTION_DECLARATION;
|
|
|
|
|
}else{
|
|
|
|
|
t= TYPE_UNDEFINED;
|
|
|
|
|
printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper.");
|
|
|
|
|
throw_error(ERROR_TYPE, "Undefined type stored in array.");
|
|
|
|
|
}
|
|
|
|
|
TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL);
|
|
|
|
|
//emit assign here
|
|
|
|
@ -981,12 +1001,12 @@ assignable:
|
|
|
|
|
|
|
|
|
|
| assignable rec_op ID
|
|
|
|
|
{
|
|
|
|
|
if(getAdInfoType((TableNode*)$1) != TYPE_RECORD_TYPE){
|
|
|
|
|
printdebug("CHANGE ME [TYPE CHECK]Invalid type passed to record access");
|
|
|
|
|
if(getAdInfoType((TableNode*)$1) != TYPE_RECORD){
|
|
|
|
|
throw_error(ERROR_TYPE, "Invalid type passed to record access");
|
|
|
|
|
}
|
|
|
|
|
else if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3)) {
|
|
|
|
|
|
|
|
|
|
TableNode* type = table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3);
|
|
|
|
|
TableNode* type = getTypeEntry(table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3));
|
|
|
|
|
char* temp = temp_var_gen();
|
|
|
|
|
int t = -1;
|
|
|
|
|
if(getAdInfoType(type) == TYPE_PRIMITIVE_TYPE){
|
|
|
|
@ -1002,7 +1022,7 @@ assignable:
|
|
|
|
|
t = TYPE_FUNCTION_DECLARATION;
|
|
|
|
|
}else{
|
|
|
|
|
t= TYPE_UNDEFINED;
|
|
|
|
|
printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper.");
|
|
|
|
|
throw_error(ERROR_TYPE, "Undefined type stored in record.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TableNode* node = CreateEntry(cur,t, type, temp, NULL);
|
|
|
|
@ -1010,13 +1030,12 @@ assignable:
|
|
|
|
|
//emit_field_access(char* node, char* record, $3)
|
|
|
|
|
$$=node;
|
|
|
|
|
}else{
|
|
|
|
|
printdebug("CHANGE ME [TYPE CHECK] undefined type (Field Access Lookup failed)");
|
|
|
|
|
throw_error(ERROR_TYPE, "Invalid field access %s", $3);
|
|
|
|
|
$$=undefined;
|
|
|
|
|
}
|
|
|
|
|
printdebug("[ASSIGNABLE - RULE 3] record = name: %s | field = %s", getName((TableNode*)($1)), getName((TableNode*)$3));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -1033,7 +1052,6 @@ memOp:
|
|
|
|
|
printdebug("release expression");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| error { yyerrok; }
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
@ -1186,7 +1204,7 @@ void throw_error(ErrorType error_type, const char *format, ...) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
snprintf(total_error_message, total_needed, "%s%s\n\n", error_message, error_message2);
|
|
|
|
|
snprintf(total_error_message, total_needed, "%s%s\n", error_message, error_message2);
|
|
|
|
|
if (tc_flag) {
|
|
|
|
|
insert_code_line(total_error_message, line);
|
|
|
|
|
} else {
|
|
|
|
@ -1208,9 +1226,9 @@ void yyerror(const char *err) {
|
|
|
|
|
// Grammar Fallback Case
|
|
|
|
|
if (strcmp(err, "syntax error") == 0) {
|
|
|
|
|
if (asc_flag != NULL) {
|
|
|
|
|
int needed = snprintf(NULL, 0, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n\n", line, column, yytext);
|
|
|
|
|
int needed = snprintf(NULL, 0, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n", line, column, yytext);
|
|
|
|
|
char *error_message = malloc(needed + 1);
|
|
|
|
|
snprintf(error_message, needed + 1, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n\n", line, column, yytext);
|
|
|
|
|
snprintf(error_message, needed + 1, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n", line, column, yytext);
|
|
|
|
|
insert_code_line(error_message, line);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
@ -1218,3 +1236,4 @@ void yyerror(const char *err) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|