diff --git a/Makefile b/Makefile index 6fefed1..6a8e88d 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ FLEX := flex BISON = bison CFLAGS := -ggdb -BISONFLAGS := -d +BISONFLAGS := -d -Wcounterexamples LEX := src/lexicalStructure.lex YACC := src/grammar.y diff --git a/src/codegen.c b/src/codegen.c index 250d2a4..8e63df4 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -493,7 +493,6 @@ int generateAssign(Instruction *inst) { CGNode *op1CG = findCG(getTN(op1)); if (op1CG == NULL) { - printf("failed here\n"); printdebug("generateAssign failed, op1 is not constant but not in CGlist"); return -1; } diff --git a/src/grammar.y b/src/grammar.y index 7060c94..d2c4d8e 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -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))) != $2) { - 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); + throw_error(ERROR_SYNTAX, "expected %d arguments for this array but got %d", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $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) { } } } + diff --git a/src/runner.c b/src/runner.c index a74c424..8d5feac 100644 --- a/src/runner.c +++ b/src/runner.c @@ -247,7 +247,7 @@ int is_alpha_file(char *alpha, int file_len) { return 0; // is alpha file } -void insert_code_line(char * error_message, int line_number) { +void insert_code_line(char *error_message, int line_number) { CodeLine *error_line = malloc(sizeof(CodeLine)); error_line->line_number = line_number; error_line->line = malloc(strlen(error_message) + 1); @@ -259,11 +259,14 @@ void insert_code_line(char * error_message, int line_number) { int line = error_line->line_number; CodeLine *current = code_head; + while (current != NULL) { if (current->line_number == line) { - CodeLine *next_code_line = current->next; - current->next = error_line; - error_line->next = next_code_line; + if (current->is_error == false) { + CodeLine *next_code_line = current->next; + current->next = error_line; + error_line->next = next_code_line; + } } current = current->next; } diff --git a/src/symbol_table.c b/src/symbol_table.c index 37fc205..cf6edd4 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -5,6 +5,7 @@ Constant_Stack *head = NULL; int temp2_count = 0; +int temp3_count = 0; void printdebug_impl(char *file, int line, const char *format, ...) { if (DEBUG) { @@ -24,6 +25,12 @@ char *temp_var_gen() { temp2_count++; return ret; } +char *arg_var_gen() { + char *ret = calloc(9, sizeof(*ret)); + sprintf(ret, "&t%d", temp3_count); + temp3_count++; + return ret; +} Constant_Stack *Push(TableNode *type, void *value, bool isConst) { if (type == NULL || type == undefined) { diff --git a/src/symbol_table.h b/src/symbol_table.h index 391f05a..c64f036 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -101,6 +101,7 @@ void printdebug_impl(char *file, int line, const char *format, ...); printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) char *temp_var_gen(); +char *arg_var_gen(); Constant_Stack *Push(TableNode *type, void *value, bool isConst); Constant_Stack *Pop(); Constant_Stack *Print_Stack(); @@ -165,6 +166,7 @@ extern int column_number; extern FILE *yyin; extern bool DEBUG; extern int temp2_count; +extern int temp3_count; extern TableNode *funprime; extern TableNode *arrayprim; extern TableNode *integ; diff --git a/tests/carl/NoErrors/functionValue.alpha b/tests/carl/NoErrors/functionValue.alpha index f521a42..8ad0e6c 100644 --- a/tests/carl/NoErrors/functionValue.alpha +++ b/tests/carl/NoErrors/functionValue.alpha @@ -56,11 +56,11 @@ c(x) := { entry is the first function called *) entry(arg) := { - [integer: result; string2int: f; integer: temp] + [integer: result; string2int: f; integer: temp; character: char] temp := a("Hello"); f := b(temp); result := c(f); - if (d(1,2,'c')) + if (d(1,2,char)) then { result := 0; }