From cd4393d0526cecc70d39267be7b76838049f4a01 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Wed, 30 Apr 2025 08:20:11 -0400 Subject: [PATCH 01/12] I added some packpatching --- src/grammar.h | 4 +- src/grammar.y | 205 +++++++++++++----------- src/intermediate_code.c | 19 ++- src/intermediate_code.h | 9 +- src/runner.c | 7 +- tests/carl/NoErrors/selectionSort.alpha | 4 +- 6 files changed, 138 insertions(+), 110 deletions(-) diff --git a/src/grammar.h b/src/grammar.h index 055d1b4..968bee5 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -31,4 +31,6 @@ int offset; int currentsp; CGNode *cgList; -extern Stack* stack; \ No newline at end of file +extern Stack* s; +Stack* TrueList; +Stack* FalseList; diff --git a/src/grammar.y b/src/grammar.y index e4e2162..ba9e96a 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -122,7 +122,7 @@ prototype_or_definition_list: prototype: L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID - + ; @@ -149,21 +149,21 @@ definition: cur = getParent(cur); } - | TYPE ID COLON C_INTEGER ARROW id_or_types + | TYPE ID COLON C_INTEGER ARROW id_or_types { - printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, getName((TableNode*)$6), $4); + printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, getName((TableNode*)$6), $4); CreateEntry(cur,TYPE_ARRAY_TYPE, arrayprim, $2, CreateArrayInfo($4, (TableNode*)$6)); printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, getName((TableNode*)$6)); } - + | function_declaration - + | TYPE ID COLON id_or_types ARROW id_or_types { printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", $2, getName((TableNode*)$4), getName((TableNode*)$6)); CreateEntry(cur,TYPE_FUNCTION_TYPE,funtypeprime,$2,CreateFunctionTypeInfo((TableNode*)$4 ,(TableNode*)$6)); - } - + } + | ID { emit_function_start(table_lookup(cur,$1)); //printf("ID: %s\n", $1); @@ -174,11 +174,11 @@ definition: printdebug("Undefined node declared."); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ throw_error(ERROR_SYNTAX, "Not a valid function declaration."); - } + } else { printdebug("setting as keyword to true"); setStartLine(node, @1.first_line); - setAsKeyword(node, true); + setAsKeyword(node, true); } cur = CreateScope(cur, 0, 0); printdebug("Created a new scope"); @@ -194,10 +194,10 @@ definition: || type_of_param_type == TYPE_FUNCTION_DECLARATION || type_of_param_type == TYPE_ARRAY || type_of_param_type == TYPE_PRIMITIVE - || type_of_param_type == TYPE_ALL_ELSE + || type_of_param_type == TYPE_ALL_ELSE || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_RECORD - || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused + || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused throw_error(ERROR_TYPE, "Invalid type (%s) of parameter in function definition.", getAdInfo(parameter)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases } @@ -222,10 +222,10 @@ definition: || type_of_param_type == TYPE_FUNCTION_TYPE || type_of_param_type == TYPE_ARRAY_TYPE || type_of_param_type == TYPE_PRIMITIVE_TYPE - || type_of_param_type == TYPE_ALL_ELSE + || type_of_param_type == TYPE_ALL_ELSE || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_RECORD_TYPE - || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused + || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused throw_error(ERROR_TYPE, "Invalid type (%s) of parameter in function definition.", getAdInfo(entry)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases }else{ @@ -246,7 +246,7 @@ definition: if(type_of_param_type == TYPE_PRIMITIVE){ printdebug("primitive type of parameter inside record"); CreateEntry(cur, TYPE_PRIMITIVE, getTypeEntry(entry),NULL, getAdInfo(entry)); - } + } /*printdebug("creating entry of type %s for function", getType(entry)); CreateEntry(cur, getTypeEntry(entry), "undefined", NULL);*/ } @@ -270,13 +270,13 @@ definition: } //printf("Ending ID: %s\n", $1); //printf("Ending Type: %s\n", getType(table_lookup(getAncestor(cur), $1))); - } +} idlist R_PAREN ASSIGN sblock ; function_declaration: FUNCTION ID COLON ID - { + { if(getAdInfoType(table_lookup(cur, $4))==TYPE_FUNCTION_TYPE){ //printf("%s\n",$2); //printf("%s\n",getName(table_lookup(cur, $4))); @@ -290,7 +290,7 @@ function_declaration: } | EXTERNAL FUNCTION ID COLON ID - { + { if(getAdInfoType(look_up(cur, $5))==TYPE_FUNCTION_TYPE){ CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false)); } @@ -338,7 +338,7 @@ idlist: { $$ = $4 + 1; } - + | ID { printdebug("idlist rule 2 ID: %s", $1); TableNode *entry = getFirstEntry(cur); @@ -360,7 +360,7 @@ idlist: printdebug("Type of entry is %s", getType(entry)); printdebug("tag is %d", getAdInfoType(entry)); } - + ; @@ -383,7 +383,7 @@ sblock: } R_BRACE {$$ = $3;} - + | L_BRACE { if (getLine(cur) != 0) { @@ -404,79 +404,79 @@ sblock: printdebug("Moving up a scope after seeing sblock with dblock"); cur = getParent(cur); //$$ = $5; - - } + + } R_BRACE {$$ = $5;} - + ; dblock: - L_BRACKET + L_BRACKET { if (getLine(cur) == 0) { - setLineNumber(cur, @1.first_line); + 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 - + ; declaration_list: - declaration SEMI_COLON declaration_list - | declaration + declaration SEMI_COLON declaration_list + | declaration | error SEMI_COLON { yyerrok; } declaration_list //only perform error recovery once we see semi-colon - + ; declaration: - id_or_types COLON ID + id_or_types COLON ID { printdebug("ID/TYPE: %s, ID: %s", getName((TableNode*)$1), $3) ; int d = getAdInfoType((TableNode*)$1); if(d == TYPE_UNDEFINED) { throw_error(ERROR_TYPE, "Undefined type passed in declaration list"); printdebug("Undefined type passed in declaration list"); - CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + 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_DECLARATION; - CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + 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)); + 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)); + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } else if(d == TYPE_PRIMITIVE_TYPE){ printdebug("primitive variable at line %d and column %d", @2.first_line, @2.first_column); d = TYPE_PRIMITIVE; - CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); }else { throw_error(ERROR_TYPE, "%s is being defined with an undefined type", $3); - CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } } - + ; @@ -487,13 +487,13 @@ id_or_types: printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = table_lookup(getAncestor(cur), $1); } - + | types { printdebug("string of type is %s in types pattern of id_or_type rule.",getName((TableNode*)$1)); $$ = (TableNode*)$1; } - + ; @@ -521,7 +521,7 @@ compound_statement statement_list { } | compound_statement { $$ = $1; - } + } | simple_statement SEMI_COLON statement_list{ if ($1 == undefined && $3 != undefined) { $$ = $3; @@ -552,24 +552,37 @@ compound_statement statement_list { compound_statement: -WHILE L_PAREN expression R_PAREN sblock { - $$ = $5; + WHILE L_PAREN +{ + if (!TrueList) {TrueList = S_Init();} + if (!FalseList) {FalseList = S_Init();} + S_Push(TrueList, S_Init()); + S_Push(FalseList, S_Init()); +} expression R_PAREN { + emit_label(label_gen()); + backpatch(S_Pop(TrueList), getLabel(current)); +} sblock { + $$ = $7; + emit_label(label_gen()); + backpatch(S_Pop(FalseList), getLabel(current)); } - | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock { - if ($6 == undefined && $8 != undefined) { - $$ = $8; - } else if ($6 != undefined && $8 == undefined) { - $$ = $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; + | IF L_PAREN expression R_PAREN THEN {emit_label(label_gen());} sblock ELSE {emit_label(label_gen());} sblock { +/* +*/ + if ($7 == undefined && $10 != undefined) { + $$ = $10; + } else if ($7 != undefined && $10 == undefined) { + $$ = $7; + } else if ($7 == $10) { + $$ = $7; + }else if((getAdInfoType((TableNode*)$7) == TYPE_ARRAY_TYPE) && ((TableNode*)$10)==addr){ + $$ = $7; + }else if((getAdInfoType((TableNode*)$7) == TYPE_RECORD_TYPE) && ((TableNode*)$10)==addr){ + $$ = $7; + }else if(((TableNode*)$7)==addr && (getAdInfoType((TableNode*)$10) == TYPE_ARRAY_TYPE)){ + $$ = $10; + }else if(((TableNode*)$7)==addr && (getAdInfoType((TableNode*)$10) == TYPE_RECORD_TYPE)){ + $$ = $10; } else { 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)); @@ -577,7 +590,7 @@ WHILE L_PAREN expression R_PAREN sblock { $$ = undefined; } } - + | sblock { $$ = $1; } @@ -587,14 +600,14 @@ WHILE L_PAREN expression R_PAREN sblock { simple_statement: - assignable ASSIGN expression - { printdebug("simple statement"); + assignable ASSIGN expression + { printdebug("simple statement"); TableNode* node; 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 { //printf("%d\n",getAdInfoType((getTypeEntry((TableNode*)$1)))); @@ -616,8 +629,8 @@ simple_statement: 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)); } @@ -631,7 +644,7 @@ simple_statement: emit_return(tn_or_const(NODE,(TableNode*)$2));} |simple_statement error {yyerrok; printdebug("error in simple statement");} - + ; @@ -639,7 +652,7 @@ simple_statement: rec_op: DOT - + ; @@ -650,7 +663,7 @@ ablock: printdebug("ablock is %d", $$); } - + ; @@ -659,6 +672,7 @@ argument_list: //NEED TO EMIT PARAMETERS HERE. MAYBE USE STACK STRUCTURE expression{ TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); + // this emits params for function and arrays TODO: fix emit_parameter(tn_or_const(NODE,arg)); //S_Push(stack,current); //emit_detach(); @@ -679,7 +693,7 @@ argument_list: } - + ; @@ -822,14 +836,15 @@ expression: 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)); } } - - | expression LESS_THAN expression + + | expression LESS_THAN expression { + emit_conditional_jump(E_LESS_THAN, 0, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); + S_Push(S_Peek(TrueList), current); printdebug("less than expression"); if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - emit_binary_op(E_LESS_THAN,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -843,9 +858,9 @@ expression: if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1) != undefined) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - emit_binary_op(E_EQUAL_TO,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); + emit_conditional_jump(E_EQUAL_TO, 0, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); $$ = node; - + } else { $$ = undefined; 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)); @@ -856,7 +871,7 @@ expression: { $$ = $1; } - + | L_PAREN expression R_PAREN { printdebug("paren expression. current type is %s",getType((TableNode*)$2)); @@ -864,7 +879,7 @@ expression: } | RESERVE assignable - { + { int d = getAdInfoType((TableNode*)$2); if(d == TYPE_ARRAY ||d == TYPE_RECORD) { char* temp = temp_var_gen(); @@ -889,7 +904,7 @@ expression: $$=undefined; } } - + ; //UPDATED $$ for tablenodes to this point @@ -898,17 +913,17 @@ expression: // add array case // include type check for ablock in arrays - ablock is always the int of the elements in array/rec assignable: - ID + ID { TableNode* pass = look_up(cur,$1); if(pass == undefined){ throw_error(ERROR_TYPE, "Undefined variable %s", $1); } - $$ = pass; + $$ = pass; printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getType(pass), getName(pass)); } - | 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 @@ -916,13 +931,13 @@ assignable: cur = CreateScope(cur, -1,-1); } //we have to consider emmissions in ablocks - ablock + ablock { //int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); int type = getAdInfoType(getTypeEntry((TableNode*)$1)); printdebug("%stype is %d", COLOR_PURPLE, type); printdebug("%s", getName((TableNode*)$1)); - + if (type == TYPE_FUNCTION_TYPE) { printdebug("%sEntering function call", COLOR_LIGHTGREEN); //getting the parameter. The type of assignable is a function type so we need to access the paramater of the type @@ -1046,8 +1061,8 @@ assignable: } | assignable rec_op ID - { - + { + if(getAdInfoType((TableNode*)$1) != TYPE_RECORD){ throw_error(ERROR_TYPE, "Invalid type passed to record access"); $$ = undefined; @@ -1075,16 +1090,16 @@ assignable: TableNode* node = CreateEntry(cur,t, type, temp, NULL); //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //emit_field_access(char* node, char* record, $3) + //emit_field_access(char* node, char* record, $3) $$=node; }else{ 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)); } - + ; @@ -1106,7 +1121,7 @@ constant: printdebug("number of C_INTEGER in constant is %d", $1); $$ = node; } - + | C_NULL { char* temp = temp_var_gen(); @@ -1115,7 +1130,7 @@ constant: printdebug("string of C_NULL in constant is NULL"); $$ = node; } - + | C_CHARACTER { char* temp = temp_var_gen(); @@ -1124,7 +1139,7 @@ constant: printdebug("string of C_CHARACTER in constant is %s",$1); $$ = node; } - + | C_TRUE { char* temp = temp_var_gen(); @@ -1134,7 +1149,7 @@ constant: printdebug("string of C_TRUE in constant is true"); $$ = node; } - + | C_FALSE { char* temp = temp_var_gen(); @@ -1149,25 +1164,25 @@ constant: -types: +types: T_INTEGER { $$ = $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",getName((TableNode*)$1)); } - + | T_CHARACTER { $$ = $1; printdebug("string of T_CHARACTER in types is %s",getName((TableNode*)$1)); } - + | T_BOOLEAN { $$ = $1; @@ -1254,7 +1269,7 @@ void throw_error(ErrorType error_type, const char *format, ...) { void yyerror(const char *err) { int line = yylloc.first_line; int column = yylloc.first_column; - + // Grammar Fallback Case if (strcmp(err, "syntax error") == 0) { if (asc_flag != NULL) { diff --git a/src/intermediate_code.c b/src/intermediate_code.c index aee5862..fc35a1e 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -69,6 +69,13 @@ void emit_detach(){ current->next = NULL; } +void backpatch(Stack *s, int l){ + while (!S_IsEmpty(s)){ + Instruction * i = S_Pop(s); + set_label(i, l); + } +} + TNodeOrConst * getOperand1(Instruction * i){ return i->operand1; } @@ -480,21 +487,21 @@ void emit_as_file(FILE * out_file, Instruction * i){ case E_LESS_THAN: // this feels wrong I need to TODO: this fprintf(out_file, - "%4.d: %s = %s < %s\n", + "%4.d: if ( %s < %s ) GOTO %d\n", i->index, - getName(i->result), get_string(i->operand1), - get_string(i->operand2) + get_string(i->operand2), + i->label ); break; case E_EQUAL_TO: // this feels wrong I need to TODO: this fprintf(out_file, - "%4.d: %s = %s == %s\n", + "%4.d: if ( %s = %s ) GOTO %d\n", i->index, - getName(i->result), get_string(i->operand1), - get_string(i->operand2) + get_string(i->operand2), + i->label ); break; case E_CALL: diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 60b64a0..6a5a9a0 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -108,13 +108,13 @@ typedef struct TFList { TFList * next; } TFList; -TFList * make_list(Instruction * i); +// TFList * make_list(Instruction * i); // - makelist(i) function to create instruction lists -void merge(TFList * l1, TFList * l2); +// void merge(TFList * l1, TFList * l2); // - merge(p1,p2) function to concatenate lists -void backpatch(TFList * l, int label); +// void backpatch(TFList * l, int label); // - backpatch(p,i) function to fill in jump targets -void bp_temp(int n); +// void bp_temp(int n); extern Instruction * begin; @@ -159,3 +159,4 @@ int get_index(Instruction * i); void set_label(Instruction * i, int label); bool isConst(TNodeOrConst * tnc); int label_gen(); +void backpatch(Stack *s, int l); diff --git a/src/runner.c b/src/runner.c index c134dc4..dd5ea33 100644 --- a/src/runner.c +++ b/src/runner.c @@ -102,7 +102,10 @@ void print_tok(int tok) { int run(FILE *alpha) { int token; top = cur = init(CreateScope(NULL, 1, 1)); - Stack *s = S_Init(); + Stack *stack = S_Init(); + Stack *TrueList = S_Init(); + Stack *FalseList = S_Init(); + // If file is not found if (alpha == NULL) { @@ -335,4 +338,4 @@ char *file_read_line(FILE *fp) { str[len] = '\0'; return str; -} \ No newline at end of file +} diff --git a/tests/carl/NoErrors/selectionSort.alpha b/tests/carl/NoErrors/selectionSort.alpha index edd2076..24fb000 100644 --- a/tests/carl/NoErrors/selectionSort.alpha +++ b/tests/carl/NoErrors/selectionSort.alpha @@ -45,9 +45,9 @@ selectionSort(data) := { data(i) := temp; i := i + 1; } - return true; + return true; } - + (* Function definition entry is the first function called From 2b07464f84849ed1f6f8f6fdce637f26fac39a39 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Wed, 30 Apr 2025 21:55:36 -0400 Subject: [PATCH 02/12] Not working --- src/grammar.h | 2 +- src/grammar.y | 51 ++++++++++------ src/intermediate_code.c | 31 ++++++++-- src/intermediate_code.h | 3 +- tests/sprint2/test/sp2_llnode.alpha | 4 +- tests/sprint2/test/sp2_llnode_bad.alpha | 80 +++++++++++++++++++++++++ 6 files changed, 143 insertions(+), 28 deletions(-) create mode 100644 tests/sprint2/test/sp2_llnode_bad.alpha diff --git a/src/grammar.h b/src/grammar.h index 968bee5..5e1276b 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -31,6 +31,6 @@ int offset; int currentsp; CGNode *cgList; -extern Stack* s; +Stack* stack; Stack* TrueList; Stack* FalseList; diff --git a/src/grammar.y b/src/grammar.y index ba9e96a..1aedc30 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -270,7 +270,7 @@ definition: } //printf("Ending ID: %s\n", $1); //printf("Ending Type: %s\n", getType(table_lookup(getAncestor(cur), $1))); -} idlist R_PAREN ASSIGN sblock +} ; @@ -367,6 +367,7 @@ idlist: sblock: L_BRACE { + // emit_label(label_gen()); if (getLine(cur) != 0) { cur = CreateScope(cur,@1.first_line,@1.first_column); printdebug("Created a new scope"); @@ -554,19 +555,15 @@ compound_statement statement_list { compound_statement: WHILE L_PAREN { - if (!TrueList) {TrueList = S_Init();} - if (!FalseList) {FalseList = S_Init();} - S_Push(TrueList, S_Init()); - S_Push(FalseList, S_Init()); } expression R_PAREN { emit_label(label_gen()); - backpatch(S_Pop(TrueList), getLabel(current)); } sblock { $$ = $7; emit_label(label_gen()); - backpatch(S_Pop(FalseList), getLabel(current)); } - | IF L_PAREN expression R_PAREN THEN {emit_label(label_gen());} sblock ELSE {emit_label(label_gen());} sblock { + | IF L_PAREN expression R_PAREN THEN {emit_label(label_gen());} + sblock ELSE {emit_label(label_gen());} + sblock { /* */ if ($7 == undefined && $10 != undefined) { @@ -657,9 +654,11 @@ rec_op: ablock: - L_PAREN argument_list R_PAREN + L_PAREN {} + argument_list R_PAREN { - $$ = $2; +// here + $$ = $3; printdebug("ablock is %d", $$); } @@ -669,13 +668,20 @@ ablock: argument_list: - //NEED TO EMIT PARAMETERS HERE. MAYBE USE STACK STRUCTURE expression{ TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); // this emits params for function and arrays TODO: fix emit_parameter(tn_or_const(NODE,arg)); - //S_Push(stack,current); - //emit_detach(); + Stack * t = S_Peek(stack); + if (stack == NULL){ + stack = S_Init(); + } + if(t == NULL){ + t = S_Init(); + S_Push(stack, t, 0); + } + S_Push(t, current, 1); + emit_detach(); //printdebug("[ARGUMENT_LIST] argument list is %d", $$); } COMMA argument_list @@ -686,8 +692,7 @@ argument_list: { TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); emit_parameter(tn_or_const(NODE,arg)); - //S_Push(stack,current); - //emit_detach(); + emit_push_all(S_Pop(stack)); $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } @@ -840,7 +845,7 @@ expression: | expression LESS_THAN expression { emit_conditional_jump(E_LESS_THAN, 0, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); - S_Push(S_Peek(TrueList), current); + emit_goto(0); printdebug("less than expression"); if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==integ) { char* temp = temp_var_gen(); @@ -859,6 +864,7 @@ expression: char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); emit_conditional_jump(E_EQUAL_TO, 0, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); + emit_goto(0); $$ = node; } else { @@ -1008,7 +1014,16 @@ assignable: t= TYPE_UNDEFINED; throw_error(ERROR_TYPE, "Undefined type returned by function."); } + // TODO: add from stack + // TODO: emit_function_call TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL); + int a = 0; +/* + if(S_IsEmpty(stack)){ + int a = S_Size(S_Peek(stack)); + } +*/ + emit_function_call(node, a, tn_or_const(NODE, $1)); $$ = 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)); @@ -1037,8 +1052,8 @@ assignable: throw_error(ERROR_TYPE, "Undefined type stored in array."); } TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL); - //emit assign here - //emit_array_access(char* node, char* array, ...) + //TODO: emit assign here + //TODO: emit_array_access(char* node, char* array, ...) $$ = node; printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getType((TableNode*)$1), getName((TableNode*)$1)); } diff --git a/src/intermediate_code.c b/src/intermediate_code.c index fc35a1e..9074047 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -15,16 +15,17 @@ void S_Free(Stack *s){ free(s); } -void S_Push(Stack * s, void *v) { +void S_Push(Stack * s, void *v, int i) { __Node * n = calloc(1, sizeof(*n)); n->v = v; n->next = s->n; s->n = n; + s->w = i; s->size = s->size + 1; } void * S_Pop(Stack *s) { - if (s->size == 0) { + if (s == NULL || !S_IsEmpty(s)) { return NULL; } __Node * node = s->n; @@ -37,20 +38,23 @@ void * S_Pop(Stack *s) { void * S_Peek(Stack *s){ - if (!S_IsEmpty(s)) { + if (s == NULL || !S_IsEmpty(s)) { return NULL; } return s->n->v; } bool S_IsEmpty(Stack *s){ - if(!s->size) { + if(!s) { return true; } return false; } int S_Size(Stack *s){ + if (s == NULL || !S_IsEmpty(s)) { + return 0; + } return s->size; } //_______________________________________________________________________ @@ -64,6 +68,15 @@ char * temp = NULL; otherwise make it next of current and set cur to your instruction. */ +void emit_push_all(Stack * s){ + for (Instruction * i = S_Pop(s); s; i = S_Pop(s)){ + current->next = i; + i->prev = current; + current = i; + current->next = NULL; + } +} + void emit_detach(){ current = current->prev; current->next = NULL; @@ -162,6 +175,12 @@ void emit_binary_op( current->operand2 = arg2; } +void emit_goto(int i){ + emit_helper(); + current->opcode = E_GOTO; + current->label = i; +} + void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){ emit_helper(); current->opcode = op; @@ -257,8 +276,8 @@ void emit_function_call( ){ emit_helper(); current->opcode = E_CALL; - current->operand1 = tn_or_const(INTEGER, ¶m_count); - current->operand2 = name; + current->operand1 = name; + current->operand2 = tn_or_const(INTEGER, ¶m_count); current->result = result; } diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 6a5a9a0..493542c 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -22,11 +22,12 @@ typedef struct __Node { typedef struct Stack { __Node * n; + int w; int size; } Stack; Stack * S_Init(); void S_Free(Stack *s); -void S_Push(Stack * s, void *v); +void S_Push(Stack * s, void *v, int i); void * S_Pop(Stack *s); void * S_Peek(Stack *s); bool S_IsEmpty(Stack *s); diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index 3ecfb11..dfec950 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -73,8 +73,8 @@ entry (arg) := { w := reserve w; w.x := 5; w.y := 7; - result := bar1(w); + (* result := bar1(w); *) result := bar2(5,7); return 0; -} \ No newline at end of file +} diff --git a/tests/sprint2/test/sp2_llnode_bad.alpha b/tests/sprint2/test/sp2_llnode_bad.alpha new file mode 100644 index 0000000..4eab1ae --- /dev/null +++ b/tests/sprint2/test/sp2_llnode_bad.alpha @@ -0,0 +1,80 @@ +type main: string -> integer +function entry: main + +type rec: [integer: x; integer: y] +type T1: integer -> integer +type T2: rec -> integer + +type llnode: [llnode: prev; integer: val; llnode: next] +type list: integer -> llnode + +function foo : T1 +function bar1 : T2 +function bar2 : T2 +function make_list : list + +make_list (a) := { + [integer:orig_a; llnode: ret; llnode: curr; llnode: temp] + + if (a < 0 | a = 0) then { + return null; + } else { + ret := reserve ret; + ret.prev := null; + ret.next := null; + ret.val := a; + while (0 < a) { + temp := reserve temp; + temp.prev := null; + temp.next := null; + temp.val := ret.val; + if (a = orig_a) then { + ret.next := temp; + temp.prev := ret; + curr := temp; + } else { + curr.next := temp; + temp.prev := curr; + curr := temp; + } + a := a - 1; + } + return ret; + } +} + +foo (x) := { + return x * x; +} + +bar1(a,b) := { + return a * b; +} + +bar2(r,s) := { + if (r < s) then { + while (!(r < s)) { + r := r + 1; + } + } else { + [integer: x] + x := 0; + while (x < 10) { + r := r + s; + } + } + return r * s; +} + +entry (arg) := { + [ integer: result ; rec: w; llnode: li; boolean: b] + li := make_list(6, 7); + result := foo(5); + w := reserve w; + w.x := 5; + w.y := 7; + result := bar1(w); + result := bar2(5,7); + + return 'a'; +} From 456346f68ee7ccdcf7849360f5a3c3341bd1fecd Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Thu, 1 May 2025 11:12:58 -0400 Subject: [PATCH 03/12] I added some code to push args but its not working --- src/grammar.y | 21 +++++++++++++++++---- src/intermediate_code.h | 3 +++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 1aedc30..8688a6b 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -654,8 +654,11 @@ rec_op: ablock: - L_PAREN {} - argument_list R_PAREN + L_PAREN{ + emit_push_all(S_Pop(stack)); + } + argument_list { + } R_PAREN { // here $$ = $3; @@ -671,7 +674,6 @@ argument_list: expression{ TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); // this emits params for function and arrays TODO: fix - emit_parameter(tn_or_const(NODE,arg)); Stack * t = S_Peek(stack); if (stack == NULL){ stack = S_Init(); @@ -680,6 +682,7 @@ argument_list: t = S_Init(); S_Push(stack, t, 0); } + emit_parameter(tn_or_const(NODE,arg)); S_Push(t, current, 1); emit_detach(); //printdebug("[ARGUMENT_LIST] argument list is %d", $$); @@ -691,8 +694,17 @@ argument_list: { TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); + Stack * t = S_Peek(stack); + if (stack == NULL){ + stack = S_Init(); + } + if(t == NULL){ + t = S_Init(); + S_Push(stack, t, 0); + } emit_parameter(tn_or_const(NODE,arg)); - emit_push_all(S_Pop(stack)); + S_Push(t, current, 1); + emit_detach(); $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } @@ -1023,6 +1035,7 @@ assignable: int a = S_Size(S_Peek(stack)); } */ + emit_push_all(S_Pop(stack)); emit_function_call(node, a, tn_or_const(NODE, $1)); $$ = node; //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK for function call) diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 493542c..c85c2bc 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -143,6 +143,9 @@ void emit_release(TableNode * pointer); void emit_field_access(char* result, char* record, char* field); void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index); void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr); +void emit_goto(int i); +void emit_detach(); +void emit_push_all(Stack * s); int getLabel(Instruction * i); From 99dffaee01f9dad2edea4306d618e29e9e6b7ed5 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Thu, 1 May 2025 15:22:37 -0400 Subject: [PATCH 04/12] It worksgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit statusgit status! --- src/grammar.y | 44 +++++++++++------------------------------ src/intermediate_code.c | 8 ++++---- src/runner.c | 6 +++--- src/runner.h | 5 ++++- 4 files changed, 23 insertions(+), 40 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 8688a6b..3431a18 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -130,20 +130,11 @@ prototype: definition: TYPE ID COLON { - 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))); 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. + } dblock { setRecSize(look_up(getParent(cur), $2), getRecSize(cur)); - //putting in all the offsets setRecOffsetInfo(cur, look_up(getParent(cur),$2)); printdebug("Moving up a scope after seeing a record definition"); cur = getParent(cur); @@ -155,9 +146,7 @@ definition: CreateEntry(cur,TYPE_ARRAY_TYPE, arrayprim, $2, CreateArrayInfo($4, (TableNode*)$6)); printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, getName((TableNode*)$6)); } - | function_declaration - | TYPE ID COLON id_or_types ARROW id_or_types { printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", $2, getName((TableNode*)$4), getName((TableNode*)$6)); @@ -655,7 +644,11 @@ rec_op: ablock: L_PAREN{ - emit_push_all(S_Pop(stack)); + if (stack == NULL){ + stack = S_Init(); + } + Stack * t = S_Init(); + S_Push(stack, t, 0); } argument_list { } R_PAREN @@ -675,13 +668,10 @@ argument_list: TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); // this emits params for function and arrays TODO: fix Stack * t = S_Peek(stack); - if (stack == NULL){ - stack = S_Init(); - } - if(t == NULL){ - t = S_Init(); - S_Push(stack, t, 0); - } + if(t==NULL){ + t = S_Init(); + S_Push(stack, t, 1); + } emit_parameter(tn_or_const(NODE,arg)); S_Push(t, current, 1); emit_detach(); @@ -694,17 +684,7 @@ argument_list: { TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); - Stack * t = S_Peek(stack); - if (stack == NULL){ - stack = S_Init(); - } - if(t == NULL){ - t = S_Init(); - S_Push(stack, t, 0); - } emit_parameter(tn_or_const(NODE,arg)); - S_Push(t, current, 1); - emit_detach(); $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } @@ -940,7 +920,6 @@ assignable: $$ = pass; printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getType(pass), getName(pass)); } - | assignable { printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); @@ -1035,7 +1014,8 @@ assignable: int a = S_Size(S_Peek(stack)); } */ - emit_push_all(S_Pop(stack)); + emit_push_all(S_Peek(stack)); + S_Pop(stack); emit_function_call(node, a, tn_or_const(NODE, $1)); $$ = node; //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK for function call) diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 9074047..8f22de3 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -25,7 +25,7 @@ void S_Push(Stack * s, void *v, int i) { } void * S_Pop(Stack *s) { - if (s == NULL || !S_IsEmpty(s)) { + if (s == NULL || S_IsEmpty(s)) { return NULL; } __Node * node = s->n; @@ -38,14 +38,14 @@ void * S_Pop(Stack *s) { void * S_Peek(Stack *s){ - if (s == NULL || !S_IsEmpty(s)) { + if (s == NULL || S_IsEmpty(s)) { return NULL; } return s->n->v; } bool S_IsEmpty(Stack *s){ - if(!s) { + if(s == NULL || s->size == 0) { return true; } return false; @@ -69,7 +69,7 @@ char * temp = NULL; */ void emit_push_all(Stack * s){ - for (Instruction * i = S_Pop(s); s; i = S_Pop(s)){ + for (Instruction * i = S_Pop(s); i; i = S_Pop(s)){ current->next = i; i->prev = current; current = i; diff --git a/src/runner.c b/src/runner.c index dd5ea33..b8f709a 100644 --- a/src/runner.c +++ b/src/runner.c @@ -102,9 +102,6 @@ void print_tok(int tok) { int run(FILE *alpha) { int token; top = cur = init(CreateScope(NULL, 1, 1)); - Stack *stack = S_Init(); - Stack *TrueList = S_Init(); - Stack *FalseList = S_Init(); // If file is not found @@ -130,6 +127,9 @@ int run(FILE *alpha) { fseek(alpha, 0, SEEK_SET); yyin = alpha; + stack = S_Init(); + TrueList = S_Init(); + FalseList = S_Init(); yyparse(); if (tok_flag != NULL) { diff --git a/src/runner.h b/src/runner.h index 9971eed..979c36b 100644 --- a/src/runner.h +++ b/src/runner.h @@ -70,6 +70,9 @@ TableNode *recprime; TableNode *funtypeprime; TableNode *undefined; extern Instruction *begin; +extern Stack* stack; +extern Stack* TrueList; +extern Stack* FalseList; int main(int argc, char *argv[]); int check_flag(char *arg, char *alpha); @@ -108,4 +111,4 @@ CodeLine *code_head; char *file_read_line(FILE *fp); void insert_code_line(char * error_message, int line_number); void append_code_line(CodeLine *code_line); -void print_code_lines(); \ No newline at end of file +void print_code_lines(); From c2132ddd00ac05ad586a107c7484e1a3473bcab1 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Thu, 1 May 2025 16:43:00 -0400 Subject: [PATCH 05/12] While list is backpatching --- src/grammar.y | 17 +++++++++++++++++ src/intermediate_code.c | 7 +++++++ src/intermediate_code.h | 1 + 3 files changed, 25 insertions(+) diff --git a/src/grammar.y b/src/grammar.y index 3431a18..3eaa991 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -544,11 +544,15 @@ compound_statement statement_list { compound_statement: WHILE L_PAREN { + S_Push(TrueList, S_Init(), 0); + S_Push(FalseList, S_Init(), 0); } expression R_PAREN { emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); } sblock { $$ = $7; emit_label(label_gen()); + emit_backpatch(S_Pop(FalseList), getLabel(current)); } | IF L_PAREN expression R_PAREN THEN {emit_label(label_gen());} sblock ELSE {emit_label(label_gen());} @@ -837,7 +841,20 @@ expression: | expression LESS_THAN expression { emit_conditional_jump(E_LESS_THAN, 0, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); + Stack * t = S_Peek(TrueList); + if(t==NULL){ + t = S_Init(); + S_Push(TrueList, t, 1); + } + S_Push(t, current, 1); + S_Push(S_Peek(TrueList), current, 1); emit_goto(0); + t = S_Peek(FalseList); + if(t==NULL){ + t = S_Init(); + S_Push(FalseList, t, 1); + } + S_Push(t, current, 1); printdebug("less than expression"); if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==integ) { char* temp = temp_var_gen(); diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 8f22de3..27ea353 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -57,6 +57,12 @@ int S_Size(Stack *s){ } return s->size; } + +void emit_backpatch(Stack * s, int l){ + for (Instruction * i = S_Pop(s); i; i = S_Pop(s)){ + i->label = l; + } +} //_______________________________________________________________________ char * temp = NULL; @@ -72,6 +78,7 @@ void emit_push_all(Stack * s){ for (Instruction * i = S_Pop(s); i; i = S_Pop(s)){ current->next = i; i->prev = current; + i->index = current->index + 1; current = i; current->next = NULL; } diff --git a/src/intermediate_code.h b/src/intermediate_code.h index c85c2bc..f31bcc8 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -164,3 +164,4 @@ void set_label(Instruction * i, int label); bool isConst(TNodeOrConst * tnc); int label_gen(); void backpatch(Stack *s, int l); +void emit_backpatch(Stack *s, int l); From 33347f305197dcb715ee05bfb715fdfb55bbbcf5 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Thu, 1 May 2025 20:55:07 -0400 Subject: [PATCH 06/12] It works for if and while statments. Number of params not going well --- src/grammar.y | 105 ++++++++++++--------- src/intermediate_code.c | 4 +- tests/sprint2/test/sp2_llnode.alpha | 1 - tests/sprint3/test/sp3_multiple_args.alpha | 9 +- 4 files changed, 69 insertions(+), 50 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 3eaa991..dbe97b7 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -542,37 +542,48 @@ compound_statement statement_list { compound_statement: - WHILE L_PAREN -{ - S_Push(TrueList, S_Init(), 0); - S_Push(FalseList, S_Init(), 0); -} expression R_PAREN { - emit_label(label_gen()); - emit_backpatch(S_Pop(TrueList), getLabel(current)); -} sblock { - $$ = $7; - emit_label(label_gen()); - emit_backpatch(S_Pop(FalseList), getLabel(current)); -} - | IF L_PAREN expression R_PAREN THEN {emit_label(label_gen());} - sblock ELSE {emit_label(label_gen());} - sblock { -/* -*/ - if ($7 == undefined && $10 != undefined) { - $$ = $10; - } else if ($7 != undefined && $10 == undefined) { + WHILE L_PAREN { + S_Push(TrueList, S_Init(), 0); + S_Push(FalseList, S_Init(), 0); + int *l = calloc(1, sizeof(int)); + *l = label_gen(); + emit_label(*l); + S_Push(stack, l, 2); + } expression R_PAREN { + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); + } sblock { $$ = $7; - } else if ($7 == $10) { - $$ = $7; - }else if((getAdInfoType((TableNode*)$7) == TYPE_ARRAY_TYPE) && ((TableNode*)$10)==addr){ - $$ = $7; - }else if((getAdInfoType((TableNode*)$7) == TYPE_RECORD_TYPE) && ((TableNode*)$10)==addr){ - $$ = $7; - }else if(((TableNode*)$7)==addr && (getAdInfoType((TableNode*)$10) == TYPE_ARRAY_TYPE)){ - $$ = $10; - }else if(((TableNode*)$7)==addr && (getAdInfoType((TableNode*)$10) == TYPE_RECORD_TYPE)){ - $$ = $10; + int l = label_gen(); + emit_backpatch(S_Pop(FalseList), l); + emit_goto(*(int*)(S_Pop(stack))); + emit_label(l); + } + | IF L_PAREN { + S_Push(TrueList, S_Init(), 0); + S_Push(FalseList, S_Init(), 0); + }expression R_PAREN THEN { + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); + } sblock ELSE { + int l = label_gen(); + emit_backpatch(S_Pop(FalseList), l); + emit_label(l); + } sblock { + if ($8 == undefined && $11 != undefined) { + $$ = $11; + } else if ($8 != undefined && $11 == undefined) { + $$ = $8; + } else if ($8 == $11) { + $$ = $8; + }else if((getAdInfoType((TableNode*)$8) == TYPE_ARRAY_TYPE) && ((TableNode*)$11)==addr){ + $$ = $8; + }else if((getAdInfoType((TableNode*)$8) == TYPE_RECORD_TYPE) && ((TableNode*)$11)==addr){ + $$ = $8; + }else if(((TableNode*)$8)==addr && (getAdInfoType((TableNode*)$11) == TYPE_ARRAY_TYPE)){ + $$ = $11; + }else if(((TableNode*)$8)==addr && (getAdInfoType((TableNode*)$11) == TYPE_RECORD_TYPE)){ + $$ = $11; } else { 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)); @@ -841,13 +852,12 @@ expression: | expression LESS_THAN expression { emit_conditional_jump(E_LESS_THAN, 0, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); - Stack * t = S_Peek(TrueList); - if(t==NULL){ - t = S_Init(); - S_Push(TrueList, t, 1); - } - S_Push(t, current, 1); - S_Push(S_Peek(TrueList), current, 1); + Stack * t = S_Peek(TrueList); + if(t==NULL){ + t = S_Init(); + S_Push(TrueList, t, 1); + } + S_Push(t, current, 1); emit_goto(0); t = S_Peek(FalseList); if(t==NULL){ @@ -873,7 +883,19 @@ expression: char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); emit_conditional_jump(E_EQUAL_TO, 0, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); + Stack * t = S_Peek(TrueList); + if(t==NULL){ + t = S_Init(); + S_Push(TrueList, t, 1); + } + S_Push(t, current, 1); emit_goto(0); + t = S_Peek(FalseList); + if(t==NULL){ + t = S_Init(); + S_Push(FalseList, t, 1); + } + S_Push(t, current, 1); $$ = node; } else { @@ -1022,15 +1044,8 @@ assignable: t= TYPE_UNDEFINED; throw_error(ERROR_TYPE, "Undefined type returned by function."); } - // TODO: add from stack - // TODO: emit_function_call TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL); - int a = 0; -/* - if(S_IsEmpty(stack)){ - int a = S_Size(S_Peek(stack)); - } -*/ + int a = S_Size(S_Peek(stack)); emit_push_all(S_Peek(stack)); S_Pop(stack); emit_function_call(node, a, tn_or_const(NODE, $1)); diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 27ea353..d2868be 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -496,7 +496,7 @@ void emit_as_file(FILE * out_file, Instruction * i){ break; case E_IF_X_TRUE: fprintf(out_file, - "%4.d: if %s goto %d\n", + "%4.d: if %s GOTO %d\n", i->index, get_string(i->operand1), i->label @@ -504,7 +504,7 @@ void emit_as_file(FILE * out_file, Instruction * i){ break; case E_IF_X_FALSE: fprintf(out_file, - "%4.d: if %s false goto %d\n", + "%4.d: if %s false GOTO %d\n", i->index, get_string(i->operand1), i->label diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index dfec950..c78687d 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -15,7 +15,6 @@ function make_list : list make_list (a) := { [integer:orig_a; llnode: ret; llnode: curr; llnode: temp] - if (a < 0 | a = 0) then { return null; } else { diff --git a/tests/sprint3/test/sp3_multiple_args.alpha b/tests/sprint3/test/sp3_multiple_args.alpha index 8475d92..f069230 100644 --- a/tests/sprint3/test/sp3_multiple_args.alpha +++ b/tests/sprint3/test/sp3_multiple_args.alpha @@ -12,7 +12,12 @@ bar (r,s) := { entry (arg) := { [ integer: result ; rec: w] - result := bar(1,2); + while ( result = result ) { + while ( result < w.y ) { + result := 8; + } + result := 9; + } result := bar('c', 7); return 0; -} \ No newline at end of file +} From 558c09e60ffd5e8634f0816fcca1ea8b0d7e3b3d Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Thu, 1 May 2025 20:56:25 -0400 Subject: [PATCH 07/12] added some tests to help demonstrate Still need to verify the results but looks good for now --- tests/sprint3/test/sp3_if_else.alpha | 26 ++++++++++++++++++++++++++ tests/sprint3/test/sp3_if_while.alpha | 27 +++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 tests/sprint3/test/sp3_if_else.alpha create mode 100644 tests/sprint3/test/sp3_if_while.alpha diff --git a/tests/sprint3/test/sp3_if_else.alpha b/tests/sprint3/test/sp3_if_else.alpha new file mode 100644 index 0000000..efb6d69 --- /dev/null +++ b/tests/sprint3/test/sp3_if_else.alpha @@ -0,0 +1,26 @@ +type rec: [character: x; integer: y] + +type T2: rec -> integer + +type main: string -> integer +function entry: main +function bar: T2 + +bar (r,s) := { + return 0; +} + +entry (arg) := { + [ integer: result ; rec: w] + if ( result = result ) then { + result := result + 8; + if ( result < w.y ) then { + result := 8; + } else { + result := 9; + } + } else { + result := bar('c', 7); + } + return 0; +} diff --git a/tests/sprint3/test/sp3_if_while.alpha b/tests/sprint3/test/sp3_if_while.alpha new file mode 100644 index 0000000..bb6a519 --- /dev/null +++ b/tests/sprint3/test/sp3_if_while.alpha @@ -0,0 +1,27 @@ +type rec: [character: x; integer: y] + +type T2: rec -> integer + +type main: string -> integer +function entry: main +function bar: T2 + +bar (r,s) := { + return 0; +} + +entry (arg) := { + [ integer: result ; rec: w] + while ( result = result ) { + result := result + 8; + if ( result < w.y ) then { + while (true) { + result := 8; + } + } else { + result := 9; + } + result := bar('c', 7); + } + return 0; +} From 60ffb33c588832bfcb305f193cb9e81d41331bd3 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Thu, 1 May 2025 21:15:58 -0400 Subject: [PATCH 08/12] Function calls are being emitted with the right int for args --- src/grammar.y | 6 +++++- src/intermediate_code.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index dbe97b7..b793fb0 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1045,10 +1045,14 @@ assignable: throw_error(ERROR_TYPE, "Undefined type returned by function."); } TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL); - int a = S_Size(S_Peek(stack)); +//----------------------------------------------------------------------------- + // Please don't touch + // the + 1 is here because I don't detach the last param + int a = S_Size(S_Peek(stack)) + 1; emit_push_all(S_Peek(stack)); S_Pop(stack); emit_function_call(node, a, tn_or_const(NODE, $1)); +//----------------------------------------------------------------------------- $$ = 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)); diff --git a/src/intermediate_code.c b/src/intermediate_code.c index d2868be..8a89721 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -52,7 +52,7 @@ bool S_IsEmpty(Stack *s){ } int S_Size(Stack *s){ - if (s == NULL || !S_IsEmpty(s)) { + if (s == NULL || S_IsEmpty(s)) { return 0; } return s->size; From b7621278798ff7c6a013fd41236c34bee6e25654 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Fri, 2 May 2025 12:02:07 -0400 Subject: [PATCH 09/12] Fixed the else jump It was falling through --- src/grammar.y | 19 ++++++++++++++----- tests/sprint3/test/sp3_if_else.alpha | 7 +++---- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index b793fb0..a412fd6 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -566,10 +566,17 @@ compound_statement: emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); } sblock ELSE { + // NOTE we are not going back to + int l = label_gen(); + emit_backpatch(S_Pop(FalseList), l); + S_Push(FalseList, S_Init(), 0); + emit_goto(0); + S_Push(S_Peek(FalseList), current, 1); + emit_label(l); + } sblock { int l = label_gen(); emit_backpatch(S_Pop(FalseList), l); emit_label(l); - } sblock { if ($8 == undefined && $11 != undefined) { $$ = $11; } else if ($8 != undefined && $11 == undefined) { @@ -681,16 +688,18 @@ ablock: argument_list: expression{ TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); - // this emits params for function and arrays TODO: fix +// ---------------------------------------------------------------------------- + // this is emitting the param withthe wrong TableNode + // We need to fiture out how to get the right one. Stack * t = S_Peek(stack); if(t==NULL){ t = S_Init(); S_Push(stack, t, 1); } - emit_parameter(tn_or_const(NODE,arg)); + emit_parameter(tn_or_const(NODE,$1)); S_Push(t, current, 1); emit_detach(); - //printdebug("[ARGUMENT_LIST] argument list is %d", $$); +// ---------------------------------------------------------------------------- } COMMA argument_list {$$ = $4 + 1;} @@ -699,7 +708,7 @@ argument_list: { TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); - emit_parameter(tn_or_const(NODE,arg)); + emit_parameter(tn_or_const(NODE,$1)); $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } diff --git a/tests/sprint3/test/sp3_if_else.alpha b/tests/sprint3/test/sp3_if_else.alpha index efb6d69..422da89 100644 --- a/tests/sprint3/test/sp3_if_else.alpha +++ b/tests/sprint3/test/sp3_if_else.alpha @@ -13,14 +13,13 @@ bar (r,s) := { entry (arg) := { [ integer: result ; rec: w] if ( result = result ) then { - result := result + 8; - if ( result < w.y ) then { + if ( result < w.y ) then { result := 8; } else { result := 9; - } + }(* *) } else { - result := bar('c', 7); + result := 1; (* bar('c', 7); *) } return 0; } From 856e443181b77c796947f78cd3a6f04c801a9db4 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 2 May 2025 12:47:22 -0400 Subject: [PATCH 10/12] raaahhhhhh --- Makefile | 5 +++-- src/grammar.y | 2 +- src/intermediate_code.c | 5 +++++ src/runner.c | 2 +- tests/sprint1/test/sp1_simple_alpha.alpha | 6 ++++++ 5 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 tests/sprint1/test/sp1_simple_alpha.alpha diff --git a/Makefile b/Makefile index 6a8e88d..794b839 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,8 @@ CC := gcc FLEX := flex BISON = bison -CFLAGS := -ggdb +CFLAGS := -ggdb -g -O0 #-fsanitize=address +# LDFLAGS := -fsanitize=address BISONFLAGS := -d -Wcounterexamples LEX := src/lexicalStructure.lex @@ -24,7 +25,7 @@ TESTS-S4 := $(wildcard tests/sprint4/test/*.alpha) all: compiler compiler: clean tmp $(OBJS) - $(CC) $(CFLAGS) -o $(EXE) $(OBJS) + $(CC) $(CFLAGS) -o $(EXE) $(OBJS) $(LDFLAGS) clean: rm -f $(EXE) diff --git a/src/grammar.y b/src/grammar.y index 8a287d2..20888a6 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -633,7 +633,7 @@ simple_statement: | RETURN expression { $$ = getTypeEntry((TableNode*)$2); emit_return(tn_or_const(NODE,(TableNode*)$2));} - |simple_statement error {yyerrok; printdebug("error in simple statement");} + |simple_statement error {yyerrok; yyclearin; printdebug("error in simple statement");} ; diff --git a/src/intermediate_code.c b/src/intermediate_code.c index aee5862..dc79abf 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -349,6 +349,11 @@ int label_gen(){ } void emit_as_file(FILE * out_file, Instruction * i){ + if (out_file == NULL){ + fprintf(stderr, "Error: output file is NULL\n"); + return; + } + if(i == NULL){ return; } diff --git a/src/runner.c b/src/runner.c index c134dc4..2616e01 100644 --- a/src/runner.c +++ b/src/runner.c @@ -192,7 +192,7 @@ int new_file(char *arg, char *alpha) { mkdir("./out", 0777); - char *new_basename = calloc(strlen(basename) + 5, sizeof(char)); + char *new_basename = calloc(strlen(basename) + 7, sizeof(char)); strcpy(new_basename, "./out/"); strcat(new_basename, basename); basename = new_basename; diff --git a/tests/sprint1/test/sp1_simple_alpha.alpha b/tests/sprint1/test/sp1_simple_alpha.alpha new file mode 100644 index 0000000..719384b --- /dev/null +++ b/tests/sprint1/test/sp1_simple_alpha.alpha @@ -0,0 +1,6 @@ +type main: string -> integer +function entry: main + +entry(arg) := { + return 0; +} \ No newline at end of file From a876d279d1d4b378a1bcf80f4d7a2526a49010c2 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Fri, 2 May 2025 13:14:41 -0400 Subject: [PATCH 11/12] We did it --- src/grammar.y | 8 +++++++- tests/sprint3/test/sp3_if_else.alpha | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index a412fd6..3393df5 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -924,7 +924,11 @@ expression: $$=$2; } - | RESERVE assignable + // TODO: We need to type check this. + | RESERVE ID {$$ = undefined; } + | RELEASE ID {$$ = undefined; } + | RESERVE ID L_PAREN argument_list R_PAREN {$$ = undefined; } + | RELEASE ID L_PAREN argument_list R_PAREN { int d = getAdInfoType((TableNode*)$2); if(d == TYPE_ARRAY ||d == TYPE_RECORD) { @@ -937,6 +941,7 @@ expression: $$=undefined; } } +/* | RELEASE assignable { int d = getAdInfoType((TableNode*)$2); @@ -950,6 +955,7 @@ expression: $$=undefined; } } +*/ ; diff --git a/tests/sprint3/test/sp3_if_else.alpha b/tests/sprint3/test/sp3_if_else.alpha index 422da89..02c9525 100644 --- a/tests/sprint3/test/sp3_if_else.alpha +++ b/tests/sprint3/test/sp3_if_else.alpha @@ -19,7 +19,7 @@ entry (arg) := { result := 9; }(* *) } else { - result := 1; (* bar('c', 7); *) + result := bar('c', 7); } return 0; } From 5b3de8cb02d1e6834008132cf69595a3446551dc Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Wed, 30 Apr 2025 09:36:05 -0400 Subject: [PATCH 12/12] Demo file choice --- src/codegen.c | 94 ++++++++++++++++++++--------------------- src/intermediate_code.c | 4 ++ src/intermediate_code.h | 1 + 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 8e63df4..09c6af2 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -46,7 +46,7 @@ int generate(){ break; case E_IF_X_TRUE: generateIfTrue(i); - break; + break; case E_IF_X_FALSE: generateIfFalse(i); break; @@ -118,7 +118,7 @@ CGNode *findCG(TableNode *tn) { CGNode *addCG(TableNode *tn, int sp) { CGNode *cg = calloc(1, sizeof(CGNode)); cg->tn = tn; - offset += 4; // <- quick fix getPrimSize(getTypeEntry(tn)) + offset += getPrimSize(getTypeEntry(tn)); cg->address = offset; cg->next = cgList; cgList = cg; @@ -139,7 +139,7 @@ int generateAdd(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("generateAdd failed, NULL operand"); return -1; @@ -148,8 +148,8 @@ int generateAdd(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - - + + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op1)); if (op1CG == NULL) { @@ -177,7 +177,7 @@ int generateSub(Instruction *instruction) { TNodeOrConst *op1 = getOperand1(instruction); TNodeOrConst *op2 = getOperand2(instruction); CGNode *cg = findCG(getResult(instruction)); - + if (op1 == NULL || op2 == NULL) { printdebug("generateSub failed, NULL operand"); return -1; @@ -186,7 +186,7 @@ int generateSub(Instruction *instruction) { if (cg == NULL) { cg = addCG(getResult(instruction), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -214,7 +214,7 @@ int generateMult(Instruction *inst){ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("generateMult failed, NULL operand"); return -1; @@ -250,7 +250,7 @@ int generateDiv(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("generateDiv failed, NULL operand"); return -1; @@ -259,7 +259,7 @@ int generateDiv(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -275,7 +275,7 @@ int generateDiv(Instruction *inst) { fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#division start\n", getAddress(op1CG)); //moves dividend into eax fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#division end\n", getAddress(cg)); //stores result + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#division end\n", getAddress(cg)); //stores result return 0; } @@ -288,7 +288,7 @@ int generateMod(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("generateMod failed, NULL operand"); return -1; @@ -303,12 +303,12 @@ int generateMod(Instruction *inst) { printdebug("generateMod failed, op1 is not constant but not in CGlist"); return -1; } - + if (op2CG == NULL) { printdebug("generateMod failed, %s is not initialized/in CG", getName(getTN(op2))); return -1; } - + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#mod start\n", getAddress(op1CG)); //moves dividend into eax fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack @@ -325,7 +325,7 @@ int generateOr(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("generateOr failed, NULL operand"); return -1; @@ -334,7 +334,7 @@ int generateOr(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -349,22 +349,22 @@ int generateOr(Instruction *inst) { int label = label_gen(); - fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start or\n", getAddress(op1CG)); + fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start or\n", getAddress(op1CG)); fprintf(cg_flag, "\tjne\t.L%dor2\n", label); - fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG)); + fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG)); fprintf(cg_flag, "\tje\t.L%dor3\n", label); fprintf(cg_flag, ".L%dor2:\n", label); - fprintf(cg_flag, "\tmovl\t$1, %%eax\n"); + fprintf(cg_flag, "\tmovl\t$1, %%eax\n"); fprintf(cg_flag, "\tjmp\t.L%dor4\n", label); - + fprintf(cg_flag, ".L%dor3:\n", label); - fprintf(cg_flag, "\tmovl\t$0, %%eax\n"); - + fprintf(cg_flag, "\tmovl\t$0, %%eax\n"); + fprintf(cg_flag, ".L%dor4:\n", label); fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); - fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#or end\n", getAddress(cg)); //stores result + fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#or end\n", getAddress(cg)); //stores result return 0; } @@ -377,7 +377,7 @@ int generateAnd(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED); return -1; @@ -386,7 +386,7 @@ int generateAnd(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -400,27 +400,27 @@ int generateAnd(Instruction *inst) { } int label = label_gen(); - fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start and\n", getAddress(op1CG)); + fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start and\n", getAddress(op1CG)); fprintf(cg_flag, "\tje\t.L%dor2\n", label); - fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG)); + fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG)); fprintf(cg_flag, "\tje\t.L%dor2\n", label); - fprintf(cg_flag, "\tmovl\t$1, %%eax\n"); + fprintf(cg_flag, "\tmovl\t$1, %%eax\n"); fprintf(cg_flag, "\tjmp\t.L%dor3\n", label); fprintf(cg_flag, ".L%dor2:\n", label); - fprintf(cg_flag, "\tmovl\t$0, %%eax\n"); - + fprintf(cg_flag, "\tmovl\t$0, %%eax\n"); + fprintf(cg_flag, ".L%dor3:\n", label); fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); - fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#and end\n", getAddress(cg)); //stores result + fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#and end\n", getAddress(cg)); //stores result return 0; } int generateNeg(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL) { printdebug("generateNeg failed, NULL operand"); return -1; @@ -429,14 +429,14 @@ int generateNeg(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); if (op1CG == NULL) { printdebug("generateNeg failed, op1 is not constant but not in CGlist"); return -1; } - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#negation start\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#negation start\n", getAddress(op1CG)); fprintf(cg_flag, "\tnegl\t%%eax\n"); fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#negation end\n", getAddress(cg)); return 0; @@ -444,7 +444,7 @@ int generateNeg(Instruction *inst) { int generateNot(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL) { printdebug("generateNot failed, NULL operand"); return -1; @@ -453,7 +453,7 @@ int generateNot(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); if (op1CG == NULL) { printdebug("generateNot failed, op1 is not constant but not in CGlist"); @@ -474,7 +474,7 @@ int generateAssign(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL) { printdebug("generateAssign failed, NULL operand"); return -1; @@ -490,14 +490,14 @@ int generateAssign(Instruction *inst) { fprintf(cg_flag, "\tmovl\t$%d, %d(%%rbp)\t#constant assign\n", getConst(op1), getAddress(cg)); return 0; } - + CGNode *op1CG = findCG(getTN(op1)); if (op1CG == NULL) { printdebug("generateAssign failed, op1 is not constant but not in CGlist"); return -1; } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#assign start\n", getAddress(op1CG)); + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#assign start\n", getAddress(op1CG)); fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#assign end\n", getAddress(cg)); return 0; } @@ -528,7 +528,7 @@ int generateLessThan(Instruction *inst){ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED); return -1; @@ -537,7 +537,7 @@ int generateLessThan(Instruction *inst){ if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -550,7 +550,7 @@ int generateLessThan(Instruction *inst){ return -1; } - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#less than start\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#less than start\n", getAddress(op1CG)); fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); fprintf(cg_flag, "\tsetl\t%%al\n"); fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#less than end\n", getAddress(cg)); @@ -566,7 +566,7 @@ int generateEqualTo(Instruction *inst){ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED); return -1; @@ -575,7 +575,7 @@ int generateEqualTo(Instruction *inst){ if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -588,7 +588,7 @@ int generateEqualTo(Instruction *inst){ return -1; } - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#equal to start\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#equal to start\n", getAddress(op1CG)); fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); fprintf(cg_flag, "\tsete\t%%al\n"); fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#equal to end\n", getAddress(cg)); @@ -614,4 +614,4 @@ int generateAddressOf(Instruction *instruction){ int generateParam(Instruction *instruction){ //need to check if op1 is null, then add it to the appropriate register/cg node. need a way to keep track of this, maybe just have global count of params generated return -1; -} \ No newline at end of file +} diff --git a/src/intermediate_code.c b/src/intermediate_code.c index dc79abf..c0fbadb 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -129,6 +129,10 @@ TNodeOrConst * tn_or_const(Discriminant d, void * tnc) { } static void emit_helper(void){ + if (!ir_flag) { + begin = NULL; + return; + } Instruction * inst = calloc(1, sizeof(*inst)); if(begin == NULL){ begin = current = inst; diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 60b64a0..c0f1d63 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -121,6 +121,7 @@ extern Instruction * begin; extern Instruction * current; extern int label_count; extern bool code_gen; +extern FILE * ir_flag; TNodeOrConst * tn_or_const(Discriminant , void * );