From cd4393d0526cecc70d39267be7b76838049f4a01 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Wed, 30 Apr 2025 08:20:11 -0400 Subject: [PATCH 01/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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 a876d279d1d4b378a1bcf80f4d7a2526a49010c2 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Fri, 2 May 2025 13:14:41 -0400 Subject: [PATCH 10/10] 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; }