diff --git a/src/grammar.y b/src/grammar.y index e70363d..fa52d73 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -127,15 +127,17 @@ definition: printdebug("Currently see a record definition for %s", $2); tn = CreateEntry(getAncestor(cur),TYPE_RECORD_TYPE, recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); - if (look_up(cur, $2) == undefined) { - printdebug("rec not found"); - } + printdebug("Created a new scope"); + //if (look_up(cur, $2) == undefined) { + // printdebug("rec not found"); + //} } dblock { //We are scanning through the dblock scope to get the length of the dblock (num of elements) from getRecSize //and then putting it in the entry that we created above. setRecSize(look_up(getParent(cur), $2), getRecSize(cur)); + printdebug("Moving up a scope after seeing a record definition"); cur = getParent(cur); } @@ -158,14 +160,15 @@ definition: { TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + printdebug("[TYPE CHECK] function not declared at line %d, column %d", @1.first_line, @1.first_column); } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + printdebug("[TYPE CHECK] function not declared at line %d, column %d", @1.first_line, @1.first_column); } else { setStartLine(node, @1.first_line); setAsKeyword(node, false); } cur = CreateScope(cur, 0, 0); + printdebug("Created a new scope"); } L_PAREN ID { @@ -178,7 +181,7 @@ definition: || type_of_param_type == TYPE_ALL_ELSE || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - printdebug("type of parameter is undefined or invalid at line %d, column %d", @4.first_line, @4.first_column); + printdebug("[TYPE CHECK] type of parameter is undefined or invalid at line %d, column %d", @4.first_line, @4.first_column); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases }else{ printdebug("type of parameter is %s at line %d, column %d", getName(type_of_param), @4.first_line, @4.first_column); @@ -192,9 +195,9 @@ definition: TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { - printdebug(" undefined nodedeclared at line %d, column %d", @1.first_line, @1.first_column); + printdebug(" [TYPE CHECK] undefined nodedeclared at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - printdebug("not a valid function declaration at line %d, column %d", @1.first_line, @1.first_column); + printdebug("[TYPE CHECK] not a valid function declaration at line %d, column %d", @1.first_line, @1.first_column); } else { printdebug("setting as keyword to true"); @@ -202,11 +205,12 @@ definition: setAsKeyword(node, true); } cur = CreateScope(cur, 0, 0); + printdebug("Created a new scope"); }AS L_PAREN { TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); printdebug("parameter type: %s", getType(parameter)); if (parameter == undefined) { - printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); + printdebug("[TYPE CHECK] function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(parameter) != TYPE_RECORD){ printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime)); printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); @@ -220,7 +224,7 @@ definition: || type_of_param_type == TYPE_ALL_ELSE || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - printdebug("type of parameter being passed in to AS function definition is %s which is invalid", getName(entry)); + printdebug("[TYPE CHECK] type of parameter being passed in to AS function definition is %s which is invalid", getName(entry)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases }else{ printdebug("type of parameter correctly being passed in to AS function definition is %s which is valid", getName(entry)); @@ -241,13 +245,27 @@ definition: function_declaration: FUNCTION ID COLON ID - { + { + if(getAdInfoType(look_up(cur, $4))==TYPE_FUNCTION_TYPE){ CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); } + else{ + printdebug("[TYPE CHECK] function declaration of %s is not a valid function type at line %d, column %d", $2, @1.first_line, @1.first_column); + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); + + } + } | EXTERNAL FUNCTION ID COLON ID - { - CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, NULL); + { + if(getAdInfoType(look_up(cur, $5))==TYPE_FUNCTION_TYPE){ + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false)); + } + else{ + printdebug("[TYPE CHECK] function declaration of %s is not a valid function type at line %d, column %d", $3, @1.first_line, @1.first_column); + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false)); + + } } ; @@ -290,6 +308,7 @@ sblock: { if (getLine(cur) != 0) { cur = CreateScope(cur,@1.first_line,@1.first_column); + printdebug("Created a new scope"); } else { setLineNumber(cur, @1.first_line); setColumnNumber(cur,@1.first_line); @@ -297,6 +316,7 @@ sblock: } statement_list { + printdebug("Moving up a scope after seeing sblock"); cur = getParent(cur); } R_BRACE @@ -305,9 +325,11 @@ sblock: { if (getLine(cur) != 0) { cur = CreateScope(cur,@1.first_line,@1.first_column); + printdebug("Created a new scope when seeing an L brace"); } else { setLineNumber(cur, @1.first_line); setColumnNumber(cur,@1.first_line); + printdebug("Did not create a new scope when saw L Brace, set line number to %d", @1.first_line); } } dblock @@ -316,6 +338,7 @@ sblock: } statement_list { + printdebug("Moving up a scope after seeing sblock with dblock"); cur = getParent(cur); } R_BRACE @@ -330,8 +353,10 @@ dblock: if (getLine(cur) == 0) { setLineNumber(cur, @1.first_line); setColumnNumber(cur,@1.first_line); + printdebug("Did not create a new scope when saw dblock, set line number to %d instead", @1.first_line); } else{ cur = CreateScope(cur,@1.first_line,@1.first_column); // <----- What is this? + printdebug("Created a new scope when seeing a dblock"); } } declaration_list R_BRACKET; @@ -349,7 +374,33 @@ declaration: id_or_types COLON ID { printdebug("ID/TYPE: %s, ID: %s", getName((TableNode*)$1), $3) ; - CreateEntry(cur,getAdInfoType((TableNode*)$1),(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + int d = getAdInfoType((TableNode*)$1); + if(d == TYPE_UNDEFINED) { + printdebug("undefined type at line %d and column %d", @2.first_line, @2.first_column); + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + } + else if(d == TYPE_FUNCTION_TYPE) { + printdebug("invalid (function) type passed in declaration list in dblock", @2.first_line, @2.first_column); + d = TYPE_FUNCTION_TYPE; + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + } + else if(d == TYPE_ARRAY_TYPE){ + printdebug("array variable at line %d and column %d", @2.first_line, @2.first_column); + d = TYPE_ARRAY; + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + } + else if(d == TYPE_RECORD_TYPE){ + printdebug("record variable at line %d and column %d", @2.first_line, @2.first_column); + d = TYPE_RECORD; + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + } + else if(d == TYPE_PRIMITIVE){ + printdebug("primitive variable at line %d and column %d", @2.first_line, @2.first_column); + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + }else { + printdebug("other invalid type passed at %d and column %d", @2.first_line, @2.first_column); + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + } } ; @@ -427,7 +478,7 @@ simple_statement: // Type check fails: if (!passCheck) { - printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); + printdebug("%s[TYPE CHECK] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, getType(left), getType(right), COLOR_WHITE); printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType(left)); } @@ -495,7 +546,7 @@ expression: $$=(TableNode*)$2; } else { $$=undefined; - printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,getName((TableNode*)$2)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,getName((TableNode*)$2)); } } @@ -505,7 +556,7 @@ expression: if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { $$=(TableNode*)$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -516,7 +567,7 @@ expression: if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { $$=(TableNode*)$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -527,7 +578,7 @@ expression: if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { $$=(TableNode*)$1; } else{ - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); $$=undefined; } } @@ -538,7 +589,7 @@ expression: if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && ((TableNode*)$1 == integ)) { $$=(TableNode*)$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -549,7 +600,7 @@ expression: if($1 == $3 && $1 == integ) { $$=$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -560,7 +611,7 @@ expression: if($1 == $3 && $1 == boo){ $$=$1; } else{ - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -571,7 +622,7 @@ expression: if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && $1 == boo) { $$=$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -582,7 +633,7 @@ expression: if($1 == $3 && $1==integ) { $$=boo; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -593,7 +644,7 @@ expression: if($1 == $3 && $1 != undefined) { $$=boo; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$ = undefined; } } @@ -601,7 +652,25 @@ expression: | assignable { printdebug("assignable expression. current type is %s",getName((TableNode*)$1)); - $$= getTypeEntry((TableNode*)$1); + if(getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE|| + getAdInfoType((TableNode*)$1) == TYPE_ARRAY || + getAdInfoType((TableNode*)$1) == TYPE_RECORD){ + printdebug("assignable passing up to expression is primitive, array instance, or record instance. Passing up its type"); + $$= getTypeEntry((TableNode*)$1); + } + + else if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE|| + getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE|| + getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_TYPE|| + getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + printdebug("assignable passing up to expression is array type, record type, function type, or function declaration"); + $$= ((TableNode*)$1); + } + else { + printdebug("[TYPE CHECK] assignable passing up an invalid type to expression"); + $$= ((TableNode*)$1); + } + } | L_PAREN expression R_PAREN @@ -612,7 +681,14 @@ expression: | memOp assignable { - $$ = addr; + int d = getAdInfoType((TableNode*)$2); + if(d == TYPE_ARRAY_TYPE || d == TYPE_ARRAY || d == TYPE_RECORD_TYPE || d == TYPE_RECORD) { + //printdebug("[TYPE CHECK] valid memOp expression"); + $$ = addr; + } else { + printdebug("[TYPE CHECK] invalid memOp expression at line %d and column %d.", @2.first_line,@2.first_column,getName((TableNode*)$2)); + $$=undefined; + } } ; @@ -626,7 +702,7 @@ assignable: ID { $$ = look_up(cur,$1); - printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1); + printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getName((TableNode*)$$), $1); } | assignable @@ -686,7 +762,7 @@ assignable: } } $$ = getReturn((table_lookup(getAncestor(cur), getType((TableNode*)$1)))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName($$), getName((TableNode*)$1)); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); } else if (type == TYPE_ARRAY_TYPE) { printdebug("%sEntering array call", COLOR_LIGHTGREEN); @@ -694,7 +770,7 @@ assignable: printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $2, @2.first_line, @2.first_column); } $$ = getArrType(look_up(getParent(cur), getName((TableNode*)$1))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName($$), getName((TableNode*)$1)); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); } cur = getParent(cur); } @@ -702,6 +778,7 @@ assignable: | assignable rec_op ID { if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName((TableNode*)$1))), $3)) { + $$ = table_lookup(getRecList(table_lookup(getAncestor(cur), getName((TableNode*)$1))), $3); } printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", getName((TableNode*)($$)), $1); @@ -729,7 +806,7 @@ constant: C_STRING { $$ = $1; - printdebug("string of C_STRING in constant is %s",$1); + printdebug("string of C_STRING in constant is %s",getName((TableNode*)$1)); } | C_INTEGER @@ -741,25 +818,25 @@ constant: | C_NULL { $$ = $1; - printdebug("string of C_NULL in constant is %s",$1); + printdebug("string of C_NULL in constant is %s",getName((TableNode*)$1)); } | C_CHARACTER { $$ = $1; - printdebug("string of C_CHARACTER in constant is %s",$1); + printdebug("string of C_CHARACTER in constant is %s",getName((TableNode*)$1)); } | C_TRUE { $$ = $1; - printdebug("string of C_TRUE in constant is %s",$1); + printdebug("string of C_TRUE in constant is %s",getName((TableNode*)$1)); } | C_FALSE { $$ = $1; - printdebug("string of C_FALSE in constant is %s",$1); + printdebug("string of C_FALSE in constant is %s",getName((TableNode*)$1)); } ; @@ -770,25 +847,25 @@ types: T_INTEGER { $$ = $1; - printdebug("string of T_INTEGER in types is %s",$1); + printdebug("string of T_INTEGER in types is %s",getName((TableNode*)$1)); } | T_ADDRESS { $$ = $1; - printdebug("string of T_ADDRESS in types is %s",$1); + printdebug("string of T_ADDRESS in types is %s",getName((TableNode*)$1)); } | T_CHARACTER { $$ = $1; - printdebug("string of T_CHARACTER in types is %s",$1); + printdebug("string of T_CHARACTER in types is %s",getName((TableNode*)$1)); } | T_BOOLEAN { $$ = $1; - printdebug("string of T_BOOLEAN in types is %s",$1); + printdebug("string of T_BOOLEAN in types is %s",getName((TableNode*)$1)); } ; diff --git a/src/symbol_table.c b/src/symbol_table.c index debc4d5..a4c909b 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -948,14 +948,23 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, arrayType, " Type of Array"); } } + if (getAdInfoType(entry) == TYPE_RECORD_TYPE) { + char *recordAdInfo = (char *)malloc(100); + sprintf(recordAdInfo, " elements-%d", entry->additionalinfo->RecAdInfo->numofelements); + if (parentScopeNum == 0) { + st_fprint(file_ptr, entry->theName, currentScopeNum, -100, "record type", recordAdInfo); + } else { + st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, "record type", recordAdInfo); + } + } if (getAdInfoType(entry) == TYPE_RECORD) { char *recordAdInfo = (char *)malloc(100); sprintf(recordAdInfo, " elements-%d", entry->additionalinfo->RecAdInfo->numofelements); if (parentScopeNum == 0) { - st_fprint(file_ptr, entry->theName, currentScopeNum, -100, "record", recordAdInfo); + st_fprint(file_ptr, entry->theName, currentScopeNum, -100, "record instance", recordAdInfo); } else { - st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, "record", recordAdInfo); + st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, "record instance", recordAdInfo); } }