From d0d38b38e93261df565edef504a0acd9137bdd99 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Sun, 27 Apr 2025 20:12:17 -0400 Subject: [PATCH 001/109] NOTHING MATTERS ANYMORE WOOOOO --- src/codegen.c | 1 - src/grammar.y | 100 ++++++++++++++++++++++++++++---------------------- src/runner.c | 11 ++++-- 3 files changed, 63 insertions(+), 49 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 250d2a4..8e63df4 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -493,7 +493,6 @@ int generateAssign(Instruction *inst) { CGNode *op1CG = findCG(getTN(op1)); if (op1CG == NULL) { - printf("failed here\n"); printdebug("generateAssign failed, op1 is not constant but not in CGlist"); return -1; } diff --git a/src/grammar.y b/src/grammar.y index 7060c94..4ba8a08 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -564,23 +564,36 @@ simple_statement: assignable ASSIGN expression { printdebug("simple statement"); TableNode* node; - if((getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION)|| - (getAdInfoType((TableNode*)$1) == TYPE_ARRAY)|| - (getAdInfoType((TableNode*)$1) == TYPE_RECORD)|| - (getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE)){ + if((getAdInfoType(getTypeEntry(getTypeEntry((TableNode*)$1))) == TYPE_FUNCTION_DECLARATION)|| + (getAdInfoType(getTypeEntry(getTypeEntry((TableNode*)$1))) == TYPE_ARRAY)|| + (getAdInfoType(getTypeEntry(getTypeEntry((TableNode*)$1))) == TYPE_RECORD)|| + (getAdInfoType(getTypeEntry(getTypeEntry((TableNode*)$1))) == TYPE_PRIMITIVE)){ - node = ((TableNode*)$1); - } else{ - printdebug("Invalid type passed to assignable."); - node = undefined; - } + node = ((TableNode*)$1); + } else { + printf("%d\n",getAdInfoType(getTypeEntry(getTypeEntry((TableNode*)$1)))); + throw_error(ERROR_TYPE, "Invalid type passed to assignable."); + printf("%d, %d\n", @1.first_line, @1.first_column); + printf("%s\n", getType(getTypeEntry((TableNode*)$1))); + printf("%s\n\n", getType(getTypeEntry((TableNode*)$3))); + node = undefined; + } if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){ emit_assignment($1, tn_or_const(NODE, $3)); - printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3)); - } else { - throw_error(ERROR_TYPE, "%s != %s", getName(node), getName((TableNode*)$3)); + printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$3)); + } else if (getTypeEntry(getTypeEntry(node)) == arrayprim && getTypeEntry((TableNode*)$3) == addr) { + emit_assignment($1, tn_or_const(NODE, $3)); + printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$3)); + } else if (getTypeEntry(getTypeEntry(node)) == recprime && getTypeEntry((TableNode*)$3) == addr) { + emit_assignment($1, tn_or_const(NODE, $3)); + printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$3)); + } + + + else { + throw_error(ERROR_TYPE, "Object %s of type %s != Object %s of type %s", getName(node), getType(node), getName((TableNode*)$3), getType((TableNode*)$3)); } $$ = undefined; @@ -620,14 +633,14 @@ argument_list: //NEED TO EMIT PARAMETERS HERE. MAYBE USE STACK STRUCTURE expression COMMA argument_list { - CreateEntry(cur,getAdInfoType((TableNode*)$1), (TableNode*)$1, getName((TableNode*)$1), NULL); + CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), getName((TableNode*)$1), NULL); $$ = $3 + 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } | expression { - CreateEntry(cur,getAdInfoType((TableNode*)$1),(TableNode*)$1, getName((TableNode*)$1), NULL); + CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), getName((TableNode*)$1), NULL); $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } @@ -656,7 +669,7 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName(getTypeEntry((TableNode*)$2)), getName(integ)); + throw_error(ERROR_TYPE, "Object %s of type %s is not of type integer and can't be negated", getName((TableNode*)$2), getType((TableNode*)$2)); } } @@ -672,7 +685,7 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$2), getName(boo)); + throw_error(ERROR_TYPE, "Object %s of type %s is not of type Boolean and can't be negated", getName((TableNode*)$2), getType((TableNode*)$2)); } } @@ -687,6 +700,7 @@ expression: } else { $$=undefined; throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -701,7 +715,7 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -715,7 +729,7 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -729,7 +743,7 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -743,7 +757,7 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -757,7 +771,7 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be Boolean", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -771,7 +785,7 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be Boolean", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -785,7 +799,7 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -800,7 +814,7 @@ expression: } else { $$ = undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be the same type", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -824,7 +838,7 @@ expression: //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) $$ = node; } else { - throw_error(ERROR_TYPE, "Invalid memOp expression (%s).", getName((TableNode*)$2)); + throw_error(ERROR_TYPE, "Invalid memOp expression with object %s of type %s.", getName((TableNode*)$2), getType((TableNode*)$2)); $$=undefined; } } @@ -884,13 +898,12 @@ assignable: } if ($3 != getRecLength(param)) { - printdebug("expected %d arguments but got %d", getRecLength(param), $3); + throw_error(ERROR_SYNTAX, "expected %d arguments but got %d", getRecLength(param), $3); } //this isn't very efficient, but will hopefully work while (lastCheckedAct != NULL && lastCheckedRef != NULL) { if (getTypeEntry(lastCheckedRef) != getTypeEntry(lastCheckedAct)) { - printdebug("expected %s. expression in function call got %s. at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); - + throw_error(ERROR_TYPE, "expected %s. expression in function call got %s",getType(lastCheckedRef), getName(lastCheckedAct)); } lastCheckedAct = getNextEntry(lastCheckedAct); TableNode *tn = getFirstEntry(recList); @@ -904,25 +917,24 @@ assignable: } } else { if (strcmp(getName(param), getName(getFirstEntry(cur))) != 0) { - printdebug("expected %s expression in function call but got %s", getName(param), getName(getFirstEntry(cur))); + throw_error(ERROR_TYPE, "expected %s expression in function call but got %s", getName(param), getName(getFirstEntry(cur))); } if (getNextEntry(getFirstEntry(cur)) != NULL) { - printdebug("expected 1 parameter, but got multiple in function call"); + throw_error(ERROR_SYNTAX, "expected 1 parameter, but got multiple in function call"); } } } else { char *expected = getName(getParameter(look_up(getParent(cur), getType((TableNode*)$1)))); char *actual = getType(getFirstEntry(cur)); if (strcmp(expected, actual) != 0) { - printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); + throw_error(ERROR_TYPE, "expected %s expression in function call but got %s", expected, actual); } if ($3 != 1) { - printdebug("expected 1 argument but got %d", $3); - } + throw_error(ERROR_SYNTAX, "expected 1 argument but got %d", $3); } } printTableNode(getReturn(getTypeEntry((TableNode*)$1))); - // + char* temp = temp_var_gen(); TableNode* typeNode2 = getReturn(getTypeEntry($1)); int t = -1; @@ -939,7 +951,7 @@ assignable: t = TYPE_FUNCTION_DECLARATION; }else{ t= TYPE_UNDEFINED; - printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper."); + throw_error(ERROR_TYPE, "Undefined type returned by function."); } TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL); $$ = node; @@ -949,7 +961,7 @@ assignable: } else if (type == TYPE_ARRAY_TYPE) { printdebug("%sEntering array call", COLOR_LIGHTGREEN); if (getNumArrDim(look_up(getParent(cur), getType((TableNode*)$1))) != $2) { - printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $2, @2.first_line, @2.first_column); + throw_error(ERROR_SYNTAX, "expected %d arguments for this array but got %d", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $2); } char* temp = temp_var_gen(); @@ -968,7 +980,7 @@ assignable: t = TYPE_FUNCTION_DECLARATION; }else{ t= TYPE_UNDEFINED; - printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper."); + throw_error(ERROR_TYPE, "Undefined type stored in array."); } TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL); //emit assign here @@ -981,8 +993,8 @@ assignable: | assignable rec_op ID { - if(getAdInfoType((TableNode*)$1) != TYPE_RECORD_TYPE){ - printdebug("CHANGE ME [TYPE CHECK]Invalid type passed to record access"); + if(getAdInfoType((TableNode*)$1) != TYPE_RECORD){ + throw_error(ERROR_TYPE, "Invalid type passed to record access"); } else if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3)) { @@ -1002,7 +1014,7 @@ assignable: t = TYPE_FUNCTION_DECLARATION; }else{ t= TYPE_UNDEFINED; - printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper."); + throw_error(ERROR_TYPE, "Undefined type stored in record."); } TableNode* node = CreateEntry(cur,t, type, temp, NULL); @@ -1010,7 +1022,7 @@ assignable: //emit_field_access(char* node, char* record, $3) $$=node; }else{ - printdebug("CHANGE ME [TYPE CHECK] undefined type (Field Access Lookup failed)"); + throw_error(ERROR_TYPE, "Invalid field access %s", $3); $$=undefined; } printdebug("[ASSIGNABLE - RULE 3] record = name: %s | field = %s", getName((TableNode*)($1)), getName((TableNode*)$3)); @@ -1186,7 +1198,7 @@ void throw_error(ErrorType error_type, const char *format, ...) { return; } - snprintf(total_error_message, total_needed, "%s%s\n\n", error_message, error_message2); + snprintf(total_error_message, total_needed, "%s%s\n", error_message, error_message2); if (tc_flag) { insert_code_line(total_error_message, line); } else { @@ -1208,9 +1220,9 @@ void yyerror(const char *err) { // Grammar Fallback Case if (strcmp(err, "syntax error") == 0) { if (asc_flag != NULL) { - int needed = snprintf(NULL, 0, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n\n", line, column, yytext); + int needed = snprintf(NULL, 0, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n", line, column, yytext); char *error_message = malloc(needed + 1); - snprintf(error_message, needed + 1, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n\n", line, column, yytext); + snprintf(error_message, needed + 1, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n", line, column, yytext); insert_code_line(error_message, line); } else { diff --git a/src/runner.c b/src/runner.c index a74c424..8d5feac 100644 --- a/src/runner.c +++ b/src/runner.c @@ -247,7 +247,7 @@ int is_alpha_file(char *alpha, int file_len) { return 0; // is alpha file } -void insert_code_line(char * error_message, int line_number) { +void insert_code_line(char *error_message, int line_number) { CodeLine *error_line = malloc(sizeof(CodeLine)); error_line->line_number = line_number; error_line->line = malloc(strlen(error_message) + 1); @@ -259,11 +259,14 @@ void insert_code_line(char * error_message, int line_number) { int line = error_line->line_number; CodeLine *current = code_head; + while (current != NULL) { if (current->line_number == line) { - CodeLine *next_code_line = current->next; - current->next = error_line; - error_line->next = next_code_line; + if (current->is_error == false) { + CodeLine *next_code_line = current->next; + current->next = error_line; + error_line->next = next_code_line; + } } current = current->next; } From 94815e237ad448985302402515d3af47709dcf3f Mon Sep 17 00:00:00 2001 From: Partho Date: Sun, 27 Apr 2025 20:57:30 -0400 Subject: [PATCH 002/109] fixing type checks --- src/grammar.y | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 4ba8a08..118be30 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -564,14 +564,14 @@ simple_statement: assignable ASSIGN expression { printdebug("simple statement"); TableNode* node; - if((getAdInfoType(getTypeEntry(getTypeEntry((TableNode*)$1))) == TYPE_FUNCTION_DECLARATION)|| - (getAdInfoType(getTypeEntry(getTypeEntry((TableNode*)$1))) == TYPE_ARRAY)|| - (getAdInfoType(getTypeEntry(getTypeEntry((TableNode*)$1))) == TYPE_RECORD)|| - (getAdInfoType(getTypeEntry(getTypeEntry((TableNode*)$1))) == TYPE_PRIMITIVE)){ + if((getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_FUNCTION_TYPE)|| + (getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_ARRAY_TYPE)|| + (getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_RECORD_TYPE)|| + (getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_PRIMITIVE_TYPE)){ node = ((TableNode*)$1); } else { - printf("%d\n",getAdInfoType(getTypeEntry(getTypeEntry((TableNode*)$1)))); + printf("%d\n",getAdInfoType((getTypeEntry((TableNode*)$1)))); throw_error(ERROR_TYPE, "Invalid type passed to assignable."); printf("%d, %d\n", @1.first_line, @1.first_column); printf("%s\n", getType(getTypeEntry((TableNode*)$1))); @@ -998,7 +998,7 @@ assignable: } else if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3)) { - TableNode* type = table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3); + TableNode* type = getTypeEntry(table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3)); char* temp = temp_var_gen(); int t = -1; if(getAdInfoType(type) == TYPE_PRIMITIVE_TYPE){ From 31e85176011343c64fcae0ffd4b12a87002f62ce Mon Sep 17 00:00:00 2001 From: Partho Date: Sun, 27 Apr 2025 21:51:46 -0400 Subject: [PATCH 003/109] fixed more type checks, just assignable issues left --- src/grammar.y | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 118be30..1bad825 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -258,7 +258,11 @@ definition: TableNode *expected = getReturn(getTypeEntry(look_up(cur, $1))); if ($8 == undefined) { throw_error(ERROR_TYPE, "Expected %s as return type but got undefined (possibly NULL). Differing return types in function.", getName(expected)); - } else if ($8 != expected) { + } else if (getAdInfoType(expected)==TYPE_ARRAY_TYPE && $8 == addr){ + printdebug("CORRECT RETURN TYPE!!!"); + } else if (getAdInfoType(expected)==TYPE_RECORD_TYPE && $8 == addr){ + printdebug("CORRECT RETURN TYPE!!!"); + }else if ($8 != expected) { throw_error(ERROR_TYPE, "Expected %s as return type but got %s. Differing return types in function.", getName(expected), getName($8)); } else { printdebug("CORRECT RETURN TYPE!!!"); @@ -507,8 +511,16 @@ compound_statement statement_list { $$ = $1; } else if ($1 == $2) { $$ = $1; + }else if((getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE) && ((TableNode*)$2)==addr){ + $$ = $1; + }else if((getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE) && ((TableNode*)$2)==addr){ + $$ = $1; + }else if(((TableNode*)$1)==addr && (getAdInfoType((TableNode*)$2) == TYPE_ARRAY_TYPE)){ + $$ = $2; + }else if(((TableNode*)$1)==addr && (getAdInfoType((TableNode*)$2) == TYPE_RECORD_TYPE)){ + $$ = $2; } else { - printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); + printdebug("1 differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); $$ = undefined; } } @@ -522,8 +534,16 @@ compound_statement statement_list { $$ = $1; } else if ($1 == $3) { $$ = $1; + }else if((getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE) && ((TableNode*)$3)==addr){ + $$ = $1; + }else if((getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE) && ((TableNode*)$3)==addr){ + $$ = $1; + }else if(((TableNode*)$1)==addr && (getAdInfoType((TableNode*)$3) == TYPE_ARRAY_TYPE)){ + $$ = $3; + }else if(((TableNode*)$1)==addr && (getAdInfoType((TableNode*)$3) == TYPE_RECORD_TYPE)){ + $$ = $3; } else { - printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); + printdebug("2 differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); $$ = undefined; } } @@ -546,8 +566,18 @@ WHILE L_PAREN expression R_PAREN sblock { $$ = $6; } else if ($6 == $8) { $$ = $6; + }else if((getAdInfoType((TableNode*)$6) == TYPE_ARRAY_TYPE) && ((TableNode*)$8)==addr){ + $$ = $6; + }else if((getAdInfoType((TableNode*)$6) == TYPE_RECORD_TYPE) && ((TableNode*)$8)==addr){ + $$ = $6; + }else if(((TableNode*)$6)==addr && (getAdInfoType((TableNode*)$8) == TYPE_ARRAY_TYPE)){ + $$ = $8; + }else if(((TableNode*)$6)==addr && (getAdInfoType((TableNode*)$8) == TYPE_RECORD_TYPE)){ + $$ = $8; } else { - printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); + printdebug("3 differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); + printf("%s\n", getName((TableNode*)$6)); + printf("%s\n", getName((TableNode*)$8)); $$ = undefined; } } @@ -916,7 +946,7 @@ assignable: } else {break;} } } else { - if (strcmp(getName(param), getName(getFirstEntry(cur))) != 0) { + if (strcmp(getName(param), getType(getFirstEntry(cur))) != 0) { throw_error(ERROR_TYPE, "expected %s expression in function call but got %s", getName(param), getName(getFirstEntry(cur))); } From 49b83cd8ad783d7b9179bf8d5ea5e0f782facf78 Mon Sep 17 00:00:00 2001 From: Partho Date: Mon, 28 Apr 2025 00:06:54 -0400 Subject: [PATCH 004/109] updated errok placements --- Makefile | 2 +- src/grammar.y | 29 ++++++----------------------- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 6fefed1..6a8e88d 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ FLEX := flex BISON = bison CFLAGS := -ggdb -BISONFLAGS := -d +BISONFLAGS := -d -Wcounterexamples LEX := src/lexicalStructure.lex YACC := src/grammar.y diff --git a/src/grammar.y b/src/grammar.y index 1bad825..36741e3 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -106,7 +106,6 @@ program: prototype_or_definition_list - | error { yyerrok; } ; @@ -116,15 +115,14 @@ prototype_or_definition_list: | definition prototype_or_definition_list | prototype | definition - | error { yyerrok; } + | prototype error { yyerrok; } + | definition error { yyerrok; } ; prototype: L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID - - | error { yyerrok; } ; @@ -355,8 +353,6 @@ idlist: printdebug("Type of entry is %s", getType(entry)); printdebug("tag is %d", getAdInfoType(entry)); } - - | error { yyerrok; } ; @@ -405,8 +401,6 @@ sblock: } R_BRACE {$$ = $5;} - - | error { yyerrok; } ; @@ -427,7 +421,6 @@ dblock: } declaration_list R_BRACKET - | error { yyerrok; } ; @@ -436,8 +429,7 @@ dblock: declaration_list: declaration SEMI_COLON declaration_list | declaration - - | error { yyerrok; } + | error SEMI_COLON { yyerrok; } declaration_list //only perform error recovery once we see semi-colon ; @@ -477,8 +469,6 @@ declaration: CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } } - - | error { yyerrok; } ; @@ -496,8 +486,6 @@ id_or_types: printdebug("string of type is %s in types pattern of id_or_type rule.",getName((TableNode*)$1)); $$ = (TableNode*)$1; } - - | error { yyerrok; } ; @@ -550,6 +538,7 @@ compound_statement statement_list { | simple_statement SEMI_COLON { $$ = $1; } + | error SEMI_COLON { yyerrok; } statement_list { $$ = $4; } ; @@ -631,8 +620,8 @@ simple_statement: | RETURN expression {$$ = getTypeEntry((TableNode*)$2);} + |simple_statement error {yyerrok; printdebug("error in simple statement");} - | error { yyerrok; } ; @@ -641,7 +630,6 @@ simple_statement: rec_op: DOT - | error { yyerrok; } ; @@ -653,7 +641,6 @@ ablock: printdebug("ablock is %d", $$); } - | error { yyerrok; } ; @@ -674,7 +661,6 @@ argument_list: $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } - | error { yyerrok; } ; @@ -872,8 +858,6 @@ expression: $$=undefined; } } - - | error { yyerrok; } ; @@ -1058,7 +1042,6 @@ assignable: printdebug("[ASSIGNABLE - RULE 3] record = name: %s | field = %s", getName((TableNode*)($1)), getName((TableNode*)$3)); } - | error { yyerrok; } ; @@ -1075,7 +1058,6 @@ memOp: printdebug("release expression"); } - | error { yyerrok; } ; @@ -1260,3 +1242,4 @@ void yyerror(const char *err) { } } } + From 18a29d7913c45870959b3d4a20f8abc67c20a19b Mon Sep 17 00:00:00 2001 From: Annie Date: Mon, 28 Apr 2025 10:41:43 -0400 Subject: [PATCH 005/109] fixed print warnings --- src/symbol_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 2fc926c..37fc205 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -68,10 +68,10 @@ Constant_Stack *Print_Stack() { printf("Type: %s, Value: NULL", getName(cs->theType)); } if (cs->theType == stri) { - printf("Type: %s, Value: %s\n", getName(cs->theType), *(char *)(cs->theValue)); + printf("Type: %s, Value: %c\n", getName(cs->theType), *(char *)(cs->theValue)); } if (cs->theType == integ) { - printf("Type: %s, Value: %d\n", getName(cs->theType), (int *)(cs->theValue)); + printf("Type: %s, Value: %d\n", getName(cs->theType), *(int *)(cs->theValue)); } if (cs->theType == chara) { printf("Type: %s, Value: %c\n", getName(cs->theType), *(char *)cs->theValue); From dcdcf3106881ab0407ec2699308cbabf68280736 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 29 Apr 2025 14:42:19 -0400 Subject: [PATCH 006/109] still fixing assignable type checking --- src/grammar.y | 88 +++++++++++-------------- src/symbol_table.c | 7 ++ src/symbol_table.h | 2 + tests/carl/NoErrors/functionValue.alpha | 4 +- 4 files changed, 48 insertions(+), 53 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 36741e3..4a3df43 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -650,7 +650,7 @@ argument_list: //NEED TO EMIT PARAMETERS HERE. MAYBE USE STACK STRUCTURE expression COMMA argument_list { - CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), getName((TableNode*)$1), NULL); + CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); $$ = $3 + 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } @@ -880,6 +880,8 @@ assignable: | assignable { printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); + //Creating a dummy scope where we create entries for all the arguments of a function call + //Must also consider that we might be in an array access cur = CreateScope(cur, -1,-1); } //we have to consider emmissions in ablocks @@ -892,61 +894,45 @@ assignable: if (type == TYPE_FUNCTION_TYPE) { printdebug("%sEntering function call", COLOR_LIGHTGREEN); - if (look_up(getParent(cur), getType((TableNode*)$1))->additionalinfo->FunDecAdInfo->regularoras) { - printdebug("as function"); - //char *funtype = getType(look_up(cur, $1)); - //printdebug("%s", getType(look_up(cur, getName((TableNode*)$1)))); - - - - TableNode * typeNode = getTypeEntry((TableNode*)$1); - TableNode *param = getParameter(typeNode); - printTableNode(param); - - if (getAdInfoType(param) == TYPE_RECORD_TYPE) { - SymbolTable *recList = getRecList(param); - TableNode *lastCheckedRef = getFirstEntry(recList); - TableNode *lastCheckedAct = getFirstEntry(cur); - while (getNextEntry(lastCheckedRef) != NULL) { - lastCheckedRef = getNextEntry(lastCheckedRef); + //getting the parameter. The type of assignable is a function type so we need to access the paramater of the type + TableNode *expected = getParameter(getTypeEntry((TableNode*)$1)); + //Jump into case where the parameter is a record type + if(getAdInfoType(expected) == TYPE_RECORD_TYPE){ + //int argument_size = getRecSize(cur); + int parameter_size = getRecSize(getRecList(expected)); + printdebug("argument size is %d\n", $3); + printdebug("parameter size is %d\n", parameter_size); + if ($3 != parameter_size) { + throw_error(ERROR_SYNTAX, "expected %d arguments for this function but got %d", parameter_size, $3); + }else{ + TableNode* param_arg_type = getFirstEntry(getRecList(expected)); + TableNode* arg_given = getFirstEntry(cur); + while(arg_given != NULL && getName(arg_given)[0]=='&'){ + arg_given = getNextEntry(arg_given); } - - if ($3 != getRecLength(param)) { - throw_error(ERROR_SYNTAX, "expected %d arguments but got %d", getRecLength(param), $3); + if(getTypeEntry(arg_given) != param_arg_type){ + throw_error(ERROR_TYPE, "expected %s expression as first argument in function call but got %s", getName(param_arg_type), getType(arg_given)); } - //this isn't very efficient, but will hopefully work - while (lastCheckedAct != NULL && lastCheckedRef != NULL) { - if (getTypeEntry(lastCheckedRef) != getTypeEntry(lastCheckedAct)) { - throw_error(ERROR_TYPE, "expected %s. expression in function call got %s",getType(lastCheckedRef), getName(lastCheckedAct)); + param_arg_type = getNextEntry(param_arg_type); + arg_given = getNextEntry(arg_given); + while(arg_given != NULL && param_arg_type != NULL){ + while(arg_given != NULL && getName(arg_given)[0]=='&'){ + arg_given = getNextEntry(arg_given); } - lastCheckedAct = getNextEntry(lastCheckedAct); - TableNode *tn = getFirstEntry(recList); - - if (tn != lastCheckedRef) { - while (getNextEntry(tn) != lastCheckedRef) { - tn = getNextEntry(tn); - } - lastCheckedRef = tn; - } else {break;} - } - } else { - if (strcmp(getName(param), getType(getFirstEntry(cur))) != 0) { - throw_error(ERROR_TYPE, "expected %s expression in function call but got %s", getName(param), getName(getFirstEntry(cur))); - } - - if (getNextEntry(getFirstEntry(cur)) != NULL) { - throw_error(ERROR_SYNTAX, "expected 1 parameter, but got multiple in function call"); + if(getTypeEntry(arg_given) != param_arg_type){ + throw_error(ERROR_TYPE, "expected %s expression as argument in function call but got %s", getName(param_arg_type), getType(arg_given)); + } + arg_given = getNextEntry(arg_given); + param_arg_type = getNextEntry(param_arg_type); } } - } else { - char *expected = getName(getParameter(look_up(getParent(cur), getType((TableNode*)$1)))); - char *actual = getType(getFirstEntry(cur)); - if (strcmp(expected, actual) != 0) { - throw_error(ERROR_TYPE, "expected %s expression in function call but got %s", expected, actual); - } - if ($3 != 1) { - throw_error(ERROR_SYNTAX, "expected 1 argument but got %d", $3); } + }else{ + TableNode *actual = getTypeEntry(getFirstEntry(cur)); + if (expected == actual) { + throw_error(ERROR_TYPE, "expected %s expression in function call but got %s", expected, actual); } + if ($3 != 1) { + throw_error(ERROR_SYNTAX, "expected 1 argument but got %d", $3); } printTableNode(getReturn(getTypeEntry((TableNode*)$1))); char* temp = temp_var_gen(); @@ -971,7 +957,7 @@ assignable: $$ = node; //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK for function call) printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName(typeNode2), getName((TableNode*)$1)); - + } } else if (type == TYPE_ARRAY_TYPE) { printdebug("%sEntering array call", COLOR_LIGHTGREEN); if (getNumArrDim(look_up(getParent(cur), getType((TableNode*)$1))) != $2) { diff --git a/src/symbol_table.c b/src/symbol_table.c index 2fc926c..7b6771e 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -5,6 +5,7 @@ Constant_Stack *head = NULL; int temp2_count = 0; +int temp3_count = 0; void printdebug_impl(char *file, int line, const char *format, ...) { if (DEBUG) { @@ -24,6 +25,12 @@ char *temp_var_gen() { temp2_count++; return ret; } +char *arg_var_gen() { + char *ret = calloc(9, sizeof(*ret)); + sprintf(ret, "&t%d", temp3_count); + temp3_count++; + return ret; +} Constant_Stack *Push(TableNode *type, void *value, bool isConst) { if (type == NULL || type == undefined) { diff --git a/src/symbol_table.h b/src/symbol_table.h index 391f05a..c64f036 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -101,6 +101,7 @@ void printdebug_impl(char *file, int line, const char *format, ...); printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) char *temp_var_gen(); +char *arg_var_gen(); Constant_Stack *Push(TableNode *type, void *value, bool isConst); Constant_Stack *Pop(); Constant_Stack *Print_Stack(); @@ -165,6 +166,7 @@ extern int column_number; extern FILE *yyin; extern bool DEBUG; extern int temp2_count; +extern int temp3_count; extern TableNode *funprime; extern TableNode *arrayprim; extern TableNode *integ; diff --git a/tests/carl/NoErrors/functionValue.alpha b/tests/carl/NoErrors/functionValue.alpha index f521a42..8ad0e6c 100644 --- a/tests/carl/NoErrors/functionValue.alpha +++ b/tests/carl/NoErrors/functionValue.alpha @@ -56,11 +56,11 @@ c(x) := { entry is the first function called *) entry(arg) := { - [integer: result; string2int: f; integer: temp] + [integer: result; string2int: f; integer: temp; character: char] temp := a("Hello"); f := b(temp); result := c(f); - if (d(1,2,'c')) + if (d(1,2,char)) then { result := 0; } From 4ba6c0d25154a9a4baf20b9aa82b0f1ca4249e2f Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 29 Apr 2025 19:01:57 -0400 Subject: [PATCH 007/109] fixed type checking issues I think --- src/grammar.y | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 4a3df43..d2c4d8e 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -612,7 +612,7 @@ simple_statement: else { - throw_error(ERROR_TYPE, "Object %s of type %s != Object %s of type %s", getName(node), getType(node), getName((TableNode*)$3), getType((TableNode*)$3)); + throw_error(ERROR_TYPE, "Assignable Assign Expression - Object %s of type %s != Object %s of type %s", getName(node), getType(node), getName((TableNode*)$3), getType((TableNode*)$3)); } $$ = undefined; @@ -907,7 +907,7 @@ assignable: }else{ TableNode* param_arg_type = getFirstEntry(getRecList(expected)); TableNode* arg_given = getFirstEntry(cur); - while(arg_given != NULL && getName(arg_given)[0]=='&'){ + while(arg_given != NULL && getName(arg_given)[0]!='&'){ arg_given = getNextEntry(arg_given); } if(getTypeEntry(arg_given) != param_arg_type){ @@ -927,14 +927,22 @@ assignable: } } }else{ - TableNode *actual = getTypeEntry(getFirstEntry(cur)); - if (expected == actual) { - throw_error(ERROR_TYPE, "expected %s expression in function call but got %s", expected, actual); + TableNode*actual_instance = getFirstEntry(cur); + while(actual_instance != NULL && getName(actual_instance)[0] =='&'){ + actual_instance = getNextEntry(actual_instance); + } + if(actual_instance == NULL){ + throw_error(ERROR_TYPE, "Invalid function call. No arguments passed"); + break; + } + TableNode *actual = getTypeEntry(actual_instance); + if (expected != actual) { + throw_error(ERROR_TYPE, "expected %s expression in function call but got %s", getName(expected), getName(actual)); } if ($3 != 1) { throw_error(ERROR_SYNTAX, "expected 1 argument but got %d", $3); } printTableNode(getReturn(getTypeEntry((TableNode*)$1))); - + } char* temp = temp_var_gen(); TableNode* typeNode2 = getReturn(getTypeEntry($1)); int t = -1; @@ -947,6 +955,7 @@ assignable: else if(getAdInfoType(typeNode2) == TYPE_RECORD_TYPE){ t = TYPE_RECORD; } + //this may need to be updated to provide the correct name of things else if(getAdInfoType(typeNode2) == TYPE_FUNCTION_TYPE){ t = TYPE_FUNCTION_DECLARATION; }else{ @@ -957,7 +966,6 @@ assignable: $$ = node; //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK for function call) printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName(typeNode2), getName((TableNode*)$1)); - } } else if (type == TYPE_ARRAY_TYPE) { printdebug("%sEntering array call", COLOR_LIGHTGREEN); if (getNumArrDim(look_up(getParent(cur), getType((TableNode*)$1))) != $2) { From 58c41fd6a4e5234f6d03dcbc3f931a859571ba00 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 29 Apr 2025 21:59:37 -0400 Subject: [PATCH 008/109] almost finished type checks --- src/grammar.y | 62 ++++++++++++++++++++++++++++------------ src/lexicalStructure.lex | 2 +- src/symbol_table.c | 2 +- src/typedefs.h | 2 ++ 4 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index d2c4d8e..eb73cc0 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -28,7 +28,7 @@ %locations - +%token ACCESS 801 %type idlist %type assignable %type expression @@ -166,6 +166,8 @@ definition: } | ID { + //printf("ID: %s\n", $1); + //printf("Type: %s\n", getType(table_lookup(getAncestor(cur), $1))); printdebug("see function def rule 1\n"); TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { @@ -251,6 +253,7 @@ definition: } } //counter = 0; + printdebug("Created a new scope after seeing a function definition"); } idlist R_PAREN ASSIGN sblock { TableNode *expected = getReturn(getTypeEntry(look_up(cur, $1))); @@ -265,6 +268,8 @@ definition: } else { printdebug("CORRECT RETURN TYPE!!!"); } + //printf("Ending ID: %s\n", $1); + //printf("Ending Type: %s\n", getType(table_lookup(getAncestor(cur), $1))); } ; @@ -272,8 +277,10 @@ definition: function_declaration: FUNCTION ID COLON ID { - if(getAdInfoType(look_up(cur, $4))==TYPE_FUNCTION_TYPE){ - CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); + if(getAdInfoType(table_lookup(cur, $4))==TYPE_FUNCTION_TYPE){ + //printf("%s\n",$2); + //printf("%s\n",getName(table_lookup(cur, $4))); + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, table_lookup(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); } else{ throw_error(ERROR_TYPE, "Function declatation (%s) is not a valid function type", $2); @@ -565,8 +572,8 @@ WHILE L_PAREN expression R_PAREN sblock { $$ = $8; } 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)); - printf("%s\n", getName((TableNode*)$8)); + //printf("%s\n", getName((TableNode*)$6)); + //printf("%s\n", getName((TableNode*)$8)); $$ = undefined; } } @@ -590,11 +597,11 @@ simple_statement: node = ((TableNode*)$1); } else { - printf("%d\n",getAdInfoType((getTypeEntry((TableNode*)$1)))); + //printf("%d\n",getAdInfoType((getTypeEntry((TableNode*)$1)))); throw_error(ERROR_TYPE, "Invalid type passed to assignable."); - printf("%d, %d\n", @1.first_line, @1.first_column); - printf("%s\n", getType(getTypeEntry((TableNode*)$1))); - printf("%s\n\n", getType(getTypeEntry((TableNode*)$3))); + //printf("%d, %d\n", @1.first_line, @1.first_column); + //printf("%s\n", getType(getTypeEntry((TableNode*)$1))); + //printf("%s\n\n", getType(getTypeEntry((TableNode*)$3))); node = undefined; } @@ -910,8 +917,8 @@ assignable: while(arg_given != NULL && getName(arg_given)[0]!='&'){ arg_given = getNextEntry(arg_given); } - if(getTypeEntry(arg_given) != param_arg_type){ - throw_error(ERROR_TYPE, "expected %s expression as first argument in function call but got %s", getName(param_arg_type), getType(arg_given)); + if(getTypeEntry(arg_given) != getTypeEntry(param_arg_type)){ + throw_error(ERROR_TYPE, "expected %s expression as first argument in function call but got %s", getType(param_arg_type), getType(arg_given)); } param_arg_type = getNextEntry(param_arg_type); arg_given = getNextEntry(arg_given); @@ -919,8 +926,8 @@ assignable: while(arg_given != NULL && getName(arg_given)[0]=='&'){ arg_given = getNextEntry(arg_given); } - if(getTypeEntry(arg_given) != param_arg_type){ - throw_error(ERROR_TYPE, "expected %s expression as argument in function call but got %s", getName(param_arg_type), getType(arg_given)); + if(getTypeEntry(arg_given) != getTypeEntry(param_arg_type)){ + throw_error(ERROR_TYPE, "expected %s expression as argument in function call but got %s", getType(param_arg_type), getType(arg_given)); } arg_given = getNextEntry(arg_given); param_arg_type = getNextEntry(param_arg_type); @@ -937,7 +944,7 @@ assignable: } TableNode *actual = getTypeEntry(actual_instance); if (expected != actual) { - throw_error(ERROR_TYPE, "expected %s expression in function call but got %s", getName(expected), getName(actual)); + throw_error(ERROR_TYPE, "expected %s expression in function call but got %s", getType(expected), getName(actual)); } if ($3 != 1) { throw_error(ERROR_SYNTAX, "expected 1 argument but got %d", $3); } @@ -968,8 +975,8 @@ assignable: printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName(typeNode2), getName((TableNode*)$1)); } else if (type == TYPE_ARRAY_TYPE) { printdebug("%sEntering array call", COLOR_LIGHTGREEN); - if (getNumArrDim(look_up(getParent(cur), getType((TableNode*)$1))) != $2) { - throw_error(ERROR_SYNTAX, "expected %d arguments for this array but got %d", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $2); + if (getNumArrDim(getTypeEntry((TableNode*)$1)) != $3) { + throw_error(ERROR_SYNTAX, "expected %d arguments for this array but got %d", getNumArrDim(getTypeEntry((TableNode*)$1)), $3); } char* temp = temp_var_gen(); @@ -998,15 +1005,32 @@ assignable: } cur = getParent(cur); } + | assignable rec_op ACCESS + { + if(getAdInfoType((TableNode*)$1) != TYPE_ARRAY){ + throw_error(ERROR_TYPE, "Invalid type passed to array access"); + $$ = undefined; + }else if($3>getNumArrDim(getTypeEntry((TableNode*)$1))){ + throw_error(ERROR_TYPE, "Invalid trying to access the size of dimension %d but this array only has %d dimensions", $3, getNumArrDim(getTypeEntry((TableNode*)$1))); + $$ = undefined; + } else{ + char* temp = temp_var_gen(); + int t = 6; + //emission + $$ = CreateEntry(cur,t, integ, temp, NULL); + } + } - | assignable rec_op ID + | assignable rec_op ID { + if(getAdInfoType((TableNode*)$1) != TYPE_RECORD){ throw_error(ERROR_TYPE, "Invalid type passed to record access"); + $$ = undefined; } - else if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3)) { + else if(undefined != table_lookup(getRecList(getTypeEntry((TableNode*)$1)), $3)) { - TableNode* type = getTypeEntry(table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3)); + TableNode* type = getTypeEntry(table_lookup(getRecList(getTypeEntry((TableNode*)$1)), $3)); char* temp = temp_var_gen(); int t = -1; if(getAdInfoType(type) == TYPE_PRIMITIVE_TYPE){ diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index cd1b56e..7034997 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -59,7 +59,7 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] '{CHAR}' {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);char* token = strdup(yytext)/*yylval.tn = chara*/;yylval.letter = token[1];return C_CHARACTER;} \"{SCHAR}*\" {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);int k = strlen(yytext);yytext[k-1] = '\0';yylval.words = strdup(&yytext[1]);return C_STRING;} {COMMENT} {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/} - +_{DIGIT}+ {if(tok_flag != NULL){print_tok(ACCESS);}incr(line_number,column_number,ACCESS);yylval.integ = atoi(&yytext[1])/*words = strdup("integer")*/;return ACCESS;} "(" { if(tok_flag != NULL) {print_tok(L_PAREN);} incr(line_number,column_number,L_PAREN); return L_PAREN; } ")" { if(tok_flag != NULL) {print_tok(R_PAREN);} incr(line_number,column_number,R_PAREN); return R_PAREN; } "[" { if(tok_flag != NULL) {print_tok(L_BRACKET);} incr(line_number,column_number,L_BRACKET); return L_BRACKET; } diff --git a/src/symbol_table.c b/src/symbol_table.c index cf6edd4..26faf11 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1293,7 +1293,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (getAdInfoType(entry) == TYPE_FUNCTION_DECLARATION) { char *functiontype = (char *)malloc(100); - sprintf(functiontype, " %s", getName(getReturn(entry))); + sprintf(functiontype, " %s", getName(getTypeEntry(entry))); if (parentScopeNum == 0) { st_fprint(file_ptr, getName(entry), currentScopeNum, -100, functiontype, " Function Definition"); } else { diff --git a/src/typedefs.h b/src/typedefs.h index 5c476bf..3b75b3a 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -55,3 +55,5 @@ #define RELEASE 614 // comments #define COMMENT 700 +//Additional tokens +#define ACCESS 801 \ No newline at end of file From 789d67d0b6f1eb984066b1cf579fc743266f8a46 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 29 Apr 2025 22:07:21 -0400 Subject: [PATCH 009/109] IR stuff --- src/intermediate_code.c | 906 ++++++++++++++++++++++++---------------- src/intermediate_code.h | 194 +++++---- 2 files changed, 643 insertions(+), 457 deletions(-) diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 9948115..7dcf481 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -3,398 +3,570 @@ #include "intermediate_code.h" -// TODO: this is here to bring your attention to the comment bellow. -// check if start is NULL if it is assign it to the start globle variable -// otherwise make it next of current and set cur to your instruction. -TNodeOrConst* getOperand1(Instruction* i) { - return i->operand1; +Stack * S_Init(){ + Stack * s = calloc(1, sizeof(*s)); + return s; } -TNodeOrConst* getOperand2(Instruction* i) { - return i->operand2; +void S_Free(Stack *s){ + // since we are not responsible for the values we can just pop until + // NULL + for (void * p = S_Pop(s); p != NULL; p = S_Pop(s)); + free(s); } -TableNode* getResult(Instruction* i) { - return i->result; +void S_Push(Stack * s, void *v) { + __Node * n = calloc(1, sizeof(*n)); + n->v = v + n->next = s->n; + s->n = n; + s->size = s->size + 1; } -Op getOp(Instruction* i) { - return i->opcode; -} - -int getLabel(Instruction* i) { - return i->label; -} - -int get_index(Instruction* i) { - return i->index; -} - -void set_label(Instruction* i, int label) { - i->label = label; -} - -bool isConst(TNodeOrConst* tnc) { - return tnc->d != NODE; -} - -TNodeOrConst* tn_or_const(Discriminant d, void* tnc) { - TNodeOrConst* count = calloc(1, sizeof(*count)); - count->d = d; - count->tnc_union = calloc(1, sizeof(*count->tnc_union)); - switch (d) { - case NODE: - count->tnc_union->node = tnc; - break; - case ADDRESS: - count->tnc_union->address = tnc; - break; - case STRING: - count->tnc_union->string = tnc; - break; - case INTEGER: - count->tnc_union->integer = *(int*)tnc; - break; - case CHARACTER: - count->tnc_union->character = *(char*)tnc; - break; - case BOOLEAN: - count->tnc_union->Boolean = *(uint_least8_t*)tnc; - break; +void * S_Pop(Stack *s) { + if (s->size == 0) { + return NULL; } - return count; + __Node * node = s->n; + s->n = node->next; + s->size = s->size - 1; + void * r = node->v; + free(node); + return r; } -static void emit_helper(void) { - Instruction* inst = calloc(1, sizeof(*inst)); - if (begin == NULL) { - begin = current = inst; - current->index = 1; - } else { - current->next = inst; - inst->prev = current; - inst->index = current->index + 1; - current = inst; + +void * S_Peek(Stack *s){ + if (!S_IsEmpty(s)) { + return NULL; } + return s->n->v; } -void emit_binary_op(Op op, TableNode* result, TNodeOrConst* arg1, TNodeOrConst* arg2) { - emit_helper(); - current->opcode = op; - // TODO: create temp and remove result from param list - current->result = result; - current->operand1 = arg1; - current->operand2 = arg2; -} - -void emit_unary_op(Op op, TableNode* result, TNodeOrConst* arg) { - emit_helper(); - current->opcode = op; - current->result = result; - current->operand1 = arg; -} - -void emit_assignment(TableNode* target, TNodeOrConst* source) { - emit_helper(); - current->opcode = E_ASSIGN; - current->result = target; - current->operand1 = source; -} - -char* get_string(TNodeOrConst* tc) { - char* s; - switch (tc->d) { - case NODE: - return getName(tc->tnc_union->node); - case ADDRESS: - return strdup("null"); - case STRING: - return tc->tnc_union->string; - case INTEGER: - s = calloc(10, sizeof(char)); - sprintf(s, "%d", tc->tnc_union->integer); - return s; - case CHARACTER: - s = calloc(2, sizeof(char)); - sprintf(s, "%c", tc->tnc_union->character); - return s; - case BOOLEAN: - if (tc->tnc_union->Boolean) { - return strdup("true"); - } - return strdup("false"); +bool S_IsEmpty(Stack *s){ + if(!s->size) { + return true; } + return false; } -void emit_as_file(FILE* out_file, Instruction* i) { - if (i == NULL) { - return; - } - switch (i->opcode) { - case E_LABEL: - break; - // this is a terrible one to start with - // fprintf(out_file, "%04.d: %d ", i->index, i->label); - case E_ADD: - fprintf(out_file, "%4.d: %s = %s + %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_SUB: - fprintf(out_file, "%4.d: %s = %s - %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_MUL: - fprintf(out_file, "%4.d: %s = %s * %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_DIV: - fprintf(out_file, "%4.d: %s = %s / %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_MOD: - fprintf(out_file, "%4.d: %s = %s %% %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_OR: - fprintf(out_file, "%4.d: %s = %s | %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_AND: - fprintf(out_file, "%4.d: %s = %s & %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_NEG: - fprintf(out_file, "%4.d: %s = -%s\n", - i->index, getName(i->result), - get_string(i->operand1)); - break; - case E_NOT: - fprintf(out_file, "%4.d: %s = !%s\n", - i->index, getName(i->result), - get_string(i->operand1)); - break; - case E_ASSIGN: - fprintf(out_file, "%4.d: %s = %s\n", - i->index, getName(i->result), - get_string(i->operand1)); - break; - case E_GOTO: - // are we ever going to use this? - // yes we do look at bounds checking - case E_IF_X_TRUE: - fprintf(out_file, "%4.d: if %s goto %d\n", - i->index, get_string(i->operand1), - i->label); - break; - case E_IF_X_FALSE: - fprintf(out_file, "%4.d: if %s false goto %d\n", - i->index, get_string(i->operand1), - i->label); - break; - case E_LESS_THAN: - fprintf(out_file, "%4.d: if %s < %s goto %d\n", - i->index, get_string(i->operand1), - get_string(i->operand2), i->label); - break; - case E_EQUAL_TO: - fprintf(out_file, "%4.d: if %s = %s goto %d\n", - i->index, get_string(i->operand1), - get_string(i->operand2), i->label); - break; - case E_CALL: - fprintf(out_file, "%4.d: call %s %s\n", - i->index, get_string(i->operand1), - get_string(i->operand2)); - break; - - case E_PARAM: - fprintf(out_file, "%4.d: param %s \n", - i->index, get_string(i->operand1)); - break; - case E_RETURN: - - case E_INDEX_COPY_RIGHT: - case E_INDEX_COPY_LEFT: - - case E_ADDRESS_OF: - - case E_DEREF_RIGHT: - case E_DEREF_LEFT: - } - - emit_as_file(out_file, i->next); +int S_Size(Stack *s){ + return s->size; } +//_______________________________________________________________________ -void emit_label(int label) { - emit_helper(); - current->opcode = E_LABEL; - current->label = label; -} +Instruction * begin; +Instruction * current; +char * temp = NULL; -void emit_jump(int label) { - emit_helper(); - current->opcode = E_GOTO; - current->label = label; -} -void emit_conditional_jump(Op condition, int label, ...) { - // when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *). - // when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *) - emit_helper(); - va_list argptr; - va_start(argptr, label); - current->opcode = condition; - current->label = label; - TNodeOrConst* n1; - TNodeOrConst* n2; - switch (condition) { - case E_IF_X_TRUE: - case E_IF_X_FALSE: - n1 = va_arg(argptr, TNodeOrConst*); - current->operand1 = n1; - break; - case E_LESS_THAN: - case E_EQUAL_TO: - n1 = va_arg(argptr, TNodeOrConst*); - n2 = va_arg(argptr, TNodeOrConst*); - current->operand1 = n1; - current->operand2 = n2; - break; - } - va_end(argptr); -} - -void emit_function_start(TNodeOrConst * name) { - emit_helper(); - current->opcode = E_LABEL; // I think this is right TODO: ask - current->operand1 = name; - // this is probabaly a func declaration -} - -void emit_parameter(TNodeOrConst* param) { - emit_helper(); - current->opcode = E_PARAM; - current->operand1 = param; -} - -void emit_function_call(TableNode* result, int param_count, TNodeOrConst* name) { - emit_helper(); - current->opcode = E_CALL; - current->operand1 = tn_or_const(INTEGER, ¶m_count); - current->operand2 = name; - current->result = result; -} - -void emit_return(TNodeOrConst* value) { - emit_helper(); - current->opcode = E_RETURN; - current->operand1 = value; -} - -void emit_reserve(TableNode* result, TNodeOrConst* size) { - emit_parameter(size); - emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); -} - -void emit_release(TableNode* pointer) { - emit_parameter(tn_or_const(NODE, pointer)); - emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release"))); -} - -void emit_deref_right() { - return; -} - -void emit_deref_left() { - return; -} - -void emit_field_access(char* result, char* record, char* field) { - emit_helper(); -} - -void emit_array_access(Op op, TableNode* result, TNodeOrConst* array, TNodeOrConst* index) { - emit_helper(); - current->opcode; - current->result = result; - current->operand1 = array; - current->operand2 = index; - // TODO: Still don't know what to do with the dimentions -} - -void emit_bounds_check(TNodeOrConst* index, TNodeOrConst* arr) { - /* - {[string: 5] - . - . - s:= reserve s(5); - s(0) := 'H'; - s(1) := 'e'; - . - . - s._0 num of dims Known at compile time - s._1 size Known at run time - s._1 int | 1 byte - +-------+---+---+---+---+---+ - | 5 | H | e | l | l | o | - +-------+---+---+---+---+---+ - size - ^ - | - p - s._0 ok - s._1 ok - s._2 not ok - t_0 is index - t_1 = *(int *)p = s._1 - if t_0 < 0 GOTO ERROR - if t_0 < s._1 GOTO access array - GOTO ERROR + /* + TODO: this is here to bring your attention to the comment bellow. + check if start is NULL if it is assign it to the start globle variable + otherwise make it next of current and set cur to your instruction. */ - //emit_conditional_jump(E_LESS_THAN, ); - //emit_conditional_jump(E_LESS_THAN, ); - //emit_jump(); - /* We need a label ERROR to jump to - */ + + +TNodeOrConst * getOperand1(Instruction * i){ + return i->operand1; } -/*// * Implement temp variable generator function that produces unique names (t1, t2, etc.) +TNodeOrConst * getOperand2(Instruction * i){ + return i->operand2; +} + +TableNode * getResult(Instruction * i){ + return i->result; +} + +Op getOp(Instruction * i){ + return i->opcode; +} + +int getLabel(Instruction * i){ + return i->label; +} + +int get_index(Instruction * i){ + return i->index; +} + +void set_label(Instruction * i, int label){ + i->label = label; +} + +bool isConst(TNodeOrConst * tnc) { + return tnc->d != NODE; +} + +TNodeOrConst * tn_or_const(Discriminant d, void * tnc) { + TNodeOrConst * count = calloc(1, sizeof(*count)); + count->d = d; + count->tnc_union = calloc(1, sizeof(*count->tnc_union)); + switch (d) { + case NODE: + count->tnc_union->node = tnc; + break; + case ADDRESS: + count->tnc_union->address = tnc; + break; + case STRING: + count->tnc_union->string = tnc; + break; + case INTEGER: + count->tnc_union->integer = *(int*)tnc; + break; + case CHARACTER: + count->tnc_union->character = *(char*)tnc; + break; + case BOOLEAN: + count->tnc_union->Boolean = *(uint_least8_t*)tnc; + break; + } + return count; +} + +static void emit_helper(void){ + Instruction * inst = calloc(1, sizeof(*inst)); + if(begin == NULL){ + begin = current = inst; + current->index = 1; + } else { + current->next = inst; + inst->prev = current; + inst->index = current->index + 1; + current = inst; + } +} + +void emit_binary_op( + Op op, + TableNode * result, + TNodeOrConst * arg1, + TNodeOrConst * arg2 + ){ + emit_helper(); + current->opcode = op; + // TODO: create temp and remove result from param list + current->result = result; + current->operand1 = arg1; + current->operand2 = arg2; + } + +void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){ + emit_helper(); + current->opcode = op; + current->result = result; + current->operand1 = arg; + } + +void emit_assignment(TableNode * target, TNodeOrConst * source){ + emit_helper(); + current->opcode = E_ASSIGN; + current->result = target; + current->operand1 = source; + } + +char * get_string(TNodeOrConst * tc){ + char * s; + switch (tc->d) { + case NODE: + return getName(tc->tnc_union->node); + case ADDRESS: + return strdup("null"); + case STRING: + return tc->tnc_union->string; + case INTEGER: + s = calloc(10, sizeof(char)); + sprintf(s, "%d", tc->tnc_union->integer); + return s; + case CHARACTER: + s = calloc(2, sizeof(char)); + sprintf(s, "%c", tc->tnc_union->character); + return s; + case BOOLEAN: + if(tc->tnc_union->Boolean){ + return strdup("true"); + } + return strdup("false"); + } +} + +void emit_label(int label){ + emit_helper(); + current->opcode = E_LABEL; + current->label = label; +} + +void emit_jump(int label){ + emit_helper(); + current->opcode = E_GOTO; + current->label = label; +} + +void emit_conditional_jump(Op condition, int label, ...){ + // when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *). + // when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *) + emit_helper(); + va_list argptr; + va_start(argptr, label); + current->opcode = condition; + current->label = label; + TNodeOrConst * n1; + TNodeOrConst * n2; + switch (condition) { + case E_IF_X_TRUE: case E_IF_X_FALSE: + n1 = va_arg(argptr, TNodeOrConst *); + current->operand1 = n1; + break; + case E_LESS_THAN: case E_EQUAL_TO: + n1 = va_arg(argptr, TNodeOrConst *); + n2 = va_arg(argptr, TNodeOrConst *); + current->operand1 = n1; + current->operand2 = n2; + break; + } + va_end(argptr); +} + +void emit_function_start(TableNode * name){ + emit_helper(); + current->opcode = E_FUNC_START; + current->result = name; +} + +void emit_parameter(TNodeOrConst * param){ + emit_helper(); + current->opcode = E_PARAM; + current->operand1 = param; +} + +void emit_function_call( + TableNode * result, + int param_count, + TNodeOrConst * name + ){ + emit_helper(); + current->opcode = E_CALL; + current->operand1 = tn_or_const(INTEGER, ¶m_count); + current->operand2 = name; + current->result = result; +} + +void emit_return(TNodeOrConst * value){ + emit_helper(); + current->opcode = E_RETURN; + current->operand1 = value; +} + +void emit_reserve(TableNode * result, TNodeOrConst * size){ + emit_parameter(size); + emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); +} + +void emit_release(TableNode * pointer){ + emit_parameter(tn_or_const(NODE, pointer)); + emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release"))); +} + +void emit_deref_right(TableNode * x, TNodeOrConst * y){ + emit_helper(); + current->opcode = E_DEREF_RIGHT; + current->result = x; + current->operand1 = y; +} + +void emit_deref_left(TableNode * x, TNodeOrConst * y){ + emit_helper(); + current->opcode = E_DEREF_LEFT; + current->result = x; + current->operand1 = y; +} + +void emit_address_of(TableNode * x, TNodeOrConst * y){ + emit_helper(); + current->opcode = E_ADDRESS_OF; + current->result = x; + current->opernad1 = y; +} + +void emit_field_access(char* result, char* record, char* field){ + emit_helper(); +} + +void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index){ + emit_helper(); + current->opcode = op; + current->result = result; + current->operand1 = array; + current->operand2 = index; + // TODO: Still don't know what to do with the dimentions +} + +void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr){ + /* + {[string: 5] + . + . + s:= reserve s(5); + s(0) := 'H'; + s(1) := 'e'; + . + . + s._0 num of dims Known at compile time + s._1 size Known at run time + s._1 int | 1 byte + +-------+---+---+---+---+---+ + | 5 | H | e | l | l | o | + +-------+---+---+---+---+---+ + size + ^ + | + p + s._0 ok + s._1 ok + s._2 not ok + t_0 is index + t_1 = *(int *)p = s._1 + if t_0 < 0 GOTO ERROR + if t_0 < s._1 GOTO access array + GOTO ERROR + */ + /* We need a label ERROR to jump to + emit_conditional_jump(E_LESS_THAN, ); + emit_conditional_jump(E_LESS_THAN, ); + emit_jump(); + */ +} + +// * Implement temp variable generator function that produces unique names (t1, t2, etc.) char * temp_var_gen(){ - char * ret = calloc(9, sizeof(*ret)); - sprintf(ret, "$t%d", temp_count); - temp_count++; - return ret; -} -*/ -int label_gen(){ - label_count++; - return label_count; + char * ret = calloc(9, sizeof(*ret)); + sprintf(ret, "$t%d", temp_count); + temp_count++; + return ret; } -TableNode* getTN(TNodeOrConst* tnc) { - if (tnc->d == NODE) { - return tnc->tnc_union->node; - } - return NULL; +char * label_gen(){ + char * ret = calloc( 9, sizeof(*ret)); + sprintf(ret, "L_%d", label_count); + label_count++; + return ret; } -int getConst(TNodeOrConst* tnc) { - if (tnc->d == INTEGER) { - return tnc->tnc_union->integer; - } - return -1; +void emit_as_file(FILE * out_file, Instruction * i){ + if(i == NULL){ + return; + } + switch(i->opcode){ + case E_FUNC_START: + fprintf(out_file, + "%4.d: func : %s\n", + i->index, + getName(i->result) + ); + break; + case E_LABEL: + fprintf(out_file, + "%4.d: Label : %d\n", + i->index, + i->label + ); + break; + case E_ADD: + fprintf(out_file, + "%4.d: %s = %s + %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2) + ); + break; + case E_SUB: + fprintf(out_file, + "%4.d: %s = %s - %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2) + ); + break; + case E_MUL: + fprintf(out_file, + "%4.d: %s = %s * %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2) + ); + break; + case E_DIV: + fprintf(out_file, + "%4.d: %s = %s / %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2) + ); + break; + case E_MOD: + fprintf(out_file, + "%4.d: %s = %s %% %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2) + ); + break; + case E_OR: + fprintf(out_file, + "%4.d: %s = %s | %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2) + ); + break; + case E_AND: + fprintf(out_file, + "%4.d: %s = %s & %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2) + ); + break; + case E_NEG: + fprintf(out_file, + "%4.d: %s = -%s\n", + i->index, + getName(i->result), + get_string(i->operand1) + ); + break; + case E_NOT: + fprintf(out_file, + "%4.d: %s = !%s\n", + i->index, + getName(i->result), + get_string(i->operand1) + ); + break; + case E_ASSIGN: + fprintf(out_file, + "%4.d: %s = %s\n", + i->index, + getName(i->result), + get_string(i->operand1) + ); + break; + case E_GOTO: + fprintf(out_file, + "%4.d: GOTO : %d\n", + i->index, + i->label + ); + break; + case E_IF_X_TRUE: + fprintf(out_file, + "%4.d: if %s goto %d\n", + i->index, + get_string(i->operand1), + i->label + ); + break; + case E_IF_X_FALSE: + fprintf(out_file, + "%4.d: if %s false goto %d\n", + i->index, + get_string(i->operand1), + i->label + ); + break; + case E_LESS_THAN: + // this feels wrong I need to TODO: this + fprintf(out_file, + "%4.d: %s = %s < %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2) + ); + break; + case E_EQUAL_TO: + // this feels wrong I need to TODO: this + fprintf(out_file, + "%4.d: %s = %s == %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2) + ); + break; + case E_CALL: + fprintf(out_file, + "%4.d: call : %s %s\n", + i->index, + get_string(i->operand1), + get_string(i->operand2) + ); + break; + case E_PARAM: + fprintf(out_file, + "%4.d: param %s \n", + i->index, + get_string(i->operand1) + ); + break; + case E_RETURN: + fprintf(out_file, + "%4.d: return : %s\n", + i->index, + get_string(i->operand1) + ); + break; + case E_INDEX_COPY_RIGHT: + fprintf(out_file, + "%4.d: %s = %s[ %s ]\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2) + ); + break; + case E_INDEX_COPY_LEFT: + fprintf(out_file, + "%4.d: %s[ %s ] = %s\n", + i->index, + getName(i->result), + get_string(i->operand2), + get_string(i->operand1)); + break; + case E_ADDRESS_OF: + fprintf(out_file, + "%4.d: %s = &%s\n", + i->index, + getName(i->result), + get_string(i->operand1) + ); + break; + + + case E_DEREF_RIGHT: + fprintf(out_file, + "%4.d: %s = *%s\n", + i->index, + getName(i->result), + get_string(i->operand1) + ); + case E_DEREF_LEFT: + fprintf(out_file, + "%4.d: *%s = %s\n", + i->index, + getName(i->result), + get_string(i->operand1) + ); + } + + emit_as_file(out_file, i->next); } \ No newline at end of file diff --git a/src/intermediate_code.h b/src/intermediate_code.h index c1efb76..9f99d2b 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -12,113 +12,127 @@ #include "symbol_table.h" -// these are from page 364 -typedef enum { - E_LABEL = 10000, // this is not in the book - E_ADD, // 1 from the list - E_SUB, // 1 - E_MUL, // 1 - E_DIV, // 1 - E_MOD, // 1 - E_OR, // 1 - E_AND, // 1 - E_NEG, // 2 - E_NOT, // 2 - E_ASSIGN, // 3 - E_GOTO, // 4 - E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got - E_IF_X_TRUE, // 5 - E_IF_X_FALSE, // 5 - E_LESS_THAN, // 6 rule 1 + 5 - E_EQUAL_TO, // 6 rule 1 + 5 - E_CALL, // 7 - E_PARAM, // 7 - E_RETURN, // 7 - E_INDEX_COPY_RIGHT, // 8 this is x = y[i] - E_INDEX_COPY_LEFT, // 8 x[i] = y - E_ADDRESS_OF, // 9 x = &y - E_DEREF_RIGHT, // 9 x = *y - E_DEREF_LEFT // 9 x* = y +typedef struct Stack Stack; +typedef struct __Node __Node; + +typedef struct __Node { + void * v; + __Node * next; +} __Node; + +typedef struct Stack { + __Node * n; + int size; +} Stack; +//______________________________________________________________________________________________ + +typedef union TNConstUnion TNConstUnion; +typedef struct Instruction Instruction; +typedef struct TNodeOrConst TNodeOrConst; + +typedef enum { // these are from page 364 + E_LABEL = 10000, // this is not in the book + E_FUNC_START, + E_ADD, // 1 from the list + E_SUB, // 1 + E_MUL, // 1 + E_DIV, // 1 + E_MOD, // 1 TODO: Please change to REM + E_OR, // 1 + E_AND, // 1 + E_NEG, // 2 + E_NOT, // 2 + E_ASSIGN, // 3 + E_GOTO, // 4 + E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got + E_IF_X_TRUE, // 5 + E_IF_X_FALSE, // 5 + E_LESS_THAN, // 6 rule 1 + 5 + E_EQUAL_TO, // 6 rule 1 + 5 + E_CALL, // 7 + E_PARAM, // 7 + E_RETURN, // 7 + E_INDEX_COPY_RIGHT, // 8 this is x = y[i] + E_INDEX_COPY_LEFT, // 8 x[i] = y + E_ADDRESS_OF, // 9 x = &y + E_DEREF_RIGHT, // 9 x = *y + E_DEREF_LEFT // 9 x* = y } Op; typedef enum { - NODE = 11000, // TableNode - INTEGER, // int - STRING, // char * - CHARACTER, // char - ADDRESS, // void * - BOOLEAN // bool + NODE = 11000, // TableNode + INTEGER, // int + STRING, // char * + CHARACTER, // char + ADDRESS, // void * + BOOLEAN // bool } Discriminant; -typedef union { - TableNode* node; - int integer; - char* string; - char character; - void* address; - bool Boolean; +typedef union TNConstUnion { + TableNode * node; + int integer; + char * string; + char character; + void * address; + bool Boolean; } TNConstUnion; -typedef struct { - Discriminant d; - TNConstUnion* tnc_union; +typedef struct TNodeOrConst { + Discriminant d; + TNConstUnion * tnc_union; } TNodeOrConst; -typedef struct Instruction Instruction; typedef struct Instruction { - Op opcode; - TableNode* result; - TNodeOrConst* operand1; - TNodeOrConst* operand2; - int label; - int index; + Op opcode; + TableNode * result; + TNodeOrConst * operand1; + TNodeOrConst * operand2; + int label; + int index; - Instruction* prev; - Instruction* next; + Instruction * prev; + Instruction * next; } Instruction; + +// NOTE We are not using this We are using the Stack api typedef struct TFList { - Instruction* i; - TFList* next; + Instruction * i; + TFList * next; } TFList; -TNodeOrConst* getOperand1(Instruction* i); -TNodeOrConst* getOperand2(Instruction* i); -TableNode* getResult(Instruction* i); -Op getOp(Instruction* i); -int getLabel(Instruction* i); -int get_index(Instruction* i); -void set_label(Instruction* i, int label); -bool isConst(TNodeOrConst* tnc); -TNodeOrConst* tn_or_const(Discriminant d, void* tnc); -static void emit_helper(void); -void emit_binary_op(Op op, TableNode* result, TNodeOrConst* arg1, TNodeOrConst* arg2); -void emit_unary_op(Op op, TableNode* result, TNodeOrConst* arg); -void emit_assignment(TableNode* target, TNodeOrConst* source); -char* get_string(TNodeOrConst* tc); -void emit_as_file(FILE* out_file, Instruction* i); +TFList * make_list(Instruction * i); + // - makelist(i) function to create instruction lists +void merge(TFList * l1, TFList * l2); + // - merge(p1,p2) function to concatenate lists +void backpatch(TFList * l, int label); + // - backpatch(p,i) function to fill in jump targets +void bp_temp(int n); + + +extern Instruction * begin; +extern Instruction * current; +int temp_count = 0; +int label_count = 0; +bool code_gen = true; + + +TNodeOrConst * tn_or_const(Discriminant , void * ); +void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2); +void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg); +void emit_assignment(TableNode * target, TNodeOrConst * source); +void emit_as_file(FILE * out_file, Instruction * instr_arr); void emit_label(int label); void emit_jump(int label); + void emit_conditional_jump(Op condition, int label, ...); -void emit_function_start(TNodeOrConst * name); -void emit_parameter(TNodeOrConst* param); -void emit_function_call(TableNode* result, int param_count, TNodeOrConst* name); -void emit_return(TNodeOrConst* value); -void emit_reserve(TableNode* result, TNodeOrConst* size); -void emit_release(TableNode* pointer); -void emit_deref_right(); -void emit_deref_left(); + +void emit_function_start(int name); +void emit_parameter(TNodeOrConst * param); +void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name); +void emit_return(TNodeOrConst * value); +void emit_reserve(TableNode * result, TNodeOrConst * size); +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); -int label_gen(); -TableNode* getTN(TNodeOrConst* tnc); -int getConst(TNodeOrConst* tnc); - -extern int label_count; -extern Instruction* begin; -extern Instruction* current; - -extern int offset; -extern int currentsp; -extern CGNode* cgList; \ No newline at end of file +void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index); +void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr, int error_label); \ No newline at end of file From e45f0663f120df671bce4c3cf766855ac956a91c Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Tue, 29 Apr 2025 22:40:32 -0400 Subject: [PATCH 010/109] I made the IR compile --- src/CG.c | 614 ++++++++++++++++++++++++++++++++++++++++ src/IR.c | 395 ++++++++++++++++++++++++++ src/intermediate_code.c | 36 ++- src/intermediate_code.h | 33 ++- src/stacks.h.gch | Bin 0 -> 1745332 bytes 5 files changed, 1058 insertions(+), 20 deletions(-) create mode 100644 src/CG.c create mode 100644 src/IR.c create mode 100644 src/stacks.h.gch diff --git a/src/CG.c b/src/CG.c new file mode 100644 index 0000000..c550dea --- /dev/null +++ b/src/CG.c @@ -0,0 +1,614 @@ + +int generate(){ + offset = 0; + Instruction *i = begin; + while (i != NULL) { + switch(getOp(i)) { + case E_LABEL: + generateLabel(i); + break; + case E_ADD: + generateAdd(i); + break; + case E_SUB: + generateSub(i); + break; + case E_MUL: + generateMult(i); + break; + case E_DIV: + generateDiv(i); + break; + case E_MOD: + generateMod(i); + break; + case E_OR: + generateOr(i); + break; + case E_AND: + generateAnd(i); + break; + case E_NEG: + generateNeg(i); + break; + case E_NOT: + generateNot(i); + break; + case E_ASSIGN: + generateAssign(i); + break; + case E_GOTO: + generateGoto(i); + break; + case E_IF_X_TRUE: + generateIfTrue(i); + break; + case E_IF_X_FALSE: + generateIfFalse(i); + break; + case E_LESS_THAN: + generateLessThan(i); + break; + case E_EQUAL_TO: + generateEqualTo(i); + break; + case E_CALL: + generateCall(i); + break; + case E_PARAM: + generateParam(i); + break; + case E_RETURN: + generateReturn(i); + break; + case E_INDEX_COPY_RIGHT: + generateCopyRight(i); + break; + case E_INDEX_COPY_LEFT: + generateCopyLeft(i); + break; + case E_ADDRESS_OF: + generateAddressOf(i); + break; + default: + ; + } + i = i->next; + } + return -1; +} + +CGNode *getNextCG(CGNode *cg) { + if (cg == NULL) { + return NULL; + } + return cg->next; +} + +int getAddress(CGNode *cg) { + if (cg == NULL) { + return -1; + } + + return currentsp - cg->address; +} + +TableNode *getTNofCG(CGNode *cg) { + if (cg == NULL) { + return NULL; + } + return cg->tn; +} + +CGNode *findCG(TableNode *tn) { + CGNode *cg = cgList; + while (cg != NULL) { + if (getTNofCG(cg) == tn) { + return cg; + } + cg = getNextCG(cg); + } + return NULL; +} + +CGNode *addCG(TableNode *tn, int sp) { + CGNode *cg = calloc(1, sizeof(CGNode)); + cg->tn = tn; + offset += getPrimSize(getTypeEntry(tn)); + cg->address = offset; + cg->next = cgList; + cgList = cg; + return cg; +} + + +int generateLabel(Instruction *inst) { + fprintf(cg_flag, ".L%d:\n", getLabel(inst)); + return 0; +} +int generateAdd(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + 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; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op1)); + if (op1CG == NULL) { + printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op1))); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#addition start\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\taddl\t%%edx, %%eax\n"); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#addition end\n", getAddress(cg)); + return 0; +} + +int generateSub(Instruction *instruction) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + 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; + } + + if (cg == NULL) { + cg = addCG(getResult(instruction), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateSub failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#subtraction start\n", getAddress(op1CG)); + fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#subtraction end\n", getAddress(cg)); + return 0; +} + +int generateMult(Instruction *inst){ + /* + Both immediate: + One immediate: + Neither immediate: + */ + 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; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateMult failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateMult failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#multiplication start\n", getAddress(op1CG)); + fprintf(cg_flag, "\timull\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#multiplication end\n", getAddress(cg)); + return 0; +} + +int generateDiv(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + 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; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateDiv failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateDiv failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + 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 + return 0; +} + +int generateMod(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + 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; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + 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 + fprintf(cg_flag, "\tmovl\t%%edx, %d(%%rbp)\t#mod end\n", getAddress(cg)); //stores result from edx (remainder) + return 0; +} + +int generateOr(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + 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; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateOr failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateOr failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + int label = label_gen(); + + 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, "\tje\t.L%dor3\n", label); + + fprintf(cg_flag, ".L%dor2:\n", label); + 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, ".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 + return 0; +} + +int generateAnd(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + 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; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateAnd failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateAnd failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + int label = label_gen(); + + 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, "\tje\t.L%dor2\n", label); + + 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, ".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 + 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; + } + + 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, "\tnegl\t%%eax\n"); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#negation end\n", getAddress(cg)); + return 0; +} +int generateNot(Instruction *inst) { + TNodeOrConst *op1 = getOperand1(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL) { + printdebug("generateNot failed, NULL operand"); + return -1; + } + + 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"); + return -1; + } + + fprintf(cg_flag, "\tmovzbl\t%d(%%rbp), %%eax\t#not start\n", getAddress(op1CG)); + fprintf(cg_flag, "\ttestl\t%%eax, %%eax\n"); + fprintf(cg_flag, "\tsetne\t%%al\n"); + fprintf(cg_flag, "\txorl\t$1, %%eax\n"); + fprintf(cg_flag, "\tmovzbl\t%%al, %%eax\n"); + fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#not end\n", getAddress(cg)); + return 0; +} + +int generateAssign(Instruction *inst) { + TNodeOrConst *op1 = getOperand1(inst); + CGNode *cg = findCG(getResult(inst)); + + + if (op1 == NULL) { + printdebug("generateAssign failed, NULL operand"); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + + //add option for constant assignment (should be easy) + if (isConst(op1) == true) { + 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) { + printf("failed here\n"); + 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%%eax, %d(%%rbp)\t#assign end\n", getAddress(cg)); + return 0; +} + +int generateGoto(Instruction *instruction){ + return -1; +} + +int generateCondGoto(Instruction *instruction) { + return -1; +} + +int generateIfTrue(Instruction *instruction){ + return -1; + // might just be a goto for where to go if something is true, or returning if something is true, or checking if true and writing goto if thats the case +} + +int generateIfFalse(Instruction *instruction){ + return -1; +} + +int generateLessThan(Instruction *inst){ + /* + Both immediate: + One immediate: + Neither immediate: + */ + 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; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateLessThan failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + 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)); + return 0; +} + +int generateEqualTo(Instruction *inst){ + /* + Both immediate: + One immediate: + Neither immediate: + */ + 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; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateLessThan failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + 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)); + return 0; +} +int generateCall(Instruction *instruction){ + return -1; + //will want to store parameters and then update the offset by adding 8? for stack pointer stuff, can then print call subroutine name, followed by movl of the result into the result's cg +} +int generateReturn(Instruction *instruction){ + return -1; + //will movl the result into the appropriate register and move the stack pointer/offset stuff back to correct value +} +int generateCopyRight(Instruction *instruction){ + return -1; +} +int generateCopyLeft(Instruction *instruction){ + return -1; +} +int generateAddressOf(Instruction *instruction){ + return -1; +} +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; +} diff --git a/src/IR.c b/src/IR.c new file mode 100644 index 0000000..ce141f5 --- /dev/null +++ b/src/IR.c @@ -0,0 +1,395 @@ + +// TODO: this is here to bring your attention to the comment bellow. +// check if start is NULL if it is assign it to the start globle variable +// otherwise make it next of current and set cur to your instruction. +TNodeOrConst * getOperand1(Instruction * i){ + return i->operand1; +} + +TNodeOrConst * getOperand2(Instruction * i){ + return i->operand2; +} + +TableNode * getResult(Instruction * i){ + return i->result; +} + +Op getOp(Instruction * i){ + return i->opcode; +} + +int getLabel(Instruction * i){ + return i->label; +} + +int get_index(Instruction * i){ + return i->index; +} + +void set_label(Instruction * i, int label){ + i->label = label; +} + +bool isConst(TNodeOrConst * tnc) { + return tnc->d != NODE; +} + +TNodeOrConst * tn_or_const(Discriminant d, void * tnc) { + TNodeOrConst * count = calloc(1, sizeof(*count)); + count->d = d; + count->tnc_union = calloc(1, sizeof(*count->tnc_union)); + switch (d) { + case NODE: + count->tnc_union->node = tnc; + break; + case ADDRESS: + count->tnc_union->address = tnc; + break; + case STRING: + count->tnc_union->string = tnc; + break; + case INTEGER: + count->tnc_union->integer = *(int*)tnc; + break; + case CHARACTER: + count->tnc_union->character = *(char*)tnc; + break; + case BOOLEAN: + count->tnc_union->Boolean = *( uint_least8_t*)tnc; + break; + } + return count; +} + +static void emit_helper(void){ + Instruction * inst = calloc(1, sizeof(*inst)); + if(begin == NULL){ + begin = current = inst; + current->index = 1; + } else { + current->next = inst; + inst->prev = current; + inst->index = current->index+1; + current = inst; + } +} + +void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2){ + emit_helper(); + current->opcode = op; + // TODO: create temp and remove result from param list + current->result = result; + current->operand1 = arg1; + current->operand2 = arg2; + } + +void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){ + emit_helper(); + current->opcode = op; + current->result = result; + current->operand1 = arg; + } + +void emit_assignment(TableNode * target, TNodeOrConst * source){ + emit_helper(); + current->opcode = E_ASSIGN; + current->result = target; + current->operand1 = source; + } + +char * get_string(TNodeOrConst * tc){ + + char * s; + switch (tc->d) { + case NODE: + return getName(tc->tnc_union->node); + case ADDRESS: + return strdup("null"); + case STRING: + return tc->tnc_union->string; + case INTEGER: + s = calloc(10, sizeof(char)); + sprintf(s, "%d", tc->tnc_union->integer); + return s; + case CHARACTER: + s = calloc(2, sizeof(char)); + sprintf(s, "%c", tc->tnc_union->character); + return s; + case BOOLEAN: + if(tc->tnc_union->Boolean){ + return strdup("true"); + } + return strdup("false"); + } +} + +void emit_as_file(FILE * out_file, Instruction * i){ + if(i == NULL){ + return; + } + switch(i->opcode){ + case E_LABEL: + break; + // this is a terrible one to start with + // fprintf(out_file, "%04.d: %d ", i->index, i->label); + case E_ADD: + fprintf(out_file, "%4.d: %s = %s + %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_SUB: + fprintf(out_file, "%4.d: %s = %s - %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_MUL: + fprintf(out_file, "%4.d: %s = %s * %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_DIV: + fprintf(out_file, "%4.d: %s = %s / %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_MOD: + fprintf(out_file, "%4.d: %s = %s %% %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_OR: + fprintf(out_file, "%4.d: %s = %s | %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_AND: + fprintf(out_file, "%4.d: %s = %s & %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_NEG: + fprintf(out_file, "%4.d: %s = -%s\n", + i->index, getName(i->result), + get_string(i->operand1)); + break; + case E_NOT: + fprintf(out_file, "%4.d: %s = !%s\n", + i->index, getName(i->result), + get_string(i->operand1)); + break; + case E_ASSIGN: + fprintf(out_file, "%4.d: %s = %s\n", + i->index, getName(i->result), + get_string(i->operand1)); + break; + case E_GOTO: + // are we ever going to use this? + // yes we do look at bounds checking + case E_IF_X_TRUE: + fprintf(out_file, "%4.d: if %s goto %d\n", + i->index, get_string(i->operand1), + i->label); + break; + case E_IF_X_FALSE: + fprintf(out_file, "%4.d: if %s false goto %d\n", + i->index, get_string(i->operand1), + i->label); + break; + case E_LESS_THAN: + fprintf(out_file, "%4.d: if %s < %s goto %d\n", + i->index, get_string(i->operand1), + get_string(i->operand2), i->label); + break; + case E_EQUAL_TO: + fprintf(out_file, "%4.d: if %s = %s goto %d\n", + i->index, get_string(i->operand1), + get_string(i->operand2), i->label); + break; + case E_CALL: + fprintf(out_file, "%4.d: call %s %s\n", + i->index, get_string(i->operand1), + get_string(i->operand2)); + break; + + case E_PARAM: + fprintf(out_file, "%4.d: param %s \n", + i->index, get_string(i->operand1)); + break; + case E_RETURN: + + case E_INDEX_COPY_RIGHT: + case E_INDEX_COPY_LEFT: + + case E_ADDRESS_OF: + + case E_DEREF_RIGHT: + case E_DEREF_LEFT: + } + + emit_as_file(out_file, i->next); +} + +void emit_label(int label){ + emit_helper(); + current->opcode = E_LABEL; + current->label = label; +} + +void emit_jump(int label){ + emit_helper(); + current->opcode = E_GOTO; + current->label = label; +} + +void emit_conditional_jump(Op condition, int label, ...){ + // when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *). + // when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *) + emit_helper(); + va_list argptr; + va_start(argptr, label); + current->opcode = condition; + current->label = label; + TNodeOrConst * n1; + TNodeOrConst * n2; + switch (condition) { + case E_IF_X_TRUE: case E_IF_X_FALSE: + n1 = va_arg(argptr, TNodeOrConst *); + current->operand1 = n1; + break; + case E_LESS_THAN: case E_EQUAL_TO: + n1 = va_arg(argptr, TNodeOrConst *); + n2 = va_arg(argptr, TNodeOrConst *); + current->operand1 = n1; + current->operand2 = n2; + break; + } + va_end(argptr); +} + +void emit_function_start(int name){ + emit_helper(); + current->opcode = E_LABEL; // I think this is right TODO: ask + current->label = name; + // this is probabaly a func decleration +} + +void emit_parameter(TNodeOrConst * param){ + emit_helper(); + current->opcode = E_PARAM; + current->operand1 = param; +} + +void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name){ + emit_helper(); + current->opcode = E_CALL; + current->operand1 = tn_or_const(INTEGER, ¶m_count); + current->operand2 = name; + current->result = result; +} + +void emit_return(TNodeOrConst * value){ + emit_helper(); + current->opcode = E_RETURN; + current->operand1 = value; +} + +void emit_reserve(TableNode * result, TNodeOrConst * size){ + emit_parameter(size); + emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); +} + +void emit_release(TableNode * pointer){ + emit_parameter(tn_or_const(NODE, pointer)); + emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release"))); +} + +void emit_deref_right(){ + return; +} + +void emit_deref_left(){ + return; +} + +void emit_field_access(char* result, char* record, char* field){ + emit_helper(); +} + +void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index){ + emit_helper(); + current->opcode; + current->result = result; + current->operand1 = array; + current->operand2 = index; + // TODO: Still don't know what to do with the dimentions +} + +void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr){ + /* + {[string: 5] + . + . + s:= reserve s(5); + s(0) := 'H'; + s(1) := 'e'; + . + . + s._0 num of dims Known at compile time + s._1 size Known at run time + s._1 int | 1 byte + +-------+---+---+---+---+---+ + | 5 | H | e | l | l | o | + +-------+---+---+---+---+---+ + size + ^ + | + p + s._0 ok + s._1 ok + s._2 not ok + t_0 is index + t_1 = *(int *)p = s._1 + if t_0 < 0 GOTO ERROR + if t_0 < s._1 GOTO access array + GOTO ERROR + */ + //emit_conditional_jump(E_LESS_THAN, ); + //emit_conditional_jump(E_LESS_THAN, ); + //emit_jump(); + /* We need a label ERROR to jump to + */ +} + +/*// * Implement temp variable generator function that produces unique names (t1, t2, etc.) +char * temp_var_gen(){ + char * ret = calloc(9, sizeof(*ret)); + sprintf(ret, "$t%d", temp_count); + temp_count++; + return ret; +} +*/ +int label_gen(){ + label_count++; + return label_count; +} + +TableNode* getTN(TNodeOrConst * tnc){ + if(tnc->d == NODE){ + return tnc->tnc_union->node; + } + return NULL; +} +//we must fix this +int getConst(TNodeOrConst * tnc){ + if(tnc->d == INTEGER){ + return tnc->tnc_union->integer; + } + return -1; +} diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 7dcf481..a0bfa9d 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -17,7 +17,7 @@ void S_Free(Stack *s){ void S_Push(Stack * s, void *v) { __Node * n = calloc(1, sizeof(*n)); - n->v = v + n->v = v; n->next = s->n; s->n = n; s->size = s->size + 1; @@ -55,8 +55,6 @@ int S_Size(Stack *s){ } //_______________________________________________________________________ -Instruction * begin; -Instruction * current; char * temp = NULL; @@ -287,7 +285,7 @@ void emit_address_of(TableNode * x, TNodeOrConst * y){ emit_helper(); current->opcode = E_ADDRESS_OF; current->result = x; - current->opernad1 = y; + current->operand1 = y; } void emit_field_access(char* result, char* record, char* field){ @@ -340,18 +338,10 @@ void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr){ } // * Implement temp variable generator function that produces unique names (t1, t2, etc.) -char * temp_var_gen(){ - char * ret = calloc(9, sizeof(*ret)); - sprintf(ret, "$t%d", temp_count); - temp_count++; - return ret; -} -char * label_gen(){ - char * ret = calloc( 9, sizeof(*ret)); - sprintf(ret, "L_%d", label_count); +int label_gen(){ label_count++; - return ret; + return label_count; } void emit_as_file(FILE * out_file, Instruction * i){ @@ -569,4 +559,20 @@ void emit_as_file(FILE * out_file, Instruction * i){ } emit_as_file(out_file, i->next); -} \ No newline at end of file +} + + + +TableNode* getTN(TNodeOrConst* tnc) { + if (tnc->d == NODE) { + return tnc->tnc_union->node; + } + return NULL; + } + + int getConst(TNodeOrConst* tnc) { + if (tnc->d == INTEGER) { + return tnc->tnc_union->integer; + } + return -1; + } diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 9f99d2b..60b64a0 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -24,6 +24,13 @@ typedef struct Stack { __Node * n; int size; } Stack; +Stack * S_Init(); +void S_Free(Stack *s); +void S_Push(Stack * s, void *v); +void * S_Pop(Stack *s); +void * S_Peek(Stack *s); +bool S_IsEmpty(Stack *s); +int S_Size(Stack *s); //______________________________________________________________________________________________ typedef union TNConstUnion TNConstUnion; @@ -112,9 +119,8 @@ void bp_temp(int n); extern Instruction * begin; extern Instruction * current; -int temp_count = 0; -int label_count = 0; -bool code_gen = true; +extern int label_count; +extern bool code_gen; TNodeOrConst * tn_or_const(Discriminant , void * ); @@ -127,7 +133,7 @@ void emit_jump(int label); void emit_conditional_jump(Op condition, int label, ...); -void emit_function_start(int name); +void emit_function_start(TableNode* name); void emit_parameter(TNodeOrConst * param); void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name); void emit_return(TNodeOrConst * value); @@ -135,4 +141,21 @@ void emit_reserve(TableNode * result, TNodeOrConst * size); 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, int error_label); \ No newline at end of file +void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr); + + +int getLabel(Instruction * i); +TableNode* getTN(TNodeOrConst* tnc); +int getConst(TNodeOrConst* tnc); + + + +TNodeOrConst * getOperand1(Instruction * i); +TNodeOrConst * getOperand2(Instruction * i); +TableNode * getResult(Instruction * i); +Op getOp(Instruction * i); +int getLabel(Instruction * i); +int get_index(Instruction * i); +void set_label(Instruction * i, int label); +bool isConst(TNodeOrConst * tnc); +int label_gen(); diff --git a/src/stacks.h.gch b/src/stacks.h.gch new file mode 100644 index 0000000000000000000000000000000000000000..7600f4d256ba6efcd8071b37b3b9f9802c834fed GIT binary patch literal 1745332 zcmeF431D1R_5TMDDJ~H90s_OH0|D1ci_szTKy`jb3-~XYV&-)nm;#&|Joi)?!lWm^Barpxu@CK12Pu#Hf#!^ zF^{Bb=GRoY0gjTydpWkf9VH^LlRft205;PAwRhm~&637p_^k zylHWI;o|ewHmz!iCyyZOAtq#L^O}le$|S2uU=LMwmB|_keZGxh_MVPcEU2ihuBxl5 ztWKno$z-awI#F9!ld7$(sjjRgL$a#6CY70AnOe$am;9G4UYu@fSe&k|u1haoxxA&h zp*5a7j)HaBQ|UDqwlq-LhjWF#o?NCY-r3te$eHkAkaL<|+OTqIdTH~@g=@+!S@zw!k6>qOL z2`*?_vZj%fa4V6FE?__V{mVXH%i)|jO+{N%nRHK7vU=W&D2&~aPOn_Gq+wOMxoORs z=7w~`iX}}8SMXsZE31yBaM=eRWndq?AO3G`Gw)2we}O5bElsUN=stnM*}3U7`@M1D z`3>pS7p_=rJil;NLwezgCF#`{ENn?v#4C0?Zt_{gt%_GP(*EU?alKvAuwvz^<)}dA z-EKc-Q&Uo^0G9PNvniJVdMPJ;sd?6h|6Sv2T zTCR%+*$C-|^C@U~!&W|w$E`_hCREMZJ z7mHg?kz}`~p)aL&PWjt2j}z}-HO-l%jZ`nYUi;J zq;W27TG6zIt0T39l`EPr#V$&KL7p}HdfLvHi>>Y}~4RSE{ zEKP~B_6k>-V)sf*qcZ~+$et@x)qFzd(7$xrG;HY!ilyPEYr4o(+H2YKyxkRh&}Z~4 zdlk*JaaFM^;Kosq0SGPh7twt&om}Lwywq z?kHBI(8jZ9<;rG%ZEWyLfsw;$;57@XYO86GsHmV(B9%zeMxriRMcZ}N)T(Q1sHsW|;WXAYtJ4*!nwpAqCD&)JGd!xN)5Ezw%9qcBjK*9f?$6DslmV4n z*;?*jycS@_PXEwM=eA-V_b~o3gCfwb*0O`WKEkH-&T%=prLtlkw@*IR7*AT$`a~Cd z8n05*xNmE9MGcotx;Gig>;cqvbGA|eaPF2bq-KHct)i08hBLUBVwcZPr~QM?{CLGY z&V8PFeB*AM%;I-nx7M6N82$@SeUOLZlOil^4D=5z}eH8iJN zRy8bb;@M3-g?eXztGe&xFG!@SlGLnflU1qe>I7B2szjo;sydlUBvLhXbu`XYWad}Y zEv=~<@s0Uwme6pya`l=9?#$iF#a)8$3|FR-^SFY@XOttsAZseSNTrfhwN*9Ll_XPDiR!w_${OlhD(X@+ zJ)nNIg3n{1$#B=#w89KuJZPEoDFt%dw4FBbBvJ+s?gTgm_ex$0&*ha#pGRaqN_`H` z4$RC_y0X<=m+X|6vf>^^YO92-UP*%*b%c~EnW(5u)HHMLka;ZkIpkq!Pn<|9jyn@c znk@O`)2!IPGt95K{AW=pmldOdui7OSB$L!EY7$j-RO2cuDibMcGPN`)v1?NmH8e3J z-&WL+XNxtuCpVlnJuheO_?!DNT>+eq&J1Q$^>jy9ti5JD3k+A>{(Y@H*g<&RhuK51 z`>3hnwkhXx*^0G`xyTj80VLm-Vb>Q8%a?PfQo%D1Z+~X=M4iMDOH0FLh&k;`R<2z{ zQ+W!nDR#<>nwBkVSiL5_u(@g3iscQ|so8LEYJ*9J=MXvt3u))Y9!0urZ?;^qpti2I zh6abqs#Fb4BdTi?sS4`SYO9i!G`*-z&=py2=2Xh2dEQChQSj)%lSQuqCPr+1x3k4& zw;k(d!`?uh_Fa6@@l^4|l}~aS*BC7gi`O7Y@alz28`3m4UfUq^J*kE02z>o$ zU6mO|B!4Pv%bHbQJFBU3su-VNUA8#wT^w4Ry!npQ9^u;JtjToBl2P%*^3|EtBkL|| ze*Q@a%{_{4;F@wl6U~NKuQsQhtEi;*s&FxD=McD+=tJPtPB&@#=Zc2;b=6Cj^0A@u z^VL61LW+}YE|7%Dz-&i^%H-)@mNEoMMXFp-l}M)OI0~cyTDsI67tM@<6|>kn+xxp}=&F)?Q90kf?Cp96O)4vExaLb`GmX>y z6z4v+LI|6i`Ls!Fv}kkXZ59cf37+k}ytNlI!3(4|YXh9xTmhj@@X%n2VNXy^6`ymj zUq*e!iA|=sHA>*J*4FgGMNR4R8&<8RMis9}RMc>&oOPZ@_@^W^bui08T;qIK{!1=c zxN2!Ky?AL;dg1Ej(!qIS8dY<@bBZG%t>>lL;lY+c-Ii(@i)e@bUd)7e>`N-6p89?ia>*AWr{AI63NPBElpWyksv{17OfU=|5r~%lKM+tQuTKMRr9(e z%>n6pgf7P@w@SWxs;#Z7O433^U6STMluZ?1nk=S#5^vloScMJ z4a=HncD|~35x^~}c%kO2&fLO_F1JoB_RB>Fd!4p_t{CV-rAWKI^jVqYmQyTQ__`*y zLmBVMHTFuOINe&YlIE|?O)JzWLtb(&Woa5y=k3h8&{R=7*_J7H=x+o0xN3>%2xSoF zlK8H|l2z;}Y2LcCAm?1h_sco(0^ zs?#X39JX0(PG3L^w^+PQ$4e~Z^0l)R%A1kP%1m)iPW={jRAzaOy<=wPc3KctJLz;# z$y}$`ag&s~MZug}no?yY8@)?%N+6Rre#ii*= zTASsA5>MIsMeV^3hE#)+W`VnS)-dB#14TLIA_rZZtraI)h2DX|A!oUVS7e?;|71;u zXPcOD@bb7nZ|`OS&C_^#QEYeIXQ`zdI|o?noA+|1*OxEzDI-3iRKxi4fktmyuWzL( zu9@KSa`I}ksDI!+W$Be`*R-sq)hmj@Z9wJ%Sfzqb{O&0BCVY&m7A`SsCrNH(a>l(zrq2ZV z@+A~YdIi(;ef4H{7g&ssrF-Bq^11N$0eqscmP&JJJBhUCJ)ORoR`YpACq*^21}opC zPXCz{+iMzTMalHsyFYoL+3yHn)Y!4wTRgY*$o4>SiWFGmlBu|}a?f#O{8OF6qNRKz z4;=!>kfXHI15A$1WR%aM_(}R;S!*(PrF=tcpbB#m>3?NDXRDR3)1xIfUsE-ppw1iuOtAC!wn-LW&i#;6w+~q{tlU$aYj_aBFtkiKKt*h7( z1Qy^qYdL)~l87?`(~JfhT$d~#c z8op!ab>zO`B~aDfJujm@^W}}SaXM|}3+FJNri!j*Xcab5OUuG^1C;KW zRMPTrT}4erC9QT=QwLS_tncQYJ?6?JpM2H1tF}RXJJ&_&DCz8I?^8Grx5`an!xm>F zLxkzwigQ3-)vQPqXLCZnN2&PTt}3s#D2!&G&2frhmBQ#1&C`N9n-=oe7WI z{idxwG1;S z3Uyidok_leJ&pDf92L!wz_*8dRZ)D&_lSx;Rp&rgCf!dz*>s`5J)7mRh$|{LZf6pY zbsO(SJv&8qYio+v8f$rZ_qis6i&LB-J3{&tsyTdC{R0A3>SCY6!;G%={&^GcQR)YV zba^a=@+eN!@_n7O(q1E`}^$c~d6`WRjEnXS$wI#Xf zDE%HLV&?LX`x&ZVH9YT7z2Y;SAwD~yk9Tm@(>Fq$fz>oC8t`e6YsnJsQY2JX7}X za?0UJmnwB*_wRR5=TxjdW~G?VRk4>fPP2_nMo&3Tu88UZh}v$h$Kpya*lD9&kNt;J ztax0@`CuhA`gT4TuluLP$zmUm`bB%OwM&gH;dlL|`e6|8<<0kMizgTB88f{^e6(|vv3xO*%iJ<6FR(>o{`jhg_T2fa@yTnf7BF;>jsn$7b!49;Ze}*Sh;>m zgA2I@9y5L&ZCMP{oU@GpU?jHKDGn zSik8c?B4Sgl}X-(oM>($G}&;T`{V4TzL=8nQxLQx>Sv1egZm5dk?m}JEBi}ZSFhse zTvTyB9f&;gVs1R|_T61xpjb+o6vr=LP4SxZ?)RQ@w^)j_=t6qZPsYrWi=6Bt**6_8 z*BpDWGDj`0_mX>jYdw72QkCeq?WvOmh26jO;gcZO;--%%)>{scLr}NcinFyAdi0q_ zxsVH9DyV;+=x_XsC|{`)I9onn@4k!qloc22_;R^^kr~($Je)fV^oyow7Slw`5 zdhzNt@oH`_j#G3^q=%GwAd}N*ue|)(`&(9mV#-xJ)fgJ=ceVItXWqUs!PYeI>a((n zuU&oaR3$VIa&iVTML|Qu<*hs~#{S_L-fbXv)TylD0hm4ET;etBOJrx>NG&N)--~0E zbiV$ftuAEkl}>5t`pd(;^c|)WIX&X;Kk6KMWO6Oydq9+DY2sl%!x&w0lD+fGuZRRH z5GO^4uTMp;&rpcA$O8 z#IjqIST<|0!Rd^Jx&v%+dSjw_7Hti-cT!f%@Iq3$slUCaFV{Y}DVAO_Fqjz{9?Zqk ztJ^6G9nlaiaS^dTGjQ(PIMqjZyvzc}}WwtDx zR5#lPGwI9-HLzTduar8(U$S7BuYiF-UpWI|zTyVL{H0dKOjG5xhY&2fwfKu%wE2qa z8GS|cY`&s-HeZoEo3AL{nZfqHLWY7e`JrM7&B^B47-I65(ThjVUWY~Xm9iMsSInZ( zS56pn!JSj}@HGN2Uf9klYH;Ud4DOtaft}~tgL`LNaQ9*j9K10H3Sg{(5*TZs2m^!K zp#y`#-LoyQb20{YO}4;}$rjjcVYox@mrTJO8)IP4Yz^$1je&i$F|hNI;6alqxN~C+ z?3}HEowG5pb2j>R-WS^G(U9h=fvo%m5$!93G5B_Gv~SNw`*v!yuO*sVV5)S{|3#aB z*M6(706w#?7(T17Fg~lVNaPh&0BiB@zG(C9+%x)i?b&=g_H4f0^5Z7$S=x23)7P69 zhG@_)y240*F<|hOK`g!kh{3maG5B}QJMnkTTrHIkJd?9`8_#Ke#i;&Lcv1Z&@r=IG z3}p&KY3^kTnW5s556SdKxreK;DyV1j7u09;xvFUO6|`vd6|`uSf({M#bqo*5iNUr^ zV1|bV(nFi_9MVzP*q-m|U$UI-V)a^f~?QBmOw~e3mY}ie6!z zZXfJ%N>k|L0nGC)NyoLM9pAGKL~wjfFTxscgxBKor7O@boTqJK}Y96-tR!u5t=Jx?;ym)y|O(lW8n*B*TUDyMaw0b z!2zG{blV9_|ADdg7n3?or@h*XnK+ z?xf1)9M)iuTdctzcL!8gocN^O1YF&840RkFC6KFYp!4ozqACvcsZ=p^47D3wcT6H@ zHyuvb*GbYj7Sc|1bq+~7(e)W*9f+VababXqOD8=Ace|CjlTA+5g~i{i7?V?*VbPJ? zosak%R%d1;@0MjG-{r$VxJ@@0dQPnK4s`norH z(;)OlGF!=0Z%&=Mzogj#Eh`c#ydvT3l2TM8+L_-w{6uq>y}O0&EM_) z^UfrulceJk(oX99;DB?QSi1?x;HDU+`3o-z7f*GbOwJLJp)j1!({#@<(<-i$6>Dc_ zY;a??UDRo#y&>R_D7JJL4asSmOXvL4 zB$~kca~03@r`X`8aM~1&RZjA} zGjLF-J8l?*Tg1G7mPz5xbeXk^PMxf~M>5C+kNSj;_Kv=6-;jU4OIbKB8_BB-`*|hT z4oeifze2_DuW(ZgWoTt2q%MrmMDUvtyQBZhvn~&cwx7oDQ8W{?Zv8 z%*GuuOeAx&%R5YC3g&EXe>su-N6v}-!$WshpTBLgbjn8BNltZ-ZlHK8{MO~&8EW>K zoWB~1$=nL)&N`DH6EZk3Y*xjKIrI)>yFxN{Zz&X`)8dKVA)CT?NFl);@(NkV4u|v9 z<})hqZhzO(-Ca;q7P2^QBI#%z#r#dO+Zc4^5u;mu#O9u6V{=ZEu{e9o4mgViwBRt{ zbXsCi)y_n6_YaeQ>LE$pBAIBa>aoo!Q@_7U@9uAR4uPa94O!f>7=u$1vbg0i1{Fn> zL4}T}Qj7$PF%l>TTLSs$l8jKk=(Kj z_?JYw=`9AgECXFm^npSDqG)%%6PGLg-clCof)@G!8Q&Im)?m8x!$bZ-)aX(Xowi5` z3!xEdU5r+H0;^uQ8SQl>)S3B*KMHmS8)I;eorb7V14NeiiyT%k|LE4cDL>$!X&CL4oFn*i>1(HFi>T7j0@C27k@T=rbRFmv z)duGM?Z`9wtE@E^!eTlrv=TE@=*o1uuJr{_!;^<)yfNPf(k-y?R1{D;RbPLJR2OG9 z(f56MRU&+cxvpHuv9mRJ@VTzgsKJ;Wg~2ZWf{ZyfG8O{H&TMyf*jZ~dacLnnvp%>p zF$W4}%)#>_=CIg3nb5q+92$ElJoZp%>}+`6WDd(aOVz~JPVK>yIW%^7NwOtMG8CTo zP-xz{5)Nm3SXsy(nmyY?W>{PKm zygcFVr}&}%85j&{T~vkH9+p4ZL(9+hu=vBdQhSh)l4(NsV$y`{hwfTs{C&ApXtJ88 zwCo5~wEFvb&zkj5x{KD(xK!N&?T2M81R z!d=b*;VDWvSG*oxu0n}Jp$;tcSi1T)1S>2X1O6jp@C30j5Hr)?AFy@Pl7q8qVQO?Y z&5!tjWp_r^O?M4KBNv7W{+s!d#mFE(9~8(#%t0r0j}+RSMLXoe)?n;xSN}+7A&`64 zKGx&(j{Iy`*ZN^y6gKw;oh;^nqu87ckDU#k6pl^HC}F!C4#w_pFI-HI&V-Z^A%U)l zZaD>WXJeq;WDHghHU?vcI*+c&L-s_*VEVpX$ezd;j5)BOH^gb=f^2U{z5^Tj3m1nJ zLhNC==cvQizNg%CLxJ8zticLq?4kS2h0IY*?65tq54rxJ$RU0rWAI3ZLuy<<8N*_R zvGB1txe?3ALNduNDvx5JTgCM73i(=@>sajSF)82ghhMth~ zPR7t2HuQuX9T~$ScV?+gt`9%W=E6C+UonSf#+U2CI%g7udd7qV3oGUld*~SoEfSea zCI~H3&rqo%^$dj;iOgYp=%oQVxC6F^RC+cCGw-FRg+sC+YgiU!4rb9$8HYyafQ`Y- z#T<4#JidnIPu3FA&3giFOQ1}KL(c~d$zi#(H8gknGaA9uO_`L)-3+TC3B(?{hv97R zU|5mJJ{;l)V=k3Zc>M4q8_s4!qi0J+9}elEsqvCItT@5xD=i^}MJ%*;h14fw4UOJA z+#Pgqfvmww#@628L9#jI*x4KsnR?%l{gE|fe`F2GA)5_}O2*K`BYR+?m8TnmU45mZ zuP+r698f8r(38dX(7l$-JM=I^YYyeTF*NUu;pHAQ@4C3nxj@Fy!zX)4-fS%qJ*3=& z?cwDnduZOJ${lu=2TPn~vWMke>MT?A5@%vC8*-M(7=HMnXPIJ`@K#tO84T|q3S9t%0b$1=VIe)g4Je(c#H>ydhD-@;K*=1lrOHkLr4yAZ zJ2k1&iJqzK*-~YvfUq3ty`{kHn`|Lb>2;al#UvSnSE95S-|xTUZ7!k)yM_wkM*lr( ziAt}jXZXn)y89ixfFB&l_68a=8G~cQ;J{#5%)yYD`hi6$2U|mqSZ=5r(XN8GFcj zkgL9#vHs?BIfYe zA$Lkl^ssw32q;mUu)8-%QKCp;_ivCQtXQT84?13Y&Y zike^p_5zd6!#$=M`@#bKMlmdSKf(*E3icw!Fz10scYjsSkY_49Pk!1hy&>f02=7n= zOO!?eQ{k@RWwUglyDzZv&)M?3nj1>wYQn@?CkFVsud%L;UFlrb-7Eo-rwfmPosi);UWimB436S$eOWG<>fcJII-VPS-qG zReC_A;X2sr*yuDNeuKzA(wjGmw84pC9)|SC2s~-oXDm)4dauTrv$FO-mej`vCk3sB z&^oh!KRJ3>*3nJ|xo$m?A&dJk6B*obHRn8+PLB+#rw`epvrx}La+E-(?o*Hy#W}KE zw=>!2rXBjat7*FO9soU#pDy%Wl1UG>)8ANjoIt62Gwu0w=v%QSi|`PB)!UzudG%Wx zoO0{uiTjMfISIz%Br3FLbNtPu;+;jZZ#+tLeF4(-v7!7TQc;tvopQ5w#@or=h44D^-7Grg-wqC*xslQueY?Ur8~iN`HLWkO&8_#wqzX^5 z+`^N=Ej&FoL!ZBLc4r=ubuGg==jDjLLV?C5r;-=UBQu#n=KMj=;4jQW89bz9OTB}QEm)5ppjrH0;Y8dpF`IQR5OIElx<8iVtcu$Y{EhdggAv4VNKPaJ2pV*;KDx+drwISzlRLyk4%V6&=o z&l-bsWX9qgMOOFkl!{+jQOVfkq;uZFrD5E8m&#}-2mJ~z$8ahDYn{Ta00TWqzfVZ2 z_|Dr`JhO14J2MXsR>z}qb3=1I>zpqY1bnRr(x9gUjt=_SSo}NYzpmhXvw}a$((50^ z*x-~*3~A@;R6gb6a|apd`2>G&OBVi+iW`R}{CbozJ- z>LnnKq>jjWAumU-*L7@iXQQ6Y@wknsi|X0k6X-KLh4$=j$$jR~=*}_lii7*bjU1WU zyWNSUXLAn&5p{+`1N6?Xzd3MnG3xYUbut*>SB&U8U_Apv{ug%#I@a;4rhM_>tN#P^ z`d((pd{ookw4$#*r- z%-2ADN8-MbPs$m7jP^Uv7~H)%ukcg2|3ZYNO72`PQ@E4aV8(t_%yX+A4)8IjkT=5A z3t=q7UYlY&eH+*B1F@8d?C&p1y*g$-4d4tf^olxtai+_eUwbycOFX0B5oBCH?5~Dm zQ0XX&n@B!V>s>1P-br@f=^&rFYXNG$qkV3)+gTfv(_g^iZ~MmN^b)Y>NX}uX_k7Jz zp4pJ`k3XKx@dzj6h^l`pMs~~VMRz;pVsy9UUUYZ7@uCNgAyBrka=BxK$xICrVhff< z4HG7szYO#=Md+u)*d99en}8A_^re%G^YJZuZ!zni78>n8VqOTbvp}7yvWhv zEU&<#rW@AkR84DiPCAT^k7Xy0x5(7j-A9M-9|<`vtU5i+ZXS-i`Gau&PLLK^)K_7| zqOx#zzD4e96pEXq@xdE7BcR&qkJ7x#d0n;Ifiq&DF*j)lWoqWBpV8Or+E$y(wh_Rp6F$K z6{UNqk3UE6O${iYtTUpLfj-a~av1#CPB&pLP;Rya3eMm4R0#tGr57PpLGvBXcLJzb zgYIQISpp6qn}1Iws*2C-T-wr~HrNnyfo;w1CAPJyi)?Gwm)Y+3nAGQ()Yq6;`db`p zf1@DnNWCOCB&%&cPl&}$)ZaejU(YW&C=Lziy9z@CdaZV7K(Dycg;g+8U|p8(sQ7E_ z&>*eu`isrl@q{tBosUW6_CD6+?|#JQ^gq@Vh~_woz9n3sH5dBY|4<*@GjeLoaEYlE z+e7;t6A&I!Vr&~OHMW_6@T}-BNzgZm)g7*3`GXXEXUFGaSg98@f2P9g7vxhmeD9iO zL}c}!h2au?Fx$fmRI(4I zXBNE4bRh2MtGSBHyNlQ|-_xd#8=6H#Ls;ZRVjA(O#GRXZ()8sm`d(Tl-A%2Pd@oBk z!2tQpGQD8g)yXMogVr~P`gl^qZ(UmBklh$D8?wXiQ_F4S2 zHw*9k-z0or{Whu?wux#D_oH;B;(bcK5HOl)c9@x`)**JTBOzw4Z6W5AXQn~~3*tBW z3gViJ1##@ff;i@4K^(JJkPi9_NHXluUk2b3@yG0KDMJH`1uGHk6)-&9D`a=8%H0J)|IP4k-wmy@K#( z&8YvTPb8W*Fiko9wqh|{t5*ug>=nYXdS!5|ZV}Yq{wS8iAD{~32Dv42!rWpxL2lWc zAg_R?8V5RO*IF!^wtMAL0bZe$-7Ar@d&QyC7buM1RxFBZ^$Oycy<#|4uMm#aD+1T$ zKp7lku@K7amBO`q#c<7DIb3tGAT(b04i4nx?wF}H^zpZn<5yT%v83UlUV%e{y>f?! zdc_Y7^^SsDWWb${u~pVV1XHfLBG$svlj}qZT@y6|M7&F`D-2WOR300ProokP=2&c>oNus zLcjFqhGOPVZpa_npp|~ULu~#4Q3p-OFOGGXzmw4!Gk+gL{wjw2Ee!b!82Gyv@~12) z5+8mym=!Y2Gb`p#Q}7Q*;6Fpb>va4>2X21ZZVp{wrHRN#Z~oqc{Bjr{4`3zY5cn@a z$lrh9Uoue1%nwC1=g9m*NHG2KL(uZ%v-#zf8nZ!nHNX+spoJJ?;N@T5;AHgtn*3D- z{v`w7oRvR+V18*|d<91V^r(^fpYvGbPQTQgH zYvHmwQB0v>=^CI#4>}8w=CagN{4jS(N%_KG#nM3Z`4}=7%DfyYijp zzZNVVi& z2ueaK8!LV^o?c&Trwij4kuT&0UBo;s{m?fmH^sb<$#?a&(-+ta^oLqwT?6!gbGG=y z@iF+)T7 z^D8#`hPvqhxr)<2s<-BsGGakl(TC2>kFij{Lk6>Hw&)Y(r1`_-25h4>mRyV%L(Gr4 zmB@;pS2Cp2&+L|8ZiYr8*xXn)1{;rSG#j$?%U&=a_m)q3^Dmj5&v$zt?be^__I;qc zJLCH-xBK@!yEC-p!5_qujpB#5jW##1DTpV5_{es5rub=Xdg3NV|I7n0L@Jv3WHugI z7l=d5L+r*Svc(5$w#Y4pl$KYK_?OP4`K2K95Ug>T*YKx_2t9Q=2vz} zEzhJioFk`-?Y(9@1!&j5>tz;~@;^W7H;tu3Shxw%kj&YYmV0Bi^{19;u z%`rN;`ODS_J?@Qd*}%7qdve1u^Q>2ocZBlsUwrb{ARFtWeq|^|T|-|tbvN`&9Sy-e z6l;DVC??*x>ErKaQWE+k+%WwSY%t9aqmkg}Zm%2c?5+?MI%7ZFJD#SK>-*)r+aWYWhF?wvDAJ*qb^y$I;b<|JtL-_RQJwI^IkJ+1N$mIcfJQi<20U7#| zygY~wP`$B_uY;b2qMN$Lb<3p7F*lGicLeAaA^F?%xdFO_q&eIG{~6nXJl*f-i*oy?Be^f9f0_1}xy6?6 zq`zx3n4wu+CqEfTk3<#di2-`ZG)-re{=Oe?aUL{1rEPk2RDO#Okn(Ji{?Uxa{B{en z46{vJgY7*uHsTf-Zd-UyZIa$VZ;?^(zz{uOOINOWnxWBTEk8_ub~jI-<+df^O|K~Y z$$x%+vp6=e;tK}Q381n&pZYhGReDO3-h(m|NPh1*N8kJ>1HB$d-^~;ck)kK)>9H^G z(ahpjcX2bzoBWifeKu3bX1=py%WQANkl8$*DJZ1v3AB1>BmZSlYI;0Em=*StZy=cXyY=BY`e&0~>8qh#nk(a5>_1m)x@&fh0|LD&;{gu{zD za>El7Ph(`u=0e4VDI23d1XsLhrrV;~_CdNmJ3!SYlcvu_lmFS+A-~-MN``OQ0VL|#0oT&({%$y?d1{L{F**cwwz87Pus;n)8W`{IzYQg2Zl}BhkY84 zH>gGn;--4?wtXzmw=IdhNAPH@rc~x}I{}BYq$1NW&Og28M>dU>f2g7J4=ww6s}SD( zXxzq&nX51Up-BA8y_(tJqhSM|EwjPL#0EZByg_>)-}3H@xtqVL8N<_2_L(SiBTyb8 zGMnULx*JGi0fWW@28{&_euRg}4+Ig+^GZzfloD<5&3=OSM3QWq{LIrwMoU&Xp%4ALJoipdi<07a0QL(D!*V;`Zh56*ax%g~0*cKnNarZ1#2XJY1&75Sx1 zy{BPhi%y{37{L~uLNW0JLS*{HOeO)oTgc!3=Q_!t{cBi*~NLv^z z>{Al-I!BH=bow}D7eBAZSN?3`KV!L(*Vs1p^6KPBswPdxOAk`;;}iVQ1U)Lj4@mH1 z5%e$wKLWuIKJb4}<3A(lXAip(!e z^%H-3$zLvy#l}IKu>PK%#%{I86CN>kuY#VWbh*-}D1DmJ3zTkq)Xl#`=`N+amF`t~ zozhvQb4rgX{YIs4RQfGSZ&CW~O21R-cPl-v^vz1&qV#P_Pbhtd(%y;0#$6KbneS10 zTIp{o{T-#fjIi-N3HR#DcBOx)v`+tHmH$tbo>BVeNls{qP^YzUgy=)l^b)0) zD&45`IZ8Jxy+Y|Wr9H=EqeH?ybC=THO7|+gPH8VAY-A3fu(RQdx-Ykz)7!aegxl-{cJ$Cdu1(q2Z` z__Tz3=W9mkpDV4?Kcw=1MClz$KdSU&O6&ZekZ`YjvB%u@y{FPT{c|MTGe1}9IZ8iI z=@%&NWrU6WB-|@snbHR;tXDQvH^eUy-D1E+YulyG%-Kw-#5Nuqi!e6TNMM}R+>6a_5^M8d3A65D_N?)P$ z>y*Ay>8q69tn}4NU!(MON?)(^xY9Q%eY4W~_}{C-Z&CVIrEgREeM;;6Csg?DO5dUM zol4)O^xaC|qxAcgo>uysqP=2%Tj}pA{e7i>p!AQF{)y5*Q~Cj=9~AAikB5|gSm{TU z-l6oPNg`a-2IQu^gerbV2E1r8g?QN$E?KzD()M zm41WLZ&LcrO21X399mHxKU-%FrAYKBE#hTH9=`=kI={KdbcTmHwjAUsC!jN`Fo1Zz%m6rGKaN zAC&%+(oZV=7p0$4`e~&Pm{sjp=|hx0OzFdwK2qtUls-o33Z*NRu2#BM={lufqV$2s8BR(gffZKAzq)S+~j(%mY3uhQ$3&MKW#dQ|DxD1C*} zS1P?(>1&j}PU-8F9#{HirEgLCHl-(&zC-D|l)gvlDWyN7^yifRg3{ZR{<6|v744nh zuPZ&H^v{)kNVL~~J)-mur5{!LG11=spHShk-?jnXO6UinW~;b$m)meOr1eTNF~Qo38|UZvM5ofYksFQ>xCRQMZJ_>C(3 zEh>DA3V*u_f2Y##R`JJG_{}Q(78QP*3ZGEncc}2YRQNqgPb>W`rN5)}_mtkQ^beK( zvC=5l=|h#CtMm~{zeu!K-lJ7` zLg}Q^RZ7<=ol^RArO#0METvnNUZwOJrO#KoRq2;1{W7Irp>$g5Hl^E@?ohf@=`N)+ zN_Q*Wqjay*eM+xW`eLQCO7|UR&N>3<#hthY7_UiB5 zD*PU$->>wf()TL;0i{1E+S}iURrp7h-m3J+l>WHVpHTXfN`Fe}Pb+<&(lbgwp!Cm` zeo*O$lzv$0M?`!6*rD{JD*msOeoX1dm3~6Bm;bENzg7D8O8-&mol5^%v^PKbtI|&? z{WqnbRyzJWx4%ACv{(M)l|E7Fla-#Q^r@n~@}8#j0;ON9(pRYPN~Nn*{2HZGN}sOu z8A_j}biHV={0o&{r1WB?8$^5lT&8rB(&s9@Ty&=I($_0}gVJM4zd`9YDt)8UZ&CWKO219%w=4Y)rQfOayOe&n((h4vO6mKR{)}kv ze1A@be_rV?D!onVFDdd&A=)eN zqbmGqd2ZONe`Qa){nLR;AE5L>N*}EBAxa;r^kGWRRr)DazP~AbxQc(I(nl!$m^%K) zm4AM%^d7%=uW$EKdT*uoQF>pcpRe=_mEK?JW0gK$=@XScS?PI7pQ`kHrC+S{deL6} z7*x8T^pMhC#VfHftm1D_dZW@KN^es75~VLy`bDZf=wcnE!jD$^7^PpS^1n>!S1EnD z(xXbhTIts){aU53Q2KRBU#av}N^e&BYNfAH`dX#0Q~LEvU$68HN{=gjlhQXU{a&SS zQTkS;Z&UhxN>3<#yV7?keW%iQDSfxn_bB~-rKgm>U+K>%{aK|yr}XEQ{({n9RC=4z zUsC$ZN`FP^uPXgDrN6H9HfuROw$S{g~2^ zEB%Dhzg9Z-2Y0;PL+L%0-b?A{D80AR&sBOKrRONUuhP#``uR$~KPFZcuuu z(#w=?RJuv&bCf<;>1L&uE4@PLl}fiLeV)>*lwPg$8l~4NeZJBcDBY^`g-X9v>5G(p znbI#;`V~s2mCh@@Ug<%l3rY_uJ*@Nwr8g=)qVy)EFH!nZrC+J^WlFzF>C2TKSNbNU zZ&v!fO5dXNtxDgf^!t>aQ2KVI?@;`cq1OTIu_go>KaLr9Y$eXO;e((w|rQ3rc@c>1|4XN$D>u z{S~FZs`S^C{<_lNP`Dd5P2Z-K;(hQ1Ca+J4@4e_JP>&x@<8N)$ODlFA`e6! zh&&K^Ao4)ufye`q2O_Lg`AStCg;G_4ZA_ zFwet}ULqWO@L{7Tz$tJ$I1A2sNaDr86xagxg4+M1ux|k;!EN9SxDzaUSoTv6)`P8J z9^4F$gImFAa0eKBMDm*pCcs9p4IBZ-zzJ{)+z!rybAADTfGMyA>;*@`E#M@$4V(dY zf@M2!{9rxU3g*Gh;5fJyoCbG*v0vi&!35X{wt*wy7&rk=f!o1ZaL%JRelP{LfW6=- zxCNX9w}CU@PO$7(IDW7mYz6b+W>D9+NJk!sJP>&x^1%PL2ga_Hzk{_EoB`)tCH4f^ z3XXyk;54`sjBl27jbI+!0#1QDz_P0)ehO>@H-nSlb})90#4iV1z!7j9+y>5qbFY7p)0ZxOu*C;2$?4(>noJ!j#@V|~G`CP%h;r4h5d+*s&M|3{*CE~ZfS@J&( z`%PiLn@iZok&lj_$9}baszm&m{p4=|&R6@5?H_J0`+$^F#~;CdwLM-Uehci@Kch(B zR>D47!oFGg+2%7=BL3XBxqco)`oyNwf3q|EHMR6di{v1be~ zl`gVJ9*8^;c_8w@|7{P9*BygVjy&)Wd0^_f&O9pqHq=|oG0`)-n7{05elu>7>gExV2CX0Q?E~0QfNYOYm{g!4tr8@H8+1R)Hz78C(Ijfaig0 z!1KXY@TK5I;LAZ<&NOs8*a>!l-Jp%%3w;UrDi!`3=qtf%!0W*`f;PXmK)(Zgj|#sT z`Zn+m@E-63pv~_i&>sgsslxArz90N7_<8V)pv~_~&_4!$20j2j2tEw{0{kWTEAR>M zH{kEVKZ1V(cY=2RPeT70{0sP3@Nb}v|1|UgdrQ4O1Uwu(5~i&jRZ~8-EdW1Go%q0?!4PgDb)Fz;3V?TnA>s9GC|O!C`PCcnSC_ za1?wk_&V@v@b%yuz&C+!2Hy(46C4L`0Vlw_z)A1};D^AEfLp;YgI@)w!S8_E!5@P& z;6vaJ@G)=}{5`l6{3{s4c=;S~4!9q9Ab2Qv1b8%f9C$K#DwqJ1U=>&crohv|Gr_aL zRiLd$=R>~~d_ z1b2de1!Mb2fAk!14)_Al9>)RDhk%EJM}x4R`~1Be(^8CpZq?0#1N;fs^2e zz^&jX!71=_;1|Gc;FrO#f?o%x!Eb@~xc>nCB={7##~i5#&joG#=RxlW9tfTUmV>8& zr-2K=Xt^&^oUkbhg>;SvLbzlx01UG<}fR}@>1+N0H z1#bY~1ilq~2lyWFCh)!Bt>Eq8-Qd08hry45p91d(KM#Hh{2KU8@Vnp-z@LCW10Mh% z1Rn->fRBQYflq-?gL~{L^S>){3ZA(_!#&EI1Bz3{5|+b@K4~A;9tO}z^B1IaDBWNxHq^D_&o3h z;C^5kcp!K%cqlj*JRCd{JPJGpJQh42JP|w@oClr?&Iex%R)CdYHCPMQf#-nD;0kah zcpkVKTnki-<@Lk}0z?;F_z}vyQ!F$0Efm^|kgP#OH1%4X554<1zEckiwi{O{Q zFN0qNzXpC2{0{g%@Q2_}!JmVVfRBPtfV1Fl!QX*Tf=_`lTz@|YoC7`|JO(@-JQ+L{ zd@)!FR)e)*9rzOP4Dd|wEU+G21TF>}z@^|aun}wm&jHT`*MS#%gnPtHEo*8^D*LAL|DPz#Nzd*Moy#0UQE{!Iy#;fg8XP za3lC8?ElT++rW2&H-Wc;w}W?s_kte=KL&mk{5tqe@Y~>b!S91V0DlDTiR<~jz~_K_ z+v|Kg;RT-y`##_ta9{9w;Pb&3fSce4o82YQmx8YZUx@hof%}7H;DO-5;Gy7L@Cfil z;L%_lJPteoJP9lZPXSK@7k~*c308qMU;OB#E-(Xb0xtzG11|?(16~1M32p|j0j~qE2gkrS zf;WP10k?qf0N(|^2fPV~!96SX)4Xg(jf{Vb#;1aL_Tna7&8^I><9PnJQ8C(vo09S(Nfvdr_ z;054?;6>oe!8F(oc7hqO2kZkc2K&JQFb}Q=2f;nD-ZBI|3?2;o2I!688JHK1KyLyU z!G0<9E5Xaa8^AH}4d5HWH-R^TZwB8AZUNs0z8$pV(%;K>{FCzed-orui#!l{Ao4)u zfye`q2O`Dd;P=3*aKGg>;OoGv!BOyL@G9_H;kMJ~ zn&(=|pFGSk{}R!2&k**WDV*L6R=-vil*;3(Fux*(efAg856K4sx zgQI7Qo`t_-)uLN!g!a7Y^Ig79!rOi>{@Dq}a9*boK5{Yg8y4;a8#jvHG9t9^rI*)> zo(4x2ik`WBe{()2n+`IZ(+m&DEo-F16N009x^{;IwGk6cwvaLhf zuceJ=nMg`_BWUfGwx6^8n6=MdDe2~1B}{b+<5q($U@tfdZn5D=XY;k3MEEwa7x8AG zcYrz7FSp%zQaECM*YAz|rm(n(z_mac~NMZ8i2Ef0LwZ1oPk)a0)EDQR1b*HgFQ$4#wUr@mjzUa2(tQ z#(U)WXQAugBI$a;F>ot51I~G?#A^jd!3l60+zH0FNc=pw1>D{*`=5f|0hYZ@;%m@d3~W04@l1oWV4_#-qu?YsW4R1| z=o5~CQ{XHZUnk)$U>=+VV;4(!0&D|E!EtaJjAaoYYy-!@DR2fX>zDZTU>+O?6O9r+ zW8*=W<**;H1Vv|J(vf}8l`?tLeE$`+EYE42gkuU(#=|p_S6E7f|KAhI19$m zuHs-l*anVTJK9kjI0}w~Q{Xf>3%1#I_-}4^wjRu2zyB=SeE(ZGfp#n@)V;pM%V~sM-jX_U=vtS(KSPM7`PJ+{54C7YQE&_#2PeTPa2lKeXTexE$^pi~1XvHYfNfwN90kX~ zDfn|7deYj#X>bOd1!FxZ2N(wvU_ICZwt;zY6dbd!|>eD!Qi3b zT+k*sTxn~6wmcd6%mYsa=YuZ>lVBBC1D+11z%#&7=sctpr=Z^Zv>0>z&x|yTEsYtFWKd;E(YguP4A?gR|f(!QX(t1%C(r z9{dCNNAOSJPVhOzXa^C~}er31e&z3(xK0o|B^ZOCf{TTcS_*3v_;0*Wx_;c_<@FDOBoTrDOkHmLb z9)bP^_!sag@M&-ld_Qq7aBuM0`X!1Vc_8vY&crohv|Gr_lGeswlpAWte+#fsuJP14lJQO?(oC_Wf9swQ+z6d-DJQ_R(jDyF5$AQO# zCx8#hx^C=Y@DcDA;12MY;G^KLz{kMH!6(39gR|goz~6$u1Ahq2z)u12HU|-Fa!30ec;7lKR5uc2MgdZxDnh0UJ5S9agIX22D}2i65I@4 z16~JS4~~Iv1aAc20&W4{4!#q7H#iR74Bi6%vqsI^RDKgm-=XwfO5daOq|zTy`a?>8 zMCq+ce_ZKLD*b7trh}l{)f3 z`Dd5P2Z-K;(hQ1Ca+J4@4e_JP>&x@<8N)$ODlFA`e6!h&&K^Ao4)u zfye`q2O`Dd5P2Z-K;(hQ1Ca+J4@4gLzvzK4Jj?fG zwmr-EU*665Uo8>u>m}@^&c$?z_}?mFFO|=CO2q$O345u0wwH+i!xHvV`9$`}1Ca+J z4@4e_JP>&x@<8N)$ODlFA`e6!_@DH^mYd~!=Z(*mzZX97ZufiW(@!2|{$5_|yIlL$ zx4U}#`$Wg@6pq}7@DB>dDkc9NNuhPt)_J056RzEcPYz1@&9@1+oFJS$H9Y>7eUKlH z$L6!+C^vpRbgD}1+fH=Dcbq8uNz}M@o8RVg3Aefww^X?4>o>XS=9D;&Qu&p#&u)}_ zw>~ZBYX-+vDt_B3Zn?IXI8L2@{Kam%diY7lE2YObxW`{A-oM&Du?_ypgHO2S+WI(;l;aaYfrEa|6D750`(cp3VY_}W|p7xuA}-0-prSL^axJ$b0) zvsJ~{x*X-+hH~2UmW|iB`-Ha$d$`*AXzo)o{#b1}dt`Wg8@}a55+wQl$ zTK1R!mAl_vm-N}i7#aQ7=Kt(U6UB}^5P2Z-K;(hQ1Ca;*5f4mUE#rFY=Ksy{eaq{^ z%e~`zu}@(>*86yPynn=ZQQF7@kq06VL>`Dd@bC73y^n0~tJ?ce_I{7OZ)5MT*!vgu zK7+kqW$y>s`#bhNjJ?mXyZ0mh-N*lI_vhVLD{&vl`t8}~YuBTmZMt2>pFLjYE4^pR z`q9)GLaWQp65Vz-)|VE!@wOs-PQBPC5N^}iaGT!7vus`H=4;d2a@h1SH@B{86mrD1aw$q;_G|xxHCSPEv+oNs2wq09V`y~1U+rG7KSuE#w zCuq}8?q*(Zaz0f8n{WQ^7n<-%?5E|p{fw@!lKpH!_>3(FbSuJl zKVB$|=9|fnu_)f96+$-tx&{JU9lM>zrPJ*#N zBON#n&Vu!Sk?=8a22A`_?4#f`82`>eru=zuVxAm-{1o99uf!nJkpB>O;TP0lzYy&rgiIl{jgx(G|)`>m#F-czzrcM`o z3-ky$4sHWy!TK{K{@jmCKJ{QPI0o)KQ{v^%5|*7U+=}oSaLy+rp9DBwFY#KTN5Khj z8r*5a7fJm1CncXoFb{44r@$Rx*{39a3Ty*6gOlLarIP=4=-8(vUF$NjmqWLJJ7J&v ziiD5AJ`QdJXTh>2i8uE?$+sTt1;@axVEH)`e+GKal%z|5t>7qFf3C!zfSv|-g7Nz$ zeIwY~Eb;TuTfixB2UzwQNjHJ`ZP1&+Y1k*Bw}a)Mm2@p&e7Wpz^AClM(0Q=_$70`N z_2(r04(PHK622AoHt0E@mw1!V+rijMi9a$UEQfBfc5ocr2F`+WTO?gQ*b9z<`3ji_ zjDq7}%OPT)g5J6o<5Zh4o|N!b#7jVr--vYJDD0c}6#E$T6gUmeg1yKuRw?mg7s~z; zU_I<3h}QzWZNB(#>jL2z?Bn1hSbve^mj`EI-)#3=CHoz{S2zyV!@kAt7g`Os|FCSM z9Lnh5u1J3#R>re`65DWGyJ8;kcEvG!zIVY<OV??)d-Xze8nSF#Y8NOg*p% z?dfaP-(gJ9iQxb8bA|NF^(^`?@<8N)$ODlF{?i^vryH7=rqi*bP>`NXE;HEI8SCrr z%5;;huRCWpGTA`u~-goxRQN zZ88fl|NDHn=VS8S-^_34JKvez+1Z&L!#HBvG)ft+$f|&3MyN8o7{mOMto(`4TbV&t z!+;JQ{ooM&B({ga;QaZike^_1TIvD{i;GGts|^0vfa8^=MOB8u{~AVkdAK641kPI) z#=}NG@&EZ1Svia0?_h9FS#BQ0D>?=KHH=yK5By|4QWzT05u~5Y&-h7^SjLxj8A9O{ zm4fG@l293zM{q`YRt|(krI2GfZ$W8Zt^ws$R9Xlnm{pNgIGxEzJ1spHPDk;f=h>QFf z+c1iY%Zo}YijCs3f@C~I5ROY8l7DGdDd`4bF6xJ=&@W`09OV#^Vk0M1UbYC*hbuxk zq2<6goK;*}Sz?rA6_w)oDzeH8@~}LD=`*LHj(rFx$ho6j3g#lQm8!sG6Y!78Rr_dhX4Uh9DPw-Ee zWu9LYtC>HMT|@GjFn%1l96uqMvLN#hRfB#KOTPZ9eBv$Bn|6+Fo=3=J*xTEIw(^*8 z5T8kw<9I)NcH}8eoIG)S3UU$6*%+U~8J6kn*=`hbV!z;jAt)jS&s5J#>bMDe$;U|498`BsfXli=7*b`VYVwjmvFM} z`iJF+c>*0MYqDIqR#^B7eWk9VIh*BS>MGl@!}(-B<$2}#lKr9{O8rGX?eWcgiu@cT z`J|4SIDH1RUm-wp>X`B4r>k}#%U$}Dp*(KtCj82Bm-e29vi&6vbsv+mi$HdKR2gQC0#s@Zi+4GQ8jir{v_oW!(tQ&qDWbJjUxf7(ol6+tSCc2*{R2p#KD`Wp~+rnsYzk|*S z{L1qxDlvYzkZ#k|A1H(N5r&3~_v`SoqKceCxNj{F4fGRpc23rF@^tDJv#BjCsxWQt-shrB8w9L1(EEEPE;YJMSf&Ar{Kn}8U%1BoX@i>N%T@K*@VJL45Q8&Cz zLqH+L$Nq=Fg%}So#e*9=#lwCH+A&0b5K=k_DIJF5IHu3Z#@-Hx7!NV}%gHOkfI>PB zSRTiI1lqBKA?RR;(J;i*P)O+jQ#z(&x~h;&SAuOBj+Z2Z1^ZvuE_@F2^g&B|q42#C%~02dMuDC!`RLQy45a3YUkth|vM`ztIhb!6Sv>5km40A^C@9wWJcRxg6$;u$Z0$(2uxWQHTi$L%kC8I0TP^ z9$v?avA`&V;}k+d4of)%s)T_mhsAJxE-1||s(_Ho0YbWDa0u}TV>~V&2-mE$3`Nh`B|~$8*GW2t%}Bh?X3@@XHVk zgrP(@%oia%w}~4>4m_Vhbim~W?5CV6E0h51d2y|RDj2zK0=y?~2 z4*y*vJor^c=ezp)C!lDv|f!g3BVCSr^TVM*E2JPheU9>Op_w?n(8gz$V{iV>k70#ZVI zf)M>+h<-3cKNyBX(4H&Gb1V6HDgFVtI1iXWSc(oPgoG5b-%^YKIFwz!7(+S%gy;@2 z{0H|X(NPLjR$%i2%zt2r^*$di99U5K%gT$OTL%3p=*~fxQkadfNFNsQmWl*R#qp)` zxQKw`8KJ@~9M=fv6cs_3U7S_A7{Z)VpafxVQ2|_^ioyluS)oD*i_4bfl|x7lF@y^N z+QXqN=!zGGD?=f$SCp~8iZYI0QO3u!vbkR>nzupSN9Y>B<&*l6c~yC0dK z%9F!?N2V2*dbC zNjR95T?GD?=H>xC=#Q6|VLO9DrF<{r#|UHog6Y#RT}fUzoK=u#1k?G!C>RVC<THN9%Ev* zWAjw;@g^=YjE7aFOblX@VPZh6BrB&79|7SxtON(>aC{8t81OtfDcP@{WBIIVyvdJF z;b)F(hzE3uWw`gk1vAE^>}@3b`N>v}FZcyf8Bad<3VP-^gSedmA0C&G;|>_&c!V6^ zkbXpQnCT^!`A;6l0|nznf`ga_4&rKIz<9(#2f_e_S-vUEAC4yhkM56leBF_iJauO=RiIAs{)NEY^Q-}wdY z>EjrWKH+wH?&}ix(A8(3kM{cUZ1O%;k@DSj^F8T;C<3fboul=WL0%aEh=eygLSQ;#9`j>wY^Caa951 zxuK3Z zjq&r#c6}Og+DyhDp1Q?Rh&u)T?WykbbfPAKL0|9D`x8xW_=W_<7|YcdeG3w&|ewZykcl*jBx{=5b4{<$3g#M6s1 z5w{8a%&*~6|4rhGd;q&NvRW*GQe2h5bc*dmzx1;)KoWS@$t+3<-Rj3t`F%avi+Lr-@cCaE`hIJHksN>{Yh+}zspGC(^AOzmG##x!uXvhGd?xHVFu#5 zAmb%Z9ZTgK$YeZp`S+Bc4uN;vqVy+>pOVe?r8TS9A#NA=`)&R>3$bwx+dq8oh6xC3 zav0AUcpjava53X!?wd*NtvZkK_zQL~#rO>({kDhwaT(&SYuSG52_I2??!2Dyp*v-r zhxYdWFh2FXRi7gE|CjMn<1(u6qi$yW&YaJVMSE*L0@`AG)Yt0pd^*$!5ozDF2$H7@u7af`sMTb?%xap+OD-x+?kKjNgv z7@u_iYfBL~iTwPSd=^bj%q(I1_M0!K>wmL|KV;2|_hI}-(Vi#VIbv_b8D$**x65v& z`razq-)9wn&Ov+O<7}UD$Ct|xCpI%a_LLCa->AuE_Vvz`f|1xc1=AOal(^~2mU?rCB$iA#?>zrQ2kF5?e~IX?|2;Tox;BD zihR0XHj4BGH$F)HrHrRI{dNPV(fz8fg7H2lkN6j+4^%QfWb@{Qh&u$nZgShph-;U! z{p^DM`yozQ#`x*2t{8;4UEo6xnnwB>PqRJw{xj#HJwaR_K0fc5YY^8|vHgOa+1ns) z5b-CcUP;$u|8ll({>z-v>p*+UWo$p=#_i~S7Pye{tXWm>puI!jAt&b$ z-`an&ebBZYbiYiwi1E2MU;iS;Zx{H1>MZK-)LhK=PnH}_{Yn2NjL-33P5qfRfuA|# z_asbT{V%p(H0ij<5RVeq&u=enrTU&Gu6Kp+rP2+u`X!D(b;7GP7{BUL#)FF*sr~o_ zzgIuH>?E{@E@%6Vvv&D6;-r5w&baZG{SY?`yywC1zks;#3btSHVe4STiB~ed?YiggVBPUb}*>KaB#{O`bsYGvjKuFWBv`Zt z#*eJb!uBI?nn3N@cPryo{?3&ddV*JcE*}mcr z_+$qBLJf>F_gYKk+adT&A5uO5?aktP|J>(wtl#Y%fB4ylb9svE|GR@u9**%d?_~R~ zFVUW{lI`2CETj5W-Nks;#bM&tDAK>T z>NV1%MeyBX+Q4Q^Z`{rC#}w^M{fh>HAN?!iE;Oe%vi~gv=0%Lt z^Ap+;8*ein*RvgcDlb8^mY?BM$tRpVvQq_phzF=N(_7t234(G%8>Oe3ED;k0`Q>O(F zJn$gO&x~0Mg7cb!PJa&IL3B#ZpR$oU*$gl--PAohiGc7 z9gFnfPsWFN@yX-p8l=vbnm&K#thpG6-YX_gz^u|Q7@R(JRz&^~Tk}WQl0S(h9~s|z ze*d^}!atwSKWTz_zFC;SED$(<>a>}&r^rLWAlXG}V|g={1lb=n2wnaDxV@;9d8^-Y%Z z;lzeu`n=TXsWXCU5W%+%ub>SW#;efto19Yy3w=s+$Kb^9!!SJ!=oXa*c|zF5(^I!Y zzbW_g^*hp@Z@k)Y>BVTTd4TPME?9X1;@bP7#V>|=DKIfFFE=Qrr5K~9E~EZlyYT<% zX}j-;=^MoT({etTF%pqKnn4n2FSO<#?8R0LGoB*S10H9y=i6|EKZtMj$1|AK`4L;w zBaVnqGn*~(aVE3nd^oci=9S@5sGnE{_#=!9w8T%$e^wZ#YvEi+(=Kqnj4!b40O0g4 zj8Bt5A&!Z~%XbrtJeXMI!Ng*oiG>f%AB@0|i3kim$4DH(pJr@F*dfyj^9=4tY)#KI zx|N-0c1K_sS&GEg^bj9rNJZEq^3OBEEq0n$9D!k?U<8JHQY4P>PZJX(>=Arn!XnHd zS9YF39*M2_M|&~PC%4oeF~8ibFNB45SVa)$TH;&$(+u=T9C1EcNtmCP14|NM(sxc? zr~>`v!3?mx(xvDde~ihRUku$=!g8`N*$ZLigP9!cm+|d|50P|9$I0gjdH>`2i57pQIR7jHN3_=>oXT#o^U4JkpI0zgFQ9V{Hl+Z(}P*VxAyxjuY~yfz#w)n8pBO-o8eFFcGYm1%g(_MK*Nl2vdc;>s!w#|1jF~-*& zIP-hNY1xcbdR`e4iLLqJl_JW{^KO%d9I_YsOUbwU13Tn*tHw*_qCMjqdwl^r z-*6Rx`cT5@FIaIhwLjm%`~}4ycK(X|XD(rTef2f$FU&aO)9a}JSXjpR+V<6NqCZ2_ z?^n*>kNSrRRBKW~bLnOAA2hJESHcH`Umc3lA{)6!t ziA4=Fv8Z7t79A>u`5vM$UsM(5i>ktWQN?xRS^2Owkx1eB1vbwwuzCKfii$G$ssfd| zVeEG2(RA+(y~_GvdbYEJX|q?YLf6f&+3oC5l@Bjuh`zP*o&;?3wBt98fmxI zf3U+TVVw}H_|G-@npp5PvEZxxQS-3)M{GSGVqSM-y`NDm%l(Y7<$gw8iM*w_4JTO-M3C8LME928m$PzyS2la zkciLgute#>dJM*9dVy)p8J zd;*V;uuvw_ZmqxccxkoM3NcH3S}7KZi;XoyhP;S8+r;%L>9;GML_A7-VV0KhNV0JJ z=V32Vf5n$5%9Gcd$?5^;$Kf+Io(JD6nF~Xrvu4i0RSNK0dR+;o}RlXdLV)@V$J1%9WUl0~tKz}?8tD435Lpk)f;fpU7Jmvu7 zpEGBt&q@{1;rX&8RGe4klULLi2CgIFGLPWv^*@6JTVUMkBE~R&0a2jH*ow1wteZ}XqP*o@AcoJ6A-80%l4GYT)LE2Kg#&eHTTi`!osH* zf3@37yJ7sMrx`!L>vMk~?s$>$9q;~3@6-IRFdqH%t^1?B>UGAQb-(vRocK25l(!zf z1#$WZjQKMm!NR;OzQ(Egfa5EL24x1~KVh3M_pHD>oxklP=&!Ab+t>3KkDG}&{T;?K z{d>0b-wUkH2hWqxf06OGLMQN(*w4@yVN5al!T$;`;x90cFpeOc2-o&Rh%>^NO}P4E zX`e?pRL9>T7-7sO+-lm7Cu|t}rQZ=oCgG~{_=|=kjBLWS0*}3D=Nm99NdvjQ?>?Yz zE#ku0neX{WzeDpG{QEFI`RWg-KBeu&ctz=xi!pxJcZ?sJ{=^rE(`p!}zO-x*V&h!K zpZ>lTy}z%!fN}fGacj_A^9$pYNjD-iI-X;E?!-H&{}T9saZtXU3FZ{yi9g#a482C^ zAAimENB?M~_aTh}!+IjR<%sCU*sJzG9OL``;P`huwRk_oEdmFFOU3ISPVwyEbDlwa z^LmbdclGbYx9~5SAF(1$oZ!(zAE?IonFg2V-Z#HU@7ojlF;?|s#!PIr3gab&+CP2J zAxMw;77X7_z=DVC1KSY?OKlj(FRXSPZ?j@te`Lie3WqD;O&GlYg7;f+sexNAzi)!_ z#xFLc$oeX1M9#>=dcupiq;Rxi05aihRj{8~N(vD{hps0IAIWQd(T z*6r2&CEDfA?|&Rr_&Q>_GyFAE-uer%+)+OLr0u9Y()@hB`|ix9>r1D=ZD;;M=aW0m zepB)2ub93=>_B_|x%0L}TsxlAfAixuXCjt6w5%`rZUJJsW5w?89YpW{{S!I^W$elLMx#jUkF}~ax z=GsYr@_dGUIep1J*B**?xwFi3q2qH9x9-RGLv|ZS{;T$9JgD-FSJCbp!?@#*OK(Kn zBJho?M)URJ0Jd*?;aIw#B#mWUoO{bp7{6KI|1P=ZJ;a56wvRog;cvu=$&CLon&%VC z9bYbA^&8zE<<2JVA!`uJ9Y|jK{2zFkHRO)F6${o9U%AuoSu1Zj z8tqA9$AR}>zn1hVJcrNM_R|w(Xm2`~ap&Z`6vT3ezsbj?wjq`~|E->W((#DXF5>uQ z`Kum7EO*e${9zfj=agEuKR?S&i|lFK4_i;o3J4C!EjtiKO#W5x1;k zeE+~f^fA2m?@tNVrV;y1Q< z0qucb1>XMoPQ*2zG5)oT$D=xgebp)7QGKZGVtexo3;x3R?Y}YRb-g%$0guA{d12`? zc>WL0%L`ZHER;oKJ~$7Lr~k=fUEXPmZn3C15a(h|SQ7Th7K!=s2V~1%7_EO;DVX6Q|B+3G8<>Jpg+X?Y{>qnPgxLwvEOO6Pn`lU$jyT= z-$OpiVsh{|ZSKN33sU7P^e?jVW!bi+mh##ah(-Vg233Dk+!Qe5e^XAW_xiuIC@(&-b zw8o!5^Z3-cGjQ4x9)O_>**I+LtupL!gW*W7v2nKH)@E;ufo3oRHt zmJ-MVfYGyrkRBjTmJmnSKTwUpK-I($KSd%uKVTJ|v5L+Z2+9-kd?@9Bv2wszIbf_D znDeX5{LCkQYQD$(w0R56=^uQ41p!k*%IJW(eB=QW^K=ljV|huliG>+3%ARa z1cf;Q#W!aUDSag&vV%Mk801ly=g&oA&{rHV^^L&FfjGa&Ei8*$IUoUZ?ib@5BaC7i z4=_RrV!WZ0ux~fM9|Wi11QK&N3ci<%kAun7heSV&)%#q=YJe9$=NmD>GPs}+J|&VH zgpZ`q2h{L+R9;KSUl6}I7{qCj2tf}qqD9DpMHA=m7+Tvq%tC>wHS!35*H9u%FUQZ= zAzY7vA54%DSC}B3+QK)uw5%9Dl}sNIge34CBADOF-ws6&Fjun(-hY>~H~iiS`;&O@ zLBWmR!`#oc**oL?nk?CD%-CQls>Wfp)p0)v1L=^n4K(DF0q5!<&T&C1Jl>nvwgteo5)}1e;5xtc{A!i z)UIIs`#)dY9OI|l%=qeIZ$6B;<`%}!-`%_=;I+0Uc7LD(0M{MTiO>+j?EV+XDI1aYUBkNd@?$#g!ycz^rTVUspPd))&Z|M$sP zK8`rh#JKRTb0~g?z~_FtY6RL-9%B0q^S7b?TBCU1_d@A3>i@S3d*JB5PQv(IV!Zd% zYyWr#vHuZHKkLFP>G`?!F~*Zt?KThXt^a2HcOxMamEq)*b5jOU+P^AXxZ zS26y2@on_{pYROhJq}t#&nJxnZ}!#u7h-&)h3#9N{NkqwyPjjbBK<>pK1y55_~?hP z&O&=Yj5m*cEBG4Xl$Y85>h^~XK-@0yuDhQ@J;T=5*uLjY6Lvzo?+wO#tbVN#ap+CP zS53WiKg6R1-1-6Gvv&WNN_zUfPz%7WI-e&vHt#6XQ#&;RNSAWetXgA(x zeE2`#ybfVnJLA=5|2`RUr@&9GzI=DYbsw?)#3?_}cuC-6#;F4yrRS~MPZ(eD+FRtW z`U}RvB>~dcC!U`!PJH?)^jG~S+kfhRJzXzGt!F%Kef?HwPZZBjYy1CxB4VFdKd#36 z@B?Ug{gd-O5L@5x@R#)O+hSorls#IjUP8FRb0XMUbFNAw0G>o z{O#92(en+;?~zxQ$}jI@D)IaPb6)9VZ;0Xf!2;pCzajXfa9(MScpicN?Udk@c}L6_ zHz>k$(?xGpy-#Siy^na(hM%(Gr)_wR4L@VUEjIj|4L@(gYi;-i8-CG-U$WtsZMfBj zU$Nm=ZTK}Ce%*%Ou;Djt_$?c5v*EXG_#GR5*M{G>;SX&1LmO_l;g4+iV;la|hCj36 z&u#b%8}6{-FKu|84S!|BU)%6EHvFv(e`mv;HvEGP|7gQM+3?Rc{EH3$YQtSN{F@E` zZo_}r@Sirk-iH6OVFCZ9n*m)3_#cV;iDMGeO&pF%OgBjj-oh52Ix!ae);2qJS}bHax_JsZ$EaB)>gv_PuP_XTvg`4CMoX#KUay>81_Gq zC4Ze}e8%;rKgLZ0_Y?VO&XMy6rcrty^u4eRN_(r#9C zZMe?FsT9A-sZ z^@}3QU+Kg4W}98KcN{sWgueHho8}wpAE7{>)1UWu?^=N zyBhpt*Ex*qhws+sR$;u*G{(<-cxox)rWuSOKUuKk7)qdmK0;9dubbhU@c7Ap`sLd& zypITmvzF$;7cTO$AjXJmKF-I8wR!B1zt8RyPI3Q}(gJg`FvOGZFXS<@TO!eZOwtJP z`E7?!ZU?2(iz8gI6=HWIO*6gXgoCIdbSrH&fn8Zzfs^1uBS)2E`dj0zw$9mpC;ZX z%-im*OA*)I#PN4{{mPdScl?)e{ipY{@;5NvcEN@8{-j;JZy1zw%0(D|lz5*I{Bsdq zm#S{(`0ERXU4`~$@jm9BvD4l`oOBo4k6iZP4~U!O`-PRCry@?chwTT6wfl&;5`d)#`E>*Wu=C@beWj zeq+10C_hQ1jPKmzT6%O%3^Bg-wWBY`_)P*&c>grQ4HaxZ`Hj6PeddXb&z$@yJ({+O z_XpRPC2@I)_XnRIH9my?svhU~kKS?Y_lSMs{lP__G+;G1LQk-L-Nm=jcyF_KpYXzm zubqwd%r$JU?LU$9%XpTt@!ixiv^R+N2e*E3Aw3G$KhO5luKm|hXipdK6Z)sz|4+oV zFR^|0dt*;S+;RuwftOx+9O9Z*#!LV6T>;{@R~Sz@wSekli+F!<)46Y~Kzq_#Y|m&M zcq`&&fuE`S@Fv8W@38&E564}CI6=H0xPHPtHHb6bWBcI3wl>5K;(dYd)+FLv{~_DY z9s5ot+G`$Wd`8l`TErdV{lJnP_Wl)d%BO6<--q_Zrx|DbIE3nZtFS-(#pNHPz3NN0cbw!q9&yTVj2}4RhHntp z{Lc8t0YBV^*#8IPvclk3h!Z*)e|+i_*zGl1#rugvTMi|DRe!O)>bwjZN~wL2ai|71 z1A$*?N4~#`eTC%h&^Rgmq;JvQEau0n_Yd&?0**&uxY9=8i1jS=IRmSmb{?YrhAius z7|Xk>+?Pn+T_sivs$_hbVRe4q!N`JXNXCls#$d&GVX$Dj4_UD-J}t>ocHZeI5?j~v z@Xkk8JML%{i6i6V4o6lytN@C@sDQ;zI~GOa2!FKxBhnt>AKoWL#0PA*7g^5--J$|3 zrUkDS|9~U>(SlQpopv;e#1Zjnha-!f76?Y-i1@U?&uYgVe=QidaIs=6P8*K!hYPZ7 z_Q>?O0L$W^8blu&uk48SCb6Dw_IbxrelmCF z^cS7Iocaq1gBdS8`yJ|g*Y;;T=h79MWBMeq-gCh7Np~SmPvG;x+AZ8dQ|$g^7{5-) zdmHV6?bzOO;xf8lwC}+9;U8|8i}t1@#>wk%rTk~?&iGOPZZ!1WFof}n(rqa}?J11k z8aLov@;{U@oWInXfk)r%??Zcif3~mrYs9^XYqw_{+V3~&xwR!Se&XwYFGKsNfs9po z^9D~>+_QBD+LH#0^suiJYyl3_eHPOk78Rd&gra{f5hCqjV|n`Sf1$sso!B4kA7zOz z-}kl*ip*c(E{t~_@lHCXPuNYQr~RgsgWKM`^b53i?ZI}jTFA_?$`9{MHR+`eUaEZ<$Cu{|oz6I1DmJu2r|^5@p~GLqu&|o#LyhWY#DO0f z|NQn+?hl;B_|FHQr2Bc7SfBRWGp*lY{ETzhE>|<*G5p=|P?rzGnitqE*K4Jp$5`6^ z;(hs?@`kN3e$p9im+#Y?1(x>2GsXFAgl^k%!j+i5$+SoEoxJ3UXVBg#-pBv(-M2K< z-yqhD-Ih3!?$2E!e??*V)*f!;C4NOPdzLmbw_@A~Okv&#Okv&-Okuk}-XKibdE+mI ziGYBxZ`Ly2I851j12Khp!!U&-2*6tL2>*a1;%{63H$DHr+c}(3-=&Dn!ue)R9 zs$CJMuVMQsdn{XtxP2SG9*uduiTeMY&$4~T{)?VMd*}CzpJ+WU2XS2sV^!aIhqD>~ zy!#ilr~KUAju)CU?>e8_L%XnVdsP!%@BF`ZiysOVFNgaDEo=+IY>vV_NH4!fl`hr~ z%I{ItKf~!m2h73K8)+iH-vmGT2yvI-tMZ#udn?Ub9>GXpN{#h{fYC# z`^uTi$Ho3~xU(7mgx&10Uik6}HE2m$%juPW-jR;}Rql9SI^|Aa)18G6?_5X!Mx=*z zhY{%!M@!Ee+o}BUPIqtJyKXV&w@uXF{ciD%K-@0!A1VtMRRv+!MH;p;jF-MYlI}0H zA2PpL*IYpT?38xKpRIkG?(hDO8K0CsnVwJE1U{yHt3S|x>!)mgV(10eA+Gw2vC3Zs z>|1EnlXv1%cHWT>)>qI@k#fE3ikEWec`m6#`U5-eASohHeB4P=;QN2MW<8$2X&uKO zde&J-AkO^Ck{*{h@bX(@YEtU{Xiqc0X9GJ>DtDll*pX5sxOhFOPxNBbzD&$=Bm4o2+zT*hA-ae~`|`_T2dMc6Og>5FSHezRHr zOCwH@zhKI4XfOPd{eAY#!*sz*6y={#^!`g|_YdXk`L>7bcRS*mQT+V6%Wp6H5qDk4 z_^E5ES`fEg#(3bsRvPPUJB{&`;T80#*eT{ip7_!1T8tn1itYdG2z-gS>qo};_om;b z64+D%n@V6)32Z8XO(n3Y1U8jGAC|!0&2;k7o8KKZ6Z}2=DGTP#o;i(|w$7S6?Wo|4 zd8w%szndMGiozO68K;{amySBw#Zp*{8T$M9J$`Zi`Dt@uZKiS#If$_1Qq2gf%}z@< zBO^qlpVd7=ggt#OoB`JHT3iH!X;Y3#4bD$bowjh+6q<)Hf69zhSY})V&W^l^<*`l;zed@d^N6elQq%VBqQt8x;1#_m%=F*kvAwGNuf65WTxeFJh zFI*rOZ;*dl?<_VffW_7L@h;w~fX)ExPw@ldXrJhZEe*QG;OPTK=JnrD{Kpri_rpJ` z>v(?MZZN-Kv&}X$k|y)>f}D3Q!ZXm`5A1UNptO@S_{Rr!>u)On2l(ds4)F0&yL}5` zXRBe1tqhls6^meCB2I437+7teo0reCaj<;k`k$gKs9GU-6fFra&Nd&=ZT6g{6&0b} zaUqzU$-gM}aPGLUlRX3j?RiU{W{x04wHLdjFLq0x zyF}*D?jL6|g_o)Fv6sJ_KHEUCp?;_!YG_Z-c2+o=UHYE~Y4PWlUhU_=v%2u#P%`W{ zAO?us?Cbb6@Bqv6p(K={Y440~9}Y8YqW$F2;RZc!cZ(vA4marad^fv1I@}o2&4vf$ z(c#7(QSI{RaD!eSb&Dg94madVg2*WH=x|UV+D{%GZq8Vbj5Soi;l|#P27%E+SkhWyKj@F0&4H%3HFFOS;nrVnKw88y8; zI@}O{^^1(A?4u$L0?DJp4f$8319^0~F*<5`dDLpRdQkR#qo$Wfha2)QjwXFX9#t;t zcjkGM<`I!V-hZ0J{l~P6KcxK`X}^r`PqO++dz-M=i~Ep)B;WH*yePD(%d;yE6 zADf@ou#_KtcQ-c}DuW5W>iZrR|5flt20p_pP6DM_9#OyY%geHD#t3^+xBzD4fa|;^ zmGmhTVxaun-!w5nWw)G{zGP*$^FAE#`KgLUB_Zf_=iB_l6kyl|FBpOzX0X`&{OY^-h4!}i#9CY6=4jke>pcnzT07Y&T`09d09Sua)sx5!;X5<%Ae@Q;Zszcd(0o%=_pz_VmEtsSy?gPJIbL7K|K737w4bS zN3{px&7klf-9FC64t?mD=~G^@~4eJH2*}VP}HQ>6xIj9o30>eriKz`mEw*S0 z{>$wVZ2V#TBOHd|4YPo{+rhuf_y{_1I6scBM4UjZx1vQ?V&PT9dMo?+OF*Hr^4t*4 zHNl^Q9Y3{5Kf7IQkLH*j_yhTIj_G-P$g%vf{BU?ER{2Flu;&l`hsQblm;7Y~w5J#L zu#;W#cd#$b%i%k8IKQY03()321l^9X8XbymHwU+(q=!yg%=BoFl^)JtX>|}Kf0b4T zc02fwnV#&H4A|3SC(>f>Rz6@ajAf_sK}!MJ{gd4s{p()7U@xeMoxY&Ll7T4x3o2sx zhwaBIE$+MX%c`;#Z+AOkD0<9NKRP=Gf&fDUzeR-O{6d znZ?{a|B&9rZgt;1eYwl|%U#Y7>0_S1yx8UZS+V(*XT|hif)^OL1c5a4v+2LIAb(sa z1w_maE=``e#JWC%-Y+Z-<%Zw_lN(%`!uLRXdec53radejIHU(VJBVUm7LI*>wmY96 z?Xk`;>`~7Ty~v_)ZfTxV|EH28xY>&<9Lis$mtV*1R=|$W5JP-E0gkjol{$czMw}OH7 z@5PmQ^6>%mr|*BKX2AP2~_%yl;#>+XDi-n*cgm+5|F%BTUzfk!Pr-Oi>HjqF_g@jcox1T)eVJ-={w9Bm{%e50 zQ$F4Jx47{4%F`*mE`PZ{xABJ3{~6%l>Y$Sw|G<;6_4i#FygnORt6m%rRE$#_@k{{rx@y~Xyu5>Y;G{99f4`)`fz*Q@>) zXzFkBx9I;O@OR3m8~>_C-k;JdpWdd|ZOh&;K{*^?!P**M^RF7ib3m_4o(lf06t@Rr=oo{Ht$_Fa9gN^8ZZn zzZLkm#u@*+z4HHD@oxbBzWVsmztJoIFBJdVfPW~?_}}A|e~03KJMeFgGybc*^8Zrt zzXSLu{wKcb|7x%N*D3yY0{_f7ls{wslh`c3gw|L^z8 zA3g&v$G`3d{+)5g{{gT3zg7Gjfq&q?@uh#0SN`8A{`Ua?+BoC?pjZB#ivKF$-yUcD zAM(ood&Pe>@b|BXuloP6SN=aJ{`Ug^>Nw;7h*$nUD*pEY|JFF;|EO2~KPmqA1ApJm z@m2qE&KCUF<6pP&kDnF)2Y`Pl&iFs>l|SrGEBil9z`r@p_&0my|EuEvAn;GTCBEuE z&RO$R|GO0bhk$=(obkswYo7T3ruaV${2SwpKh9b6#Q%52{}JGC+!|l?ALp!j;t#tA z%j@5xz&}0C_~V>4PyGK>{2v4U^>M}@=d5|+zh3cw9Qb#}8GoF!=86Abihnck4>ZJA z`^PzJp7_Hmf7$+@0RFXc#vkXbdEyT%nyoQb(<|(+%f2ekw{~*q@p@ZJff3U58 z`b1s-UI+f^n*3W`_;)(^^;#a6^m_h>jlakM>i-7tcgm-m{=U^N^IyCYbx5zv-<1sXe;e@k->Ij6$1$;JpJ-zlGN_20NJHveAI>Tz^k{te%X`H$Nu{oe!ri7WN=Pj}(p=-{`< zL>(etrm4TlU-(7+-v|Cq`E=92-i5zI_B|ig<=>GY_6OZg>Hh)nH}2Nczte?(y@Ow` z1#r2h{+;iM`oDwX-wymc9rEd>f9?IT+kb6i^m6se|KDEuiwt1>{|NXy< zJe|__o_-|CQ0 zH~zk+*!)AQHV*$Qd(S^|{`X;9o8v#v!1I6T_V^nAz%@(oUypx7#rH2v{Y6S_|DS;) zC!O5%uXEAA#~JKpM9=!~r0V~(pnu{W@ufem+0xNJvr%0C1}gragQI4LcIu{o;)Ai< zf9C3q)BdmW+WvP|{98c(&c~wX(~W;GtL+Ahj%(ID=`V7E?f(mKZZT(Q0(@fesA=0waM9Q zSf|%dXHLp^n?|D7)NKXBj1ssC4N*8l2#h5kbn{}(`ie{=MFy7BLI!`(m$@STk({Y5_T z{`VC)a?;6-f8oQiuYVheZZ|i&`j6UA=)b4Z|3%QhI?nXRcUC(3oAsNhde`Gal)i z_OGkIdH>&A>Hjk5?|UM8J$2*X%WAv9qT@SD9sSMw|4_yMTX0nE&`#a>H@N8Udmwtb zdM$`+HQT>={~xaSw}SqmIMW~B+4fR@>i?SezY&W6E5N@w&iKFGd;Zk_EnF$?|NAKZ zo!~3vP*2_Je@0R4_uq+48>jwXr&<5a``<{#|5eaG@yY1nnt{~N9Je+~4{j5Gal&VncXM=Ab4fTK)@cIu{o&EnYY z-*_;3yV9-qGTrrF+y8!w|LdTCW1Q)ab2fUZf8_Yj7{&h$;BPz?T_-pFr5^w55a(>@ z@Hemj2Ppn;0{`?l%8u)IVAA ze;fD*o{q2fk8@T$)&Fsd|2x3HHqQ9toE1;}$1DEt0{`|nGn@NbPX{y1mD6aPty|A)Ze_e^}%f1IZD_$NLaU-ci~S$op| z5XJu!;GY?1{PCTw4u5m}d$QvHDe!NMGyeF_vX}fF$NzprM-JmOZqNTIkM+&?pXc$P zLzVuYf&NBIe6@dkXQ`vVIsbis#s4R8l&-0Ndr9o^zfK3gUdM}W&>a6W?|+9Y{-1;X z>2an%zO(G5{xtq)UjL>j{$Bw9`Z(kNUGMqR_0OFD9#H&$0bhZK^xA)2S?v1X?%>yJ z{lBsI^*@ro$N;|o`4#v(<ZqF@-`T-` zJ^l?9>p#r-|I<|c?*d2uhxPb(E{R?Ls~!CIIO7fx>w91SNq@8dpQ`w;1O02`On-c5 z=ShE2uGs#614m9exwZe6K5GBE`kVLvBb5GMf&T4rra$)Cb@VsqKh9A6e+Ngc4(-%U z|FnwO?ceuE^y`X4v+nWX|9EZxGZp`@L4W`A(evrXzsDKgz!9;}?n!@Tk|}JW}!h6MTgn+NqoV^-E*7|7HijUYo;B zn(g0w{+X@#e+&Az#+m;3%mV-Q_%~Ga|4jWwN^Jk@!I6_rZu&R%QTx}`-+ccySLy#9 z=@2ZO3{@Y)Q?zhJk*CFD6HQT@0|36ys?*#or zai%{$vw70r(*FMjM@~AqwSWH;eRKcU)!)4T&sX|?5BfL9ng009rlY@k{hz1!8=FJ_ z_vPsA)J^}CQ)0LOY6rg#&AP{jS7^3>^Zvh3@&5tzPkcd-e~&Y~fg|EGnF95+|2RhR-wgC`b!ew<`nQ}KyZ!rG zqqi%s&EaOv_TMVkzaFRf{{;Fs#+m;3%;rgdOZ(p(^mo$9O@H5$eRKcU)xTMzwu)9dg{jCYdzLYkI!tL^gmwl-vaaxIkZzZ{(*nQZvV{=esy`vbhmhI|0gN_ zzkvSfai%{$vw6~A6eQmNw*>v2baKG@fE%6Uz1Dw_b-e7T{YQ`b;DaV+kfL=@%_^*#lH*m?~F73@tMt&{+9N?HTZJU z$*uh-KGiq(e_j23W5oSGN9q3?=pS$xr*h-3TYtT#!)G=f{mtk9Y{fqTd}V63fB$K* z@BfVse!cQ<&}{!LQvW=~|98;8HqP|NXEsmzTiSnr@a3eFTm7%;qxP?>f9L?w{tJ}; ze}Mk}5A^PTUhA=LdVFTn(cirP=PUl(fG^`!J^l?Y?LXbYuP$$y?l#T#pEOqJU!?f| z3Hn#Zng009=1G51kl6p<7JNDB56=e_j2XrT&YR{_8>i);QB2pV@TuH}C(8 z6#wnOSG_|!b<^K>dhGjur-NVFj&;M^HQRroU$p-c#s4qR-}j;3^-nkdUen<-n;D~^?Y~LtzeMpjwubSqIMW}W**xiQY5xPjmy=Fz?LV-lZ|?uP`e%+4?LVya z?+5xPw(He@uk~0rJwCH}(!X5sPXu4>4(-%U|HLz5-~auuM=w`h-ZI^tn(aSfywJZ= z@!t&e&x|wu@tMt&{-Pl9{=Xyma?;67|C(3(rv2;cZ(jeGDg8GG{Tt&I1Ygw-?bJ>GjJspE|5gXTvK{M&cWJhN^Zn0q#eWOX-}or{b;^yuZvMTd!)LZ$ z>QC#RlFk;_zfQ$J1^9RFu@miwWY5?CSN_*QMtjMh)<0I=F8B+gc>QaE|NGt_q{Y8s zT{~GO|^f$*pPEqxL5b*cC zq1XPqT&{m12fsZQ&LQGT&Fh~z|82Hf|GE{l|N1z){^2vLPWw0Yx77cg!IzUxZuLLC zkLtg!{$~HDTGjup@%kTU`r|XJj{fHL?+nF%F!*YAXs2%ahZBhgu8Q#DV@tM_={vtnk|Jwz8IqBrazon1bzpnn~^Y1xI z|NfwVZJg!9+v7}s zd}j5ezoq@}3cj3la??NXdf)Vab@ex&e`}Qf+k*c7PvYzPkIyVR`kU`R&R6_*17Fn+ z^Az3m&%7u0{oi;idbxUS|MzINe{=oQg^K@npnr9o>5tEBp7gi0|J}itlTL2>H}z5b z*VW&A{<}!&zdh*R8fW_BGn*&<|Ec&70bl73?bJ`8Yx`fN+5XM`|0Rn5 z4xqp9)9BYJSN>j!Xr{+!Hc$GC^J4#h5AfxrlNl`ai%{$ zv+3w>KL7tq@!u1Cbvm?DH~s5f+JB%edb`rB_GYrxn(g20|6Qi|CxZUXai%{$vw70r z(*E}XUrsu?>0jMP?O#`av;X&RrT>ngf8uA+>!}-mvqJul|G;N99sSMc|H~DBANZ2FBP5og5;Y7#; z_J0R~{>JBe{JrwfO^?rPp7a+dM*hRVmy=Fz?LYKp-}L`=^-q}~*1y6Ano|FrLI3nP z(;uJNboB2!O3eR&4U{GS;oz&)p`E(vpK)*O`@e4ec1w4^X8W%hCHTV!^d5tEBI{GKvBlyDy#3lcIz?bhGz3X2`AGQAnH1$s$E!uy*;=c>%-x+86<1?F%{++Xh z{_p`=ss9M@71Gqd?byC)|4m-?hYx5<{z;&J;0wL_?{=NqSay77)6w7D{{%iDDEW^B zU(K5OXTBBt{-5}6^m6rDE)QzzU%yn;fB1l!Ew3* z58c-{?O#{_&SgS>_<)Yoe>c#-JUW8~?=n`=hIe} z^#5Q1t<--A=wBUY`ujEYH}}7R4+u#9`++axJ-zy$-WL1*pYGsSx8BQi4{Nsnj9rBO zuz*VP-vjh-jWhkndDUMOB({INmpJL<*8Us&sQv5eZ?=D!KrZ#)6ZH3esaOAHef(dC z6EyWV-~Yk_63KrI_^Nkkr*8VUxU~OH2ftp+>k-ZNZ|V;d2qpi$K>tvj=|9n{{z3q3 z|Javs(#cJKMsPq_K(jJPCB{ipP1h_?O#{_QNzUZ9}FN!{fC48jd7-b zKvRFS{|^JGlK*({6>?~&Zu%SV$G-nJJNWh5{vX$D|EB)Xft39B!R!B5(XUgk{Jj#< zOh47D{^GpY{_$DTNhde{O)m3)H0ik})79U6{(}pM)PDr%pB`uWPuJAn?EgatO7cGt zd?o&+SO5Jk^FJ~j{JIM45}{eM{hQB!;6U;p3HsN^nf^1p>MzO{+dqyaIO*ip{##x2 zcac%stgC;@siOb?q|$#B=-(M<`lo5?Z}$J6Q2Zx>uSSP<>ZX77SuXv*zoTDQw1pQ5 zA^QeoyT`wwMk0OxspcO-|ECrI(V&0e>*)D(9Y~YA1`|HjBF!dMt!S;`1Nrr5NE{hv|#?+g0Z#+m;2YU*$H|JNw~2Z8?Sn);`o8@v72JNWh59N_Y;)&9-> zZ(9`q{XqZrIMe?julifsKaM3j>Ezb_Yx?N@pRWE@)#Cd9ywZPv(7*bd_`3c-uBpG- z|9?*LKLqsebZDn;`q$OOZvO!z`gaw*w*RLz+keZMLjM;O|1qGy@7ws&|4FaDy`H-9_gas2)3<2qZ}$IQRQwMG{c9cCsT+U) zMX}p|=A+Tul`e0Y4!ZAJ_kXkfw<`W)vHkBJU;3~0s=p{m?EmAt1Sg%`^l#~-_OGkI z+5TTu`ujouP@L)iil+V@LwBKZFXI)(|8UU1U9g$$HSAVnpzp3;e2l^)tiC$0L_`BtEW7*%) z)W6Or+W#Ah{}j-_+M%7g@%KL%`~KhR;MZ%p!0?T?_TQ%Xj|crT<4phez3MLn!23VG zOLWr7P5*{IYX7?Wo8SL`N9jKS^lywa{p&zCo%Mey!$kXkTk)R;`ujH1yZ$vk9J~F8 z9Q=B1|IhZm{nPjFP5zepkMB~Q^66IpTl=W~>+(0pf8SU7rvm?G2c6vbSFepd|08kp z==I90{xE#o+v`8+Z}PY3kMB~Q^6AFE%Z0yJo=)j?`J3Z^A1eKi0REW{I=S%=y%1af zMhCx6yn1>ZhA*}BH~EVb;r$Qar8?!)jemy=|DN*cZ9HB6=J?M?O8=R_-`FC0J9Xn< z^I~lM(;fWwmajcN4Bu<%Z}JxoQU4=>zf(Tl_>X!iHh+7*Hx$<8Z?6CUMCpGN@UM5! z$&G)YBR2m|2ftp+VQsJVH|Y9bd!Ok4hzy|qQ{n%e@9Ne6riDB3c#2m-y-W{VwrbUX zQ-5(j2LBEeo_B9z~3pKZu%#^9GkyG_B|igMrvrbde7f;(>LdMi`J4U!bxQxEfxmw%&Gz3KyZ%=@`1RTV;Ps`J{w9Bm z{_}vpQ$F4FZ~Q7Yf3G~9(rfUK-2d@CrT>92{$s@1{*PBfmU}t=6UqNu#eX93PmeSH z*Ldaso#H^d5|7NfJe^dOY0{_IJ z@m2qC@yh>q#eW*`&x|wvw|eFOhvGjS_&3HG|AyZ4r}0no{nyuu|9p7VPuK1F z-}g%F=l|A?H2(3j=JZ)?5l zU*_+z^$$7t^;#q_eS3qAe;ot-o$~3Xf1?Y3uRNX7>+(12|KCdgV}XCOgHCSzNBt37 z|HOpo^~#A?Pmja&Wi9HAvxoBV}C)c<(k@03qB{H05cmhS(QE(BF8pg9 z{Pt95r+Bb@K}&y=zeWE{;O~@AH~ll;>l^)b`J4B@{!0HW;NR|`lN6L$? z;y)Ak2ZqI0`@hR8{~ZD~R0=fAhS(tZB>KcN4Uc(5M-wmr7*llkwke4&^9Ki0qD2BH5TrT=Wu zzdFwJN9{KYz&}0w4Kx=UpG5^zNnYaKivMCl7;?575`&F|N1!7|3a_&ivq^>pAWvAbaHF|O)mPo>8NYh z)xYaPq5m+Ye+KB^8E5*}YU*#^|Myn>3&2;WLpycT-@jSx_TN4x`gKKDcbN`8-=x+4 z(=HPF@1yu12l@v_MbD=jf0>{Eb+`kZu$TS+$o`+mFt-0f(BDZXH~tMS`fsdq(bd21 zVxj*?rT_7ue{G!UKR{D|^Zq|V@h<}Xs}Int|Gv#*w}0Q*=zhJ{3;2AUR{QU`MCd(lF=s!mBKMC}& zjx+rS_F8{_|K*GF{;LY~ubmWKCpZ0DcaMGj_o}l~diZ>sv3bDB+Wq)YgTH@d)_)NN zuYbkB->IIu@z30%Z}{uh|F+9S{U599|H)AQTjQ+$?*zJey8a!Y_?LkGMzUW0Z*$SV zdEe-MMfKAT;PWk7{h#W~h5q9d{~+k^bI7M#{nsYoG2tLc?@51ger*4xc>mMnpT1?^ zw0~Xw+fEbuPf+@2g8m^*{vKu2PQEjw?4AC6|En4x_P-vl_?LnHoto{x`qS9+e{08W zoc0f&FYfLAkKX?$oG^^>Ex!rf9t+!|GN5zz7qOR zR{H0H{;hGQ{}4_669$X+Z_)oO)c;Vu_V4%gjsBnay8UziCuyMIe~8jQ4E#eA^!T^B z)c?c-qx%)buN}bW`+NEPW8-hpzXJF><0C z|MZC)NB?%zKhX2)Gt^-HP5u`BmjZvMe7fEAc{>+(0p|E4PamjVAy2c6vbXSj_2 zIgKm!T)F5mdq4hXd;XiQ_%8?k{*>tT)Qx{=NNoLE9sEXT)$^ktYu11B`B$6@+!&_- zf2Vx9@$Ycq-*ZO2i>b@sT>p`(^gk8&hYr%yKhtIXhts-}-m&c-TVwqPz5h4)AEEf4 z2K*Z}*T0O~Gj{z?KO}m&c4ySPBcEdZ??n=M{WtlGv{?U72S-l%bgTbWF8q6u#a>0# z<)68;xc{dq{m%gYoeny=@gFrPw*Iw~H;(?WeTA0(CVz|m)xh5=pKkmM_lnKGSEBYJ zvMzt~`R7Qb|CzwwulfAb?!w>cxvCdbqekuh^AFGeO!`_p{~o6J=fU%DNb~)7)Xe=4 z4(92>8UG73`KN6q?*B(C{)>Qrz~MdB|JU|^ zr6&KTZ$sivJSe-yUcDHR?Z&|J3g(zJGF@ z;$IH@s~yHE-R}QwF8iN3`Sn^IUc~l~gEu|=!S$c`cl{{zKVI<<1Am|9_+QJ{vFHCd z`R!r09izRZ$-lK$=zoIZUjh7^HTl_|K0(~W=1 z-hHFLF8}ldp?^^6e?IW9*W};k!ap!&{{rCO?vPJ6{X2)n*1vk{ z#^Dd!*J@q=O#YVok8A0j^6AFEaCmI~;xrpP(B5t!%@J)-ZlN{1OxBZ*?TlnL*q?~keT>UngCAdK|W|(z^bc{4M(9x1+(0R{{>2a z{FYL^CjSl>{(%`ANB?g$^*8xj^v7?BIOWq#|5ms9-_r`+%Xqr{&Ff#0(*IK6-|nE3 z8~?P!W7q%cBQ}oyuzk5!|KH?q(f=~w@03qB{&g<=dns#=qwDfF$3IR~`d7mEN2ccd zr$(3Y4=2ApCh8FJY0dEulYfcgzZCczn)83!T=+Zrb)ePb!_V}ZKd=98e@Kk~l`8(r zfPcLvf42-f`E^U@W?$o#f0^Q61^fdJ^R(RBzgs??{JN!cvp?Hw{s}bxQ8QdT|AZ9( z<-osvBk_0g>&DN`-qLISJpOI+U!wS*0{p8r=YP57)5)(}Iyd`sn*5tWqWzaE{-*+e zpTjt{drCP3D*h!Va5L+z(1tPf0PSp8@>SHOGJJUHCisRXNl9>lLs3mnr_$z`s+Ie~Sx$C%<~ERjSrr^G~4pKW6){ zQvA;Z{>;K3*3;0&5t#1!=8v@!-Y7!HNej9=vdo;KhR%4_^HHPqVXk>6tYvvvztn=X>)b$zeLP zW&#F@F&97n7?0Kiu#i5B`|&_-AnI%up(>8AJB3ABFkf+pPHaG5qJ?_(!}g_&5#c zzcm@2|3xCMjM_}~b>!oJ)%zd%7gYR582%IBzaaFVT{N7Zifc$@|5{)Q+3_#!U(FVa z(K{FZDNn5brNjAUbo^A-{*N;LPlW%J@c4HRXc7KTOzq}O>gc01mph{ z_%9KjIQ}liKNXkas(1LJLjQ@{_TTY_|3diB5_QV)4>JDaJC08Mf9uzOvficTdA0Rl zsaF3d8U9n@KSOM%bNs0#!ti@gQ^U;q_l8;zp7k zF!B$6{U-zdKnx12|Fhvg_78$zSpU7s{{(UWF8a=8tNs53aUJ{D>;H32{a*q9*));=O#Nq93ilu1H8`$q0{rOLe}o`m^?xq> zr#gb$Dc$~SQ~oE2`*-oLmYrY!D_|sDw6Dgk$>{*KN;``Vi4+o==xvHug3H9|0?iP z?d14#8;A1~&9NRV;C^rHNOh%`@a$VR69BTrfb9bsrK6r7w`{ldAE#J+do$u|2Ki( zqqhH<`sX@W$*Vg}}LjRh7nE!jhPqp*! z>ff6GcH{p(@D~YBw*2Y+N5}tU4fKCM_^Ec<^4sP)HNBL-V>VU)cN+f>fZzL1uqRvo zJQ0`Ts(1M0LjRgy&B*Wn9|S+uPFwzZd7_Rd2j^Dx zf1mOHDEKo6jgJ4!VDNRNQGJgbe@dZ$&94Ib_5Ya9Pqg#z>ff3lKOhqWyU+hP_+tl; zj{gD?S1o?=S5pK1KLLKKoqt#VQhx7tb^p&p#{ZMxPaQHk{wqXWv3ND%R6_rn|6#-b z6!>$Uqr;y#G&rs;|J1hpssVoeKMj7WoqyN-m-6T4Q|rG+jQ{_FzeISl<>*b`zn?Ab#zw)cVzW*1&PqmZtpJ4c@_S+7Z z@~4kg{_z0en*W!;UnD$n{5=eR?84x@vgMya=wI`z2KfG820ztKj=#k4+j3IVOZnT6 zSN`z;;hO(fz@H{Oar{~4`qu&xm*T2-cueSD^Q#&8{$B+@)lQDT#PHY46LmZR|IqpW z)QQSJen7P5|26P?7X{ZT$IrDpMa1Q%$V{5=eRg@{`}Y4DhHMDG7a@T;)C|IffrwUgs-yU>mQ=={~^zi9vO z8ULSyKbe=+e>cOQBjN^It$*m84Xpn!z)!W4^B=p&jel$Y4~+jW!Cxjkar|8jf8vVZ zysF=H@R)No(EnH9r`pN!dl$R$ADw?h|M!vc|26otgeQ)_li@EBaf7YaKXmQ}_Wu>| zQ|;vV`xyTEiK2}eoqt6C|B3Pc4fx~ZgX@&zPhJw9{~01~G};Nrp2xQSKQ;W{fxk$! zljCo?G@L(nW$<#HkSN-ad2RXC?ELMY@4-*CljF}a{L!fDAKRM$GvogU@TUn+9RDE0 zUm)VvPZ~UCyn+6I1V7bIjz4o*c>V{s-hQYx{};ypPvG~i3a(R*e}Lgn5pivoz_{;l~d#{aM2 zPhKsn{|dvOBjVcnpTB|re*-_&PR@VF6>j`T=O3~EgCCHtUH|br_{)SRj=yPqIDg`r z;JmW+zku&QLJ<7^*Uu>-4fk0F{IsSHrKSC2DjcU#Rz48Ai__Ks3j=#k4 z7hfJ7{|iR;KVtt6KOkMp|4Amt_U|jf?d15ouME$B@73VAkz@yqyif!Cze&MQwUgtI zUB&PRw7n67toeU3{wD)}p76x+7a0EJYop_T;RgDj9Q;%}IsTTb-T0UCC$3fZfBtOz zj{$#~@Wk=w8UAel==g6D`q%ub2>tcn6yT@Y$?vtPi8{SC|L?~CRNzm)A@kq5DZ~F}aNMZ8BgbE~ zf&Qlkzelu_^PhM;JpV_wyHWpd&HtzIKMnZvLjDrNpL}a{{4dr(|I>n>YA5Hv?Fl#j zt@$UJOmF{B2mUhQiQ^w&__J@1j{n6Q=zn_fQ|;vVyPkC8-f6|imTq?OE%E| zSnyNrEKr#1d(1AqL3U{4%>>oej0i$q-81+jDk{WpW3YA45E zVEAo0sp+lxr#Jp*2Y>oQng5n&!~J_71;?eh>K(pJ1O3kdeyW|E|2)TEFHpqstodWc z|D52@6P`H!mFUopMG4O{}^lh&kg=E;fdpK ze?HuQ_LI@^znsv&=2uJFKmRcg_^Ebs{2kjf$A9ZK8f`>t{+W&cdBGna2=>JBcbCHb z7m2vhXeS(d`3CxrgP&?A$6wshjejYBrS|-nS&jd3;7@-_`S&LEP$YliHK7GOJLiRP z|3T9cm||3PN^FEdK#Km3Ea z(fa=p{^vIQ3&MX{=)cF2|CMe1WBK_nzy8<5oASi@Z{NX9{agE=*Z5xu{c8z3 zH}$`Y(0|w6s{ZFO{OiMiOnCk)#%%u;h`5-g)oUtD9j*SW*Z+2(toX+n{)OQ`{w3u< z9=iQo?swyVRa^gR>HGEHhBxJjtN;F;+|<9+f9i4Ne}3b?1^$ad|B2V#_+Kru|LXcL z+oO*E%xCyFfd7>6{9lUM|EUmhRr-m){F9lI`Y%u2T)kd#LBqcY{HMQ?)qjs8|Et^j zS4-Zn{|)h`JaP43Vf?GvH2h2IU-$nD8~=;KzxTDwf60;mHH7~AYuCRoWcW7%eolJ+ zch~U#KQT(@f2Tp4CH1fS|3wV{V(_0A`j5ZirvFdc`d1a{*Z;!@mjal!!Xz{P*o1?msh1=l`cgnW={=!ReFzw)HY|7DH;1pF6;{?m^9uN&F_i2eU%4FBeS4hXOR z8DRWZh`1{K#9z~6N=f}!zES>{H~dS(fBHLF{r5Zazn-mswdDQ!-vV#S6IcJ~kKEM1 z)PHxM^1q_-zYP3)-^={Byyb>}{mA~S>;FWr;$Ok=ZwdUI@cOTQ#(!dzuK$_=ZI;x( z=EwB@%g_I<@TS_y<$ue^Zv0F62QOCs4>8w&JTnISKa%pI&K(!0G&DJDRUM zAYbCYzn1?ioBZDz4J{FQ%JFwH{xhR={hR;n8VP^u4ds6|!@n(J#mMWw!q0zod=j4j z1tP9(Zp>)QuNvUje>>h(J30To48NL9!@r{QSGWK4@!!>r|LxGa6nXtqxc{bsaQ_t| zuI&ODivZE`e+0j3fbV~Mys36_{<93fnoYyMqVreR|NVQY`ajh4|IefU&o;~Y|IU@& z^#6AY`+t4?Q_|%B4zQCWum1_p|3Suog1D~4HX&w0fN1$&^{=o0SljULgjgk_om~ER ze;Qu@8RERUE&t56{Hg(d{qKx7)lQCofZ~(<)lSZT7sIb+)9|n8{MGfJKL4|x@xLotmlB@;>}U8ZL|oei zGAjZ^^FQMFSDWGA9kFu4^FMu`hv$ESIIm#KKU-w}YX7f~f39Tsm&Ngq?60!pADxbl zf3!tD{xQP865!YW9(YrpxcX0i5$<2jrr}>=|Fz?v8yf%1!GB5UKkvx@215UO|7Qck zzbEXJh&tu`=NSJP;=F=wLNp^lwEnMJ|N8jn#)f}+_>cc4tN)54{~Jd3KcfHJ)bOtW z{-Th-`E57#zfolV5$pd=4F5lnOEKa3kL;J>{OM_D9+l&RvkUWIpa0p+@UIB}vEOC+ z-{Hvr#w;n9@ueX1wB+rm;(Pp+dqk) zl>Z%#|JC6?`DgHU3di474$uD_5!ZIPZ0`H_<<QUxaJGKjn$@@4Xl9p9HY{gSG!*{2Bb4^2G6XeB*{+;D4z9 zZ@*d9|IQ}=lki_A>XhTR)F_^O3t|7?dA+*-X&1x4KU$HyDtJB3@s}P8-~LHX9~@T< zt|pup-x2Houj~Ka4F8(&pYVd)$*uoe9M%7pLjV0QDF1sH{z@`->%R`ezaIEwlgjcx%kZa(xKv%&JG|YN|DT3`eehH5 zWY>QTf4w|W$CL8spHTkyHvDbiFA$zM{^HY2{ZAI0S5bLKj=!DnKhpkBHUBlg3h0N} z0Q?@&PL97c3By0K;SKtK0sqkUPw_a_|LtS^ZwUSr$sd0FV}SGDAl{K-winj_VD0%w z|2F&^fj=+g@1E3+{~aRpSC9Yd-#^*c@NW$M3dtY7{S%wa4gZcp{+6v({_kh_HvxZg z^5A}otN(sS{5#q5XAJ+Q;Li#9TPAnoe`g_ord|2p-|%k+{<4t2&k_GFLVkVzTXm@Z z`fpOiDlII#{~_Jx=KhD-(C}#c|JD9aumApI{HNeQF@~!D@bzDEjGO#V3;pZ<|3JgP zIry_Ae|Z02cErD{kYD%z2O0h?z+V#bC#G=Ye>Wk2{07zk?QZxFKp&7Jj?;1Lzk%<< z_kWAm1lQHb?YXG`AIAie`q%twhJOEdAl_6vIsVq~!}-;08vYeWL4M`_GON|9nFJ*ko$||1iUUC}Nd} zc5?j5AH(_MHv}(N%+l($0H&7YzvfqS_v`;Kys36_{5ghS&8FdBQvQxfmH)$y|HFO$ zSg3WI+Uw`0uUd|B;6ONW@CrB;zmr6rTUZQQ}|7mR||*^ZzKksdjSy z+Xln=)odF6CFM^~uJZpVcOQy(KuV?E+~*07?F9e$@cqf7X8!?d1H& zes<$OI)C-}Z_xFB-(o>##>=k%$z9@xe;$APKM8SlzG~P1G>uXDpEdb^3}U2(`QOF( zFA#C-Y&JRCBKV6W{|hz#;|%|Ch*h{XxK6qJZ}}zMe`;)SToSC#KP)Qb*ZaQ*8~!b^ z{~MnoxSbq-$R%uKJi++i3jQ-f|7}yc zIsUPS(0}_Bs{cFQ@SgxXd7@4^|INRK*MIW%;JUI+h{X^<(*No8-${mlYxpk;{SP?u zzo*cD&+Tge|763z4ftbI27BWCr<>g5|6W3VZ%UQ_U55W8mSJ*M)bI@WkbR`)}d>pPEg>zohJJ z|ANqerz8IzLjU^w->HWGWZ20O>nYBEiSeH!^2#%Z#$Ut8_@*Jl|1?cm>Q z3ht*k{tDwiMZ~q`|EH~g)d0W#Pr;k=#PP>}cT@k?{)h2z5C4=Wj=yS^uB@BfS615^>ey7k?!% zWyJg+y8g5261DwvuHoMa{*zP5_{9L06Ye9-f9+q*-_QRu@TNR*`QOj@x5OkTm-_Fy zO!>dS_}>}+a}$~We+m8T=f9qB_|L>rPTV2O|CT?)>%TNg^}jUQ9IgJV&wnX@sQh1O z_;-Q-ve19iG~w$%GJ!4s@NZlHYW{xx=kTUHarK{P{99s@lSlVoeg1(y{&%tQpN9X$ z)Uy0fIP$-*(7%5E?L~(FEG*^tEHeIPFFgOVM886ct@97dV7zGcU)}!e{#I@OUTXMv zh5xM3e>>y9M8vHVlN@b7p?}Sc5BapCRJf@@FFF{|Nu80e=3Ui#O$o%m3sL z;r?wosp+l#tH3`09`H|j;`mF9f2#eq!=wAJ_W%0#pRO?Ze;yiBBGywJe`=<1|FKzv z>&ljYIRuc@f3kM`XT0Ix6aI@topSu~X~X$T^NbGv{*mjy>Ri;^!|4)DYC-mRV_>aX$hyMU!{cHbf z$@}$x5#E$1F8@nEhWl5uY5145f7K$Ne{cAwJaPO*#(%@XRlw-}tNTCt`iC1${$Grk znI(hsl;iJU>Oc2na9rEvvLXUV>c3|Pwf?`!@b3fvX`)U!{sG2+frx9%f1t4bHNR?r zpa1^?Kh;i-KQ^74`j_(S^Irwy|57Z2GLfeof0@buMBnJ-e=FJ?E&r?MKL%^pf8A>M z{|*1%xZrkj{H=`t6cHD5w0a#R%zy1)&E3!c%kZW=as25)H~DYve;EJ1@K1T-_`4YY zYBml3lKR)@KW{hre>qy0CF+#pPs|eTzeL2fT_7tVK(zX=uK&A!QRhGL1KKgf@biB^ z_|Fq{%JC2Ohx6NVQqvzStbgra1@`&#cvGG@e(z^D{8In@o2l)eUgJLl{}rMC{Pb@4 z4-xv;=RffS!nORr0{-Jq$<}{8O#NqwxR|BYYh_F=ssH%3%KyEFe}DK-&L`uqIP%{a z*?+bF>v&Z4fA<^y|A0Ry+AfEqg#ITsEUdZ3i_^%LgZ5PBbw*0CAe*R~{PqmZF|CagO^nU{Wq5RkT ze@`3#$ACY%aBx4x@!NWoPJgV>f9`vA{NowJe=PWOLjFF+f0>9Y<*rS4Tx9<0{;$6O z^*+OYC4v@-<5ZmgLFV{Z?CIdVs&PoaSHXnQj(=6xf7-vAv0wkk!9V4RGfrTK$jkuV&!a{|WFh`6@=t090S z|J&|T{ol)m|0MX2FCydbSs=XrGelfl{u6Ees|NV>--9>hiOc`=@8SHmoYeHz{#9U~ zzYG2;PaJ=IK{x!?{$DZqe;t-Vo~Tofzc5=ke}#xkd98Q&>KIW{|EaX9|5pwF$?#t! z>XhT}X8gw%4enR!<)p?tse$!>J!V3A;`n?24EIm9-*&jQf7JlL{!f8_$`i-mx{w=w zsegU_&+8`tZ@@B0J`_%9G~ zZTY(**Z+v~|Ed9g{(FA^_p(fqnkdz)yMN{HGQU&wr}@ zw!@?QSI2+uRLB3`Hu--O8dE0fl;f{3^`Ce)xL>j5Pa=S%{wuZZ|91@k>G1C@7Tivb zzmM^sBI4TepBy>=NBCC_@bmv>yeUr{e{OO&_dh1lW-I@g-hcW0XTU$@iR15RaZ~?N z|9b!bJ(K^p_zNN-%m3W$;r!WAs{b|7WQqSohg$!?Z}`uI|2$Eroc}W8ze2?I7rD*r z6k+{q|7zxb{ul73JaPQ7Dc#h+wf|xKIryhMas2Izgy+ASO~b#W{`L0%M<)MoMe9mL zopSt5bAg}e{A^Ag8$^=!R_Su2O0l4BCaj}sgdiyy8W;D zRRjF`KO6j1J30R1qT&8+IjQNR@>6mCuM8jOjoAMC)a3u|SO^)SPC5T2rv8gWT-)Wo zHUdcMzxBUr|K~Hqe-84$Ow=jIUs%jd{+|}P{zv#%0{r^F18>R`$Df(T&H7*JKQ?po z(0xzdSH}Oj@Sj+M>i@k-{hfqA@luQIFJCQ-yYYXz(7#^)e`)yd1X1jHia#F8-#lNq z|1=TzFAGudKkHx`N&Rd86~liX{AY#!^N#$V5!rur{jd4)qldNo|IP=0NyuMe_~XQL zH3Z84GRc_{`TsKU|H1#6VEzA%@qag#M}eqQuKzDD5#Ik5E|{g--!^!euZwtA^{?9F zum3JU{!@86gBRZaCmH?*W9x8H^S|al==n#pqLyMy27BWCH*Xf+|LX=f_#g8_Tr~gm z_D?U`M&&8TA78)?zcl~#`S0&c{dXh(i$p)o@-G)&|A|$Dw<~PZAs4a#ujRi!{`G_5 zzXy%Umx9~L@h6rH=g++m9M_hAJp_oB|JC)s_OBY?_kS0{Kjn$zFEajZIjQNb{SV{6 z7yqU_as2(yPCF{=H;TJ9TAuXs|NV_ ze<}P^o;dyr&~F#ZSeZ^{$LUtGk^_OH~xKL3l0o@&QGE`$FxQKuY#$BNn0s|AuI@r2e&kwdDQ$zXJX#Pn`ew zN^a_3>R%uKZ!-SJgFl%J_QW0k9ANm%L|nD_#b4(|&j0H1KYjdXn1BCX%0$2H`sd6R zZv6YXA1(i@{6WWm=fbkAEG4V|ff?QKFNDIC@az5mVgBa>e`#qMe{2gk>%T=J^H;b3 z^!?9MnfiYe%OdtVRsZ4Ve~V22Up^_guGHcee{F;*qxm1fujcIc|BvBKwUg`r`#)PF?>tgYo}3`15bb{KpdE^`Cn)IIdd!;;&6GrNn>d^@@K+!~Y~=B`%lMf12Ts zzdbtqn+o~kHz@wGhW{zVioFxuPA>lo41a!n@N&g0tzMg9YKi~iI*NZL!~b8z%D*e) zZ&{kj|8j6#D|k$tvgKC|@cX}K@XitK!$yc@@H;T{%1D+p9Ozr*1HGVa7-+u{js-2wwv?Kpg{-!6C|7PR=1@Ko0PaJ=a@t@pkbn1UAv^kpp z>ho`Un$`8MA5Ec;e@{9E_*V*EPjmcehLhLFm@9VM>VA#$s@wmCn*TYB|CbOYM|k4+ zo0bi)|1uG`?uHX1ZjIs5{8#z)@gEh}um3A?{D(SD!yW(WS~;AbXukE}=*NFX_#ejq zGX70@;{2zUceDPJ`q$V0Ok?u@D)>*V8Qf2C{N5_z{!2t$+XOgYc>GWQ{`Fjj{}nVQ zv9*l9hpGQ85!aS~8w8NlzxJ;h;Mf1v@K1T-{C6_`Z8@pwt^E(R;+# zU;i_&$^UEMKfabM|0|6DA`zGJTJP`+g!Qj~|2b~>U&BmGM4fW}Teb@C|Ki&OFV}iG zsqwbOA0+j!{j0!!{a*|JlqZfqw`w>))qdOI*8Yd__v7D`CyqbQ__yVxrkDEH*FVi~ z^1lcEV`~TJDaYTmTDboL5trhscX+q3{`L8<1q}b|m}!QnQ;xrR>u~-e5w~7WYP@#* zK~n$PzY6Tv|8?+BdE)r9jDM>Aw!^Lc595CW|E4@~{5i(IEhja-)W5#|X10z_S+7(_CJjOE&QAE#PMet|F)de^iu!&`lrQA{@)1y6{1c#{;oB` z^FOz4a9vSc^$x#CSpTut)$!lO4gcGiX@RIyj=#kDZyz20?a^jQ{cHbfLHqT86Z})2 zIDRh~?qAKO;a}GNhw;DT|C{i{@waX3hF|JmAOBs->u z|0QAg--Z5^(0`HfpC{s~^b>#WfGH*Qul+A;_-}##?0Uid6z9KVO*i>}iLHON z5mQf=tUpBU{HLz}6%GHb@Sj;fxSd@6x3A?U|1Y!kuNIwO|L@~XdE)%1wsXU8?SCcX z|2Ft93jMdO?S}vI$o@y1|6axL-wytCn=Jna9P#IE`BydkcYwbjD2|M!4Dv60Mw$`Sunk^NWi|0>s>f4Y|8zZd*jA%F8f!~K_k96Kt{$GO_)_mj8I z*Ese3Tg|Vg^F!PReyW{Z{^uC}I-3`HGy(t6?;p23ua1ALZT#O4{`kgJ{(GU%|13M= zzb112SGWHX*Q)wo*YH08{tU?-5lYlZwRTPyzc4F7}Rk8MKv59cpA z;_tELU*GUQ1pc&;zil5k{;w1AXWEtjHp5>8zqhH(f6)>D^+JAK{~H+ohryo`^0)rW zjsF{j{JQ=(H2jZ%zar%Ccf@~VWd7>*k3Rp`YWP1u`saw_blmzs&m8|L6LIV8=E>1^ z!e62t{~y7xBKzAvAL325ljCpR-c9}s_=mQC^z|Pb8~-1HKe4^6|5J;R{3!Kdr=#-^`PcQY8ZeaqSdfLwf}c~t<$v;m zaR0WP)b!2%`Y%cSb;9A}yz2db+P@mb=l=|E$`i*w;hg?AL(-T{#QguO|IJPQe~ws1 zB2PK~#17%>zu1n!b!EGhcD3bK4esOmo@)Z#{ZXSU7GO3@eeZm z1tPBP0@)1#tnyzq!1w+Zy`LAZv@Gk-X(DsjB|8Habf9?X=}rvuXHObpGn`KmGjEcH{pWv@TD0;`n1bh39{T zh-+@b!Ea6$Di9J+<#)1;JmV3AbTNzB>y$PYJl(mN4%+aa{P&OIKP@r z!@s2b`uT4=8UH__by>m_$KS*7mx#Ew3#0=9B>pwOYJl&55O1oT9DjUQH~yvk`uTUe z82>+mKb{V*Q;xsL@Mnm)YVnJ|{)s6i{x!dvv+w^Gys36_{OR4?_?PnQ=l|_${QnC6 zBH@YSZ`nPZKelUdUa7?|{@NQ;O8o2R|Lt!0e@CnW(N2!PV~=otZ@1Cm-^Z3;EqOox z|M34!w3Fj++LPf|^J(;#lwUvpZV%(%|6$jZkUz`tSBSW_%i~`NAjyBtuNvU{_wYfr zlk-2w@T=K0{7cH;xrI9Zy_fMn3HW0N1=lIZpV=!s|IO0!aL8e$@cq|D^b! z+R5?9rgC%qTgtD`e{W>`KZ^6;$<1W`Q~wV4Z|j+w{-((1zpMNI`udN(4gX`{FAMqm z9P!^AnZJ7eJNb^P|9uSq=i(Ei3+g4Syf_Gn>ouzh}Sj z{4Wx5BQ!m5)LVu5ulZF}KmVTsKh;jo{~*I3*!TtvjLu)Z{=GM&u7B9i_TK`|9`oBYr{}+A!LuB>ed_cJW2uP7e?Tzfe zy8m0+T;+d<;UBt>Oql;2o#Fg>B5owufRXpZuxQ7BnupeZy*2-b8vd8yKhY`kUv}jG z9$Wuvnfm?zDtMe`^1S8~-oEe@W;+AT|FdgYFgjk8i2!|1iTp z2L6-6{x5%0xc@Q{*LERg5FlFpEC03qzatI*EAXE=R964C9Mb9Uv-PiL?AQMk_@F$o z^?$mX-+vJJAL{>Ge^%@NqmBPp;Xihm%zxs*@b#b6FE`!&LjQfW`ajC>PYM57VgHvt zBiw(Ss4I?-`}=<|Ld5zX^51iy@_&rse+~W%LjOIE{6AppUoBw2{+sYYdE)B7pYhLm zl>S}nzo~Zo`#9sjAO2H^%j$p7k^cvU{xe&t_5ZPke=7Jd5_QV?_s$Hj|1?ooQt!3t z4!}Po^{=0QcY@)69sVmq|Cxi_^#2d}{*$$(!GG7Df2aMcN&Nbs8XuG=&VP#W&$moA zhPD5bjQ=;_KX-(z{s$cSFADuPZ>{S8M8iLgp9I4E?_>PuiMTTBW~u}6&uH~uJ^nLz zhg$!iZ1~@V|HP3p|LKFn>%T(~GE_@F#-`QLY1`0*bZ9Y2+||1*vMci^A$ z#PJU}I{qQ`-?5Ea|DR#_XMq1Kv7X}i6Gw&Tf1Ic*-f;LB2jkDt>c4va!&_SMpJn*p zh5rIkryPIVVd4DY6!O2mD6D_&U(MRD{}?_fPaJ;_<6lk~K4ogxPWf{5`X9RfuYI=W>howVDOZ ze|1c%`oHsy|C#)SK=jibf04=mJQ26wjw7KNlPRS>Qh@?EhQO319z}iMVxx5+fdl;gb5-{x389AHhH6iSysf9RDGjZ#_7= z|LXQ%+gmFC^M?Op@W+l1&Qp%RiP`@t5OHl6z^lUiPfxD+FE{+NA^)?&`uENa&;R%+ z)&CK~{MY`kF#MmuKjn$@pJn{pdZwng_OAl_>%V4vP@Xvc6yu+2zwL0T|5TI8|0|9E z0r*dyAgllQ(c$a=3K7?q|21L#H;qyJ;|>4p@LweAl=I)o_)m{g|92!7pk)20{ai-(UKc}ArL_fv(?>H}f{hue|+VUTT0FwIG{;xCqpTj@piR1T< z3Ge@HIjQNb{j0#f`nm8ydE)qc8UIxKZHG(!=ciKZzZ;DIFW|pK)G5bbVD|qqU87U~ zuM6wHeG0{Yz2To5{*%J~uj%~o`Y#i4ZT%mO0FwIG{_&&lF~som|4aC%JaPW}9M!+I zeyyE z+3?Q`|5;)G*Td9*e3bgXES8*A{oiW%zlMLx6X(B|@h=w4Ola+2#rNw!jt|Nc#~;5S zy#Hq~#DC6WN{Rn+?fEbG(c@bESKvQ&imd*dneCqn5myYZCVW#^|N8tte)PJ=KMwwj zM4fW}+Zg}pQR@GWwe^o5J+AS81OJpKj=$%)@c!S{Gc~=ne-+rT|M~DidE)qsjDM>A zw!^Lc<42Ec{=bF)+^Mqqj~^fIKXF=cTwDIPg!Qk_f8s~4Yy9*3NkH^doc{sFf1ZeI z%YPgKMC<>n*Z*mL)c_xT0en#HZ0)cFB5TX z{U0y%ula}hUkLnEJ30U5o89=A@)vJX_rDC|{}g>m>W<*&6mk5W_f9*MN47qrPTvh@ zlKR)@Kk=i_wftWgv9d%z&G9#19G?I2(?_TOKM@Peihr2@7VuN;rc5?h#hQD5)QOA?=>+>HE8~=-e z-#atd6URTu@aKuRQF%v>--Q8^`q%s_ppU*dKB#tb{FzI`^M7Q!8}BnUnb+VED^KT-)VvG6G2aYkt)L-~W>MpxVj#PhaN7zm#7e|9sr|Ukd!$vt<7J z8UFa$!EtT+`n3J2N2r{qxGlZq9%E z?xJn~Rr6o_$3w4c{(pjh$`j|mlku+>bHl%+{)@HyfAP@g8vh{pQ^bB6$KQNXc>Y(2 zxV8)AU19!femwNK#{V<;sdjSwOy zub{Z<9bOjt*Zg?sagG01@Kf#N_}fl)<6ppE{r!tClz%+*x5ob)_)CN*j-T_DA@(b{ z>A1hY7v29~`SH-(8vpO$r`l=D&v8iqF6Hn0Rr$w5Uu*n-fImj;r`hrsh`3Vj+H~&= z{cC?<5vX7rMT)H{$X_gL-#-H{U7}3 zSB-yJeLK79S3x@>g#Pe+p_`#-IBsrpw7+DG3J@5C3f{lB(P-R%F(B;?or zhw(3mg+O`Y{C6<^)odF6CH0?rL;1%;A8Yx)JoxiOo^t%X41a})Yr8$*FOz1{JBx`pF@)+{x!c^ z;6D1w_@LU!`EMKVrv9b;@tKu>JoKpMe--ejg#No3{_-gKKTGIe^AGdCD)^~(a{dPx zel?qhe@XeXJ?i>LJoKjKe>L#uh5lQw4A1{Ov0kxVAZH_hsQzpGssTXvR`>adc5?m) z?{IVdtCYY0TIC-PeX03h1N;@C|M;EZ{K+eV*DJRE&k_39{KNbw!B4f5^Y2|1p8vL- z)bvvRmg|&%JoKaHe@*b`2u~b;is3I4aVf5Pho6fPCH1fQ)r^4dt%VP&og9Cj;jfn` z>Uh!ltM`8d<^NuodFET${(sY#ZubA1(PoK%z5S1eUexk`ZTL@&5ALTp{}sl6mWUhG z_sH?ji_A~^|Cb+py5RjZj=%qFH~#00%wIkKul@VXc=`3e4n8PP9Dnj^H~oKf|LXdm z+WsGI`mg2xy5KJndCKwU82&Tci!(DE4B zB#ys(&+zS^k?|V!{~N(sH2x9(RYUyzUk@LYCyu|&_-_>N$T-pctLuMi`@gv9xt9Oy zgFi#$DaW6(?b4kNBkEG`SW?jkBk0l z{C;0r5c0=*-1xsp$lrE_;>SgQHU5pk?_Dj+|IWMJtp6?%@>gp7xahCOzX|wLLjL}{ z-T1#$$lpC)`Nu_nHU3S(pBM5sKknxK=gWlr$tx8tFTtU-;42n*Ygg{TFqe7RMjb#8Lf|;QFs2{;mbo`A=N*SL2@?{2AgpwZAL>N71i; z`zt>#`m6De0e^8KgAmopouj(I3U*m5Azjr0&-<#CmNct16pbo9q5&!4lUpuHl#ISMr znS1|FZI>#3Bz=v4D)6UB{&*;V`wedVe<9@WzD)5W>1+H`gFi3iA9Te3rI0^)x#CCC z*Z8Lae?`dOeWM%yUkUkpYxR$$uklX{{^V6u{fFm&>rHO>zZUYhUZMOW>1+Jcfxj%| z?{~ys5%PD9SNur&8vpd*Ph2hY-+8ke|KAAt3$^VZBz=v42JmNv{C$r2e*(W`|4;KH z>1+Hk@Rx-A&9}JmKPcpHzf^7iA?a)UGlD;UjV%8=9P$4wOVo&gK8gBo$>E7`CFI*QKm)K0Ld+?PQQ&RsuORN4LMPK8e z3I1c(%JM%^2haIE zyVUj{lD?Mz+roeL#^5^T{AccS!+$lDN$S6CIpx3E@XrSSDWU(2BmaL2{io8(|Llgp z9sV;n$@~vE@_&uczux|z!|)>&ygcbYeEYxX$iJWb(el4q|J}PQ|8pAt?chIsv&?_% z{ch_2TA_cv{XduCM=5y8>ty|Z>^3+2lL-Cm{(o-6zdih?Zjt#fIP%{k^sl%7=P~@~ z3cQ@qf7+4%NrnD(|39zc-vR!U1)2Yr2i)ZUbwdAo`#)~@(G_}Sq5py-|C0&*>;8Y7 z;olMd6SvCz=NbQv z^WXenIDhQ+;JDCd^|}F5V-eK-8dp32UEBU&!0=;L=w*feQ;z(PvGuQ(9MpR|}Br2h5xe~aPArjVDpLDv6Q9QmKp*1uY!zWOviC{JAdCmss#|0fXFpaD|< zdi#G-;~$%XUQy^jd50VRCZYf4?bQDNB8Gog_%GiXyq@O#_b~oTcLm3_O@o^dKvMsD z`+sr6k4<4OcB8ERbB_E^W$RxF@aum!d{CY^|AUNwThG+=QvZ7Ue@WvXy8>QX=)dg9 z|J0HFtNTA|_rES-_;-i@;@!b@%K6U}-SmGqBQYfPuaEyH3_o^-yn@hw;!ZdG(@6c- z?*Cod@b3Ztgt8r|78q6b_G4}CaV7r-~P`!@;|N6zrO!@S;N04{O9kH z`EPyLP5u{z{`L0%a)uwfLSCNq9}m6$z2wOMbVC37{_o`t|6cH)yI1DF;K=`NLjQXE ze+9#jLjhhz=s$j!oBW?%=wILezM|p(hrj;6lj{G%^S|X0H~hCp_FvupDXydTe=xoO z0=joF-iaAx{N4|4?tdPKHX{Yc`K{pz=}hs}?=>HqE& z`q%qEs~LVA3i8TA|1n3;KbcYJUqAn0b;G|m{AZ?>`Oi7>f0xj|-v3#{@Z(UZm$-%M z|HAiw(vJL(75dLzrPlvR!@m#w7lrg6ipQG)c`6BaI zw}15h-3_@7Cb|K4RP|JO47|MItgrjzx5Sx5PQkI=u~|69lK z<5YkbFHrqoxc|H(|1%5yw_dIMuWR`K4gZOYW&H8S-Q@qhLjQXIXFbD@L*ZUV=)dB~ z|16RHkGTG4eZ#*m{HKNWKUi|}{I~mr{`LM(o8iZ)Ag?I&pM2I${?97(udn~u!0_(} z{{^A{_P5>e-!Js9_kT7t{7b=q>{eO-*XzjtY(oF~{QpLVKLh{X^s@E8_l2AKe?aJ8 z@BeIU_;D)GOOyV?_kWt6bCdtgLjU^u&rJ;f{_vj?`j5ZkhW|mKf4%*`so}?|P|v$f zR{vQ?{%05Z*Zu!yhW|hCpBMViIP(9H(7)dPPZ@rk3ieV$|0PHM=ZNgTy8quXsk;6X z%g=xLUH=hyXJWGaZ~w{7`HuzBW-NlbU*o(gf76%=`Hw}E!i+Nh{-53OFM>8l;~#PU zXA6`6xD>$43-dqzyqo@i&dB*+<=5N)TN{2{3gA_Q{2535a|!wN_U|@^AD04nY2o>= zq9gvfh5UN^Z(GBUO98wB$sfM`7c05R|9K+wSNp&ADJJayPDEdlyj|A+b^Pk4|65Gh z|LN_&cHKUV_4;o|!@n~4D?h*XzHX4L>f0 z@Ny)7`1-H;MK}4sfRJDJ|GOA|TngcpN&a}~^`9M%_!kuN>;6A&_;D$Om$*lk|Gkd* z7ZUR8{(o1)k4quEtdPIyB{%uMu#jK(|GOFfB=}20{&q+FEkb_X|L<=2aVdZozgL$3 zJ&yPn5%TN)e-FctO98wL$sgYT4?5ysRLHN-e{62}55PgNitzYn(b4hGV&wgw>i%EQ z??0c0SY_e<-@xx~_WzcO%wOIAX}wGB|L$e{9|-@+8D!_bV(*6c|2ZNqns4=b7*nGJ z>VAz=*MDn%H6_r!gYZGMle_;f&G6UVz=$JC`Md5`{yU8SgTY@WJaPO5hCdMt&Z~&H z6O8@{hDiKteihO8e+WLPc5?h)IXwR-Xn2DLNcnSjD*t;M|DE8^5}r8z6vJO4;@U2T zM-f2cU-PR5`2G*Y2h~oFzmMU!<)o&U^6UQZU&jAo;E&H3T&Em=^Lyd>pCRH>T=for z3?oYXYkoB&-~ZwGpxVjtCmH^Fd7_Rd<=6e+zQ+F%;4c!MIQ|^N9~&E-S5bLKj{i6Y zNc?Ml70~y8BtEEia{Oh6e`LEG_5V_S-T!5b|D(X4COmQciTA_nzd*#bT@FtmfW*J% zR}Jv}AB_*Hog9Cb;kV_arf($w*_cW84%z;HhZpXjYQOF9We`B(zvnBp{qrA_|5-l? zW(w}7IRAr;{}d6|mj6jxe$@aU{TO^u?d15|K5*k-%0JN5JoMam?;zv#qN`>|GFLdU)^X`}N7aZmPQo{Ui-dE*+*6?>B2@~wBB=W{PM!bM`#;AUe%uP{n$`iN!)AWg( z{FnOI`#&cd|F{*{s|fw)9r<5I=s)v`TK}J5_)mrZ_^h)2Kg;;f5OM1+Tw=uMFkDjq zdjF@(@Z(l!FZqCM{onkWoBUta*1uY=e*K?@56Tl)|AUNwLZ9_useirybBghgTfx1Y z(0_*`|H}#eC-+e6|C0^>>F{49>Xh@J83@n+*lfZ5ifsZsj{uVT*W3T68GhUf@0ErA zdmZ^--qybo;Me~d_@F#-{)>!%ThG+=QvZ7U{|w_Fj{@)#4^sVq`1XHOe|Y{=?YAAi zLS+9Vj(?qQ_|Js@G*PFV|JG04@RzUvCH1ej|8s^Pk3#UWr2p{k|8__IR}}i!$G^@p z{5kk92>thd>E`(_F9`kX?fsa{AD z>;Dx5kkr54|GC`o<55svLFm8Vk^j|g{VM@}{a=6&$`j|m=?gdgpVYtJ|GC2W$D^=3 z?_sL{53m2!n{N2m5c)5TRp-C*hQAyB6LSQwr#b)ajQ=bVSEZl$>s3rCseirybEV&dwdDQ!zYrgkC(eJC@h=w4OepoQxBss;{x_Rq3eQVEBFq0?NB-9q`j5}7_eVO7=Ano(n~xl>;KEYxLNTckiO=|5n3~ zM`3zdq5t+@-SDq3^q;#&)&FgVKM(&Iq5pxgZtDL{p?|&of4kvN!+(kNAHMxxa^$~F z=wJ8$cNqRF;J+yJpZeNO{=X&kpG>RzztiyJQK(-0FL-H!Zk7}{CE_sR}}IOIO5+( z$ltn~;=kAM<593)>~UHBxBl*?{x=r#muvj@8Gbwp!%GYK3y%0V5%TNx|NVv^k3#hd zB!Bq&-}}Rj|4oJb`uz6;hW{Vn_lV=P-2PvuBmT{V{QCUwgN7fELd6E4to|#G_)|iD zeg5+y!~ak4r-b~;Ki%a2=0bjb{;z2G@hDWUBIM6G;@?8Zug`xyZ20#9fAR%c{x^9u zRG+7X68c}hwiNQ~{{Iofk4K?;Ws*O<|L<|czm<@`{Yka||ES^rH~14T%KXPCapQk$ zTmHukKOTkZWrh41NBrB^@;`3)_XB@P$X|5CzpX9*6NVp;LiI8)$?`uoshj+7x8;A* z@b3@)qL9DK5&w2V{@#mJ|JP^u@hDI){j$t|za#$bBlB0!|LEhty@vlv9REoRkN-4R z+-(27gN+R=g1TSh)bmgJS62J~PZ|CL;J+aBpPI}~{qGRjfA#oJe}~Hdrw#vA@Lv%6 zADopr{wuD z?PJ{Z|7lzQ!|MM!_@_K^{s$e^ztn$rPv!p=;~$R#_Y$wk>c8a3|E@y+di(!n!+$;e z=ZHFG{m&U*|79YsN68g_L^1r*#zux}uH~crke`53C^)%_pwEl{}B4uzkgab`~~>W z5OvD=FERK37KymF_5YEu{&Op;`v1W2XW`#_LstKtj{JAn`X5&Rx57W=iSys@sQ#t? zTU(X?kBt9g;6Ekw-{;8xKW+VgX!vh~|Jatn>uJvaz_{@Bf0~GETmK&m>%VIy<^L1I zkDo&EDnkFwQ@QE?_qO#vtp0C@f65c*KlQzv^}p1A`84JKQ{(?Q_)oqm>;H3({O=?5 zuYdn~!0_Jz{{^B>Isf_j!|UJMD!5;U*zxVH5_Agur7Da!xXh95tLO209-a07r^5QrovP~pJHy`v|CzUC z{eRmuZt_24>wj4N-vj@YC(eKNpm6_cHVyxh`fsgm|Nmh8pA7#+q5q;I|N9I5>+S#V z4gbCV`u{^&{$~yj_n#Z3`u|K=|82GNe?J+1{1lp(en-Y1o7PSJ|Hsz9b{wYsf z{dXM_?!V!MuL4T_>;1oc8N~|ADstRUJXS_W(X9Pn`eUq2d13Y#RP0^*?aA z^8dT>e>(i9g#Nwh-1Pqk3H|Hs|KAM%gYcgv>Xh?eIxO6OiHK{P5MLkw7D3&waq9lB z@)gSepN1blh3Hj;{!@OXO%@;}KGL(eVn z`Ok#^WLeh#=N+<%6M8&UTJqkoAZlKOACTKS*M z@aN#aEc9P-Pav*A1El`-_Wu~;|19`Vyhqi4`1XI+ z(eckih5q&S|Kx`M5%@0>b;|i~KRVohtUb72u}y=o5I|D@`u?ve4L^Pg)ytCpj*c|2LJX|8r3PC1L%?V{Z2U z4v$>_)#pFx{l6x|{}}Q=P4v@T{`Vgfp8o|Ru5CelE%dMN|C`S6p9}x-_htE?apeC9 zTmMRc-~T_356TngzxlXu|F)i~>81Yl{eLqU|L4JfM(Drj$p4W-|9by#dc*&Op9I?l zZ>Mqo+m8?TpCaN?Uh5rR!HAOnU*G>Xqv6L-VS7cP|JaOf`v0SB{i_A-tA7$7lqb%A z+X>-8CRJgI-Z|2LEIe*yf*KA`&l@cq9oNB)l%`q$gPV-0^F{O5@}<@~2l4EJ9l z;zsp7a{O;FKvMsD|8Ew<-wpq1(tr5=ProDoSzG^Vf%^6T6h0_Vod3>~!u^l*)~NrN z`q$h4vl;&v!hb>Nzh$hO{{I-Ef4%;n)$l(J|H;Gg|xc?jx*ESEnMF2_t>+S#9 z4gW>(?+LGe>2&1(SX=)}fM5Ur#RuhytN$G1U(KfBUsC^i`+rX3|6=&heNV0b!~6d} zNB)l!`q%6KISl_Z@LwkCl=EL^{O5_fvQ3EZ5I|D@di#HF!+#0UgQ5#_)q*m)qnW*f6kHr6NLUdwpY)8oyYJ$ z2mckKPC5TQjQ`|E!ONBMTJP}hF`}gY_4fZb!+#n4XG#Cz{eRh!{}XNfs|D@X|MU2u zJaPWxr?{zqvHyVcAGcu{#Geb!Q;t9B=>EU8g!!-cf95y&e>w8MB+UQB%x>0yCkgZ4 z+eP(%^BMjU@;^uPQ=I>9CjZMsTvdMJuOEc|_5RO7hCdJg@gHURpLOKF%htbI@_zsK z0zN2Doc{sFzgRFcq13cYWVsu zOT=aLvVZ;&V_*@~{TipPf7SaxiyHp%@Lv@AkI&+!|35|OUmyQcOU|$VyYNmwFZ16q zpBw&l&}NB$o&Ur5U&2D5@|5fU3QYd1*);r1n*Txm??>z6!r#9sFYLzu`e?Jnzux~_ z%+&wO@LwYODbBxlT6q5#|0KAsY!l)qTYl95zy4pr2h~oFKgICda#GVv`Std1!uWp` z{29U%$De2Ti$q+CtKQ**7*Ue{nqSSx_x~C`sCIJv&8LUwf4w|W$CL8w{(l+czaRXu zf#5pj_&XT>G!Zu{@5u3g#sG`END;-vNJx@Wk;CGW^NU zMyLLN!}5{%*ZgYv`u^X=2h~oFKeIr1{xcfIe~!*yz5k>CT6O$m82=;qcbt6wdHDH{ z(h_d?H$@;7|T6tN)54{?Z%u5%TN)zs>O92>!B=Kj(=5Tp_>i|2HuFH-SI#i!A@kj`+_L^6UP8 zL&JYF__IR(_SxO!|M^0G-T!Z7_-_G!iR2IO|4WYeFA(zU{(ob`UjTpnS6TkY=Wye{ zTgb2b|4j`4t>DiH`7@6AFBJ0Y{(n=$e;fFVLjIy7{)-~>SC4<`;~#3r%0K?|0Y0eX z6x{KTmWABpzx4QrUjJ=o{NE1$vEO9%ADhz+|HVT8nSZO}pKBQY58=N=9H-*^_c8wC zUj#2#YQMhT;r_#zun6jYjT?FW+vbM<4){+C{ihxIzr@zRT5^8w7;zG` zSyKOc`)_N*e;53FzX$hI9KSc0oBsbYTmNdg`t|<_J}6Hde^ZMaeyM-G{kyI4e>eQ6 zg#J^G{9i8gpWa`s|F<#x1MnaFQkMTcjQ=zdmniGH2Tv-jf4%*`o#F3=|GdzD-jV;j zt^Z;5|0$Lw<%z5RLB@aGLL-hS^{==8cQF3%f&Yrof5nmiD}?^r4^Z{Lz2W~1{tHB% za{e=mF#Z2m!Tm}^-4l#HnXvx#@xPr6|Gn^^{3E!X9Dj0dhJS*VH)g| z#|Z0RZ~yOU_#cG-tk8dtBmdXf`X5&RUt?KPo;d#%#y_FYda%^L-v0lG@&6F~mxTV~ z^SbH(t`+)k`j1-w?`8Na@Sh{ALIXF_|K63!?*tj9QnUa=-)d~)&Jgx z|6BM^RD##joc}E2KTE_NQD%|DK0jY59C{j;LrnZ_+0H z`-e}$e`->y{=?UQJuAB5za_H&YX7JE{{v0__kll8@`v~TgO2zMLVn%<&20QX4gTb0 zl>c!4Vyhefw+Z=m|97zQ|6lOug#59U-0SVh9p9Ozna>{>r{TCeZ-zntR z_1|gyKj-r|Q~cri-?FkB|93^^ude^%H%z$xdm3wz{CF9EN57lrUu=dpV-eK-s;&QY z|F@RO{}TL{g#Igz{P#xoUtRy{{_k*;|1W?)KD*3+auqlEe~*w~AOAVR@V^NDjF7+A z5&ylB`K$G>_y1Mp_}jnV;e*;w=l1^xnf?E|3pC=0(f9wW{E2DR^^f}+|KEeZL>#B! z_=`)1=YRa0;Qfk-xD$*%71|uF{~N)tBKrP+zz5Y%jz6|kIR69Ie z;Li}AIQ}k2{8J14>-#^BG5kLvR#C|BCEWO*M#!)4e>m3g42Wh*c2sCmkLCnL)^}um3y2@c)Wf-gmP6?{&l< z6Y}fppH4LVzadsi$lr0foBnS`A%D>CzwZY9m9J&L|CajP&Hmr4XtQMdM_>PPlJWmL zmStY(Kfb;j|6_&z_4)sk4gVjART1)+?w>aBym^B*^T;qW3;Ff_&nbrgPsB!g>`p@<# z|EC-NNx+{K^2gf3{g;TiWMS9&huI?Yk9hvwk%s>z9RDej$A6F=nAe|p1vRbg==jfl zk&pk3IRAB~;eQ$Yu{mV<-@aJE#@3Rd5 ztKcsP`3D{GKPcqa$G^`u{I7xEn^TtmZL7J-|A&P9`uO)bhQA;DDItHiBmQD!{_641 z>?-Q|_j3*Z>)_7|`D3fQ@&9mS{%ZfPfB#o?!dSI=4`KbEKS!4TnTOo)9}{`~Kf?cc z#{V1eUlIE6a^(LJq5r`<)b`&6hW}0QC+Cv+?{~!is4aiD;eQMKIU#?`8gBCcvFQ9w ze#vY97aIPz!Cw~gryTJ=9+|&d|K9B?|1UE9?|?rsw=Dnr82&5~S9QPQujeB3dqe)) zFID^(8~*pepP5I-F9xuj@ElB!)mGiFab9eQzfimXBFISF_`}?Vp`K#MMZBwZ0zpgU;pMgJ1w9}TK zZ z_`d{yW+LN%SjwMK{5^*MEASU5GX6(|{5^e&|2o6}HTYu-OkDZ@sF1((vs(XMZ}=XH~NP@2&NJHyQr# zz+Y~bUH^e*IC=G9u2%dv8~*RXpPI=0KNXq3di+!W{^uEne=;n{c#ACm3(WN&86vK2 z(liUt|7d>I0EF=-2S3$LuK#b@z|HZ0DZjq{vtay>0e_M3#PR1D{@5bHd1dQ=cA=mUBI4TmpG)Xp^AGbsHTbD^a{N6Ezbz*q?YA5GEwn;cY)qdOIQvS@1%KyE_{|w+S z6P`H!G{c`*JUFjx`R5h-*Zjl$$G}guljF}is{iQx)$9Kfz3TYa{l@={;Lj4CIDT)_ z@cb_kac%vNi|l^{|1ke!!B4f5<4-aCww%=TQThEi{<^OA8vgIvu+jW3?u!FXcumL5 zWT;)E(718x`H%gz{D08o|4i^7Un01l;{10q{xd{eW-+jTo)60imw?s%nt)$T=`ZS; z!B4f5;~#X?|3&4mdqMqwI%3U#>J8QZKWy@U7Wgj`dCK|kWAZ>w}&8FdBQvZ7W|CGu9RnWTJYqI*!J{?~FiT>cYwhP2x z_e<9Qdi(Eb!#^kd=ZQMy{AU^e6(X)J|3bF)|E%F(4UH)go;d!@f5ZJ}ULPI*lMDUp z<3GVf=CUr#x}|&0o5C{+G4?mrVYz ziDi*`Q&#_}XT$5iLc~>zU;O1COqbNZ-v4>o@Q;K4EK#SN|F-4A`~MOVR}8KuTqJt^ z58eN(uYbM8@c)2f%1>n1fBMgCgSNU~4O{*<4gVnclM4l}r@8vCI{_O!;+sPL-anQ9w+#Q!;LlBD{BH^QdnQx& zzrAhve*u4fBD??PZCn0#4F9j-FHdCt-x2Z;POkjFYxsWyf2?)ls{eOw`OAj?ckrht zGXAoVU*G@rp5gxk{Dp~(|2-jpevHch_YMD_;P+OVxbpvfA;0$jf#LVCGm)Ce_&*Tx z7ba2uKQ#Q4fImNx@qc8?Kj-B7_unQ1e{$uCEB`+c^0&>Y{C{lxPY(XvM8-c5oquXf z;_2gG{f2*j>`2C!k@@djA$>cQ z6#tioe-ZF|%LUgd=fC2Jf62)F)$9ND^$%Ye{zbu`67nav3eW#M5m%D)!>3uwmR|)! z7;iD~Q|;vZr`K@P|4I4NZ>am9hVlE`Ql;%>$G>~Gcf-F6+AKN$qp$z?+T{P@@LwVF zl=Gis@;|wJaKEA!zxXR5%zw?V=IrPH65yxW$?+%GbmL#jueX1`HU5_be~$3P@s}C@ zWg@Ovyqa)np?}Rk%>Pp0r`pN!$Jch_U&^o7f8QJb3GgRY2(D9(KekRdf0l@A>wg)c zf6YJ4|I*;6+R5>I>x8fWZ8@pwrTo3ys_nlYjsIo9Um`ql{LSly`!B2?oL3ZAy~CG{ z?7zDGuYdna&B*Wnzs0+woQE&Cusx7XB$uoc|o-KPp$f z<45xbum zo`_p_!-)}>i(LOz|J`$`Lx*Z=YeM0w);XBq#a zwIHPalXENozZ?Hk!hd!m^Z&Wff75nq{r{WcUjhCrM4fW}ON{^I2Elb@n-|Lq>wlo; z|4+l;1plRp%>Ng*{*?f~{#S&5$`j|mtu4I&xAja-FZG|BN7er%Q|j}dQ^9|H)!;nk z_^I}d_V6z;gJ}K#$n9Ul--MD+udf`=8A4PYwT>iOm03*8Zyo z{Q6%B{wYtK|MUiK>R;+#U;i@3_@4&;ixZjucOXtu|N8m2lNWq8tw=P z!y!cF$g;bTm1Q@u3xsnrd-lQ}VP_YbJ0M3mgaK5-X%v*8B7*|YQgUs(Rz z>)#$O|GN|Zt3Ag5e?s!#-v51f7k`HEKN@oWmo)tMEtVfwqR#)OZ<7DxJ(mAFhRpx=`!Du!@h>2{VrPU~|HsPS{O1&UA^k!ZCx%@A z+Q+|_yZB#B`0vkz!yg(z#DVmkeUvu8KY09W^A7{*`nQlMQt_ml|9!W6^Y7QcpmJgP zZy*0&>GJ;)!hfm9_^0nI48wo>{U@(*@t;Z*RTcA8$A4MF|AazsP`*X^lS0n__WHk{ zi$6j5AL}vx={p-E@ecu|^ZzuWNX3(m|I{6`GylW#-(LR@aQWYd@SmL5TkAi4XJr`v z+xI{3@8ZuAMVTex@K-hb4=ePF^Eqfe6LtO{epE~?eafBUD-&q?h|Jmn%ZT_d^|LH`LiYFcZ5e@%g@#)5e<-fiD9q#h~ za>9S1$M~o3>OiPqLN~s>iADxiSQKI{%Mw@xOxbKhk6T z({~m};vWJ`!WcV)C{ppHSF=YPM;|0@aqvH88V{?m6hhvC0{{d1&? ze+f~P%!R|Bx!8OD7ZrNL@{Z%?hn)Xy{*QL?Ckg+#9^;?BvpN$05J)=zml8!Po^}Q{HO0MkHkL^KOt{ZKY9E=M&p+N0eEv^<{?WevIo{>}EP}tF zSf_OSw>0@bqR<;PKNbeZKl%Abd;NQzi~m59|HD0&|GNjz|4IDA2Sfhvv_t#(SMn;< z*w~Z3HUGaB5`X*iuLs@zj}NBDzsq{-{D;1?p8WIuL%#o?3I0CCK4rS|AKwdbhXv_7yTjmb=l?<% z|Emf9LXY96@2n1kzn%Z5y7-SE_+ugWzv(cozSYrpHiyCA&i~U~{6`Y}xpRAK{ogkv z{&xOnUHtt7f3?T((|0z9;lG{#i(LFi5&RQ9hM&H(I1K*WK5+lT8(jQH6a1NcZ{5d6bEhCdk+f9X)T{=M40{v}(%#Bx6i_xX?S1-rw7yOM_=!tmeD z|HUr<#}fX>dyIej&f0+ZCqMs6JT?9EzdsN~$&ZBNKl{nq`TXyp;Gci-pZ`HV($Bw_ z5&Wvp>2&A6#e(i93~@Q1{w8x|IS`}yxPUH;D@_;Vrg$5wdrUsdSU;nVeJL-OCo z4+bdz=MwxXKXv?9HTZQn!uE&7-+umgnah8k;GaCJy;S$F3DqLBQz@lWCZ zJc3{4rw)HzgFh_4x^ZFgx1WDI+vWd!f`3@SlMa9XDsTSB6?%2}bp3A#$$uL^7@+h2 z0)k)Vrw)HjgI|XuY=2n%?dRXlb@{)L;O}29pQk$f$<^NcmlS%#;>K~OhvdI~{6Ejd ze=)&7rtnjTKfT5qfAVa3ToFgua!FMDV3_9r0Ku>FQ-^;b43U*)F`e^rBDha+r%Sp4nd|Aj99D+vC+ zbL8_>hd*I?^IuTt4T~GcP%;_$R;rAIH!Cmbm=C zhJ60he_lBLJB`b)zWoVjHJ?!6G_37j{o%a-s_)&zR1mC`5(jm-&VN%A5Zun z>oNWh49S1{{D08JzlP|_tPQvRRleXo|A!TNqb9&vA?Lr9g71G;x%ktB|K$1M@JGcF zc07G&Ii0qCe{lV8^A7{*{9j8Hsd&=O|5#~u=6_iJ+uwh$aru8O;lJ2p{L^=~2jibT z|K5K8>uMLjMHG!I=BbYVoQD5?OFpms=B-L@dC2+S{{G)`@xPAnKiXsb(|6WK;(yBg zUq=+Fc+&A-)$p(4FKT;O{`+19>;EM#|F0+f_gx^*Qyu=OIKqxkh2+2e{@-;j{!56i zl473f@K0#?A5-WJiyOzC9diD+&;QrE_)j4G7kZ5US4HI?0!femml9nno^gB{!b+QkMtP-hlb?8{r=|-F8=jIS8`pr^>0|ie^H?q=W*EboRIUseg0o` z@t;Kak6joJe^~#cjyo(W|KI?f{~L%d6;HbPpZb#b^ zbyWT#&~*N9BDz#O>G-c{`1i|aP`R-Dx6l7Ccln=3_@C%8{*MUBe`!~k|65)BMWU;q zn5R1alW+8%|04>$LHQQt^C9Pd`~2T_@t;EY&s-#5r*!y5zhF^gd{C6uJVfk;L|6k?uKcDbF+++OrhveTLgZH0b>Eho^bj2w&p6)Ke-jG5QR8!d$oXH#&wooU{!-+L*e}QMwkE72>)X}#{U_C z`Dgq8%JzTy3+4Z#;hz5*`PA$@|Mh6#`Oosd_-i=-xxwZCa)LjzKIHm;v-k0DSfSVV z#8n7h5Ewt(|E8V)H@Wz;B>$5GA@M8x>vl8Uvy}Yv{e$aYn|~Nd*S{->A{9@%_0QJu z@7uwEf|2>Z)#ZN?;lJ2p{4Wj3e`Xb&|J>r@w~4NC#XQyV?`Zh%-yok?0qLG5eqq%4 zf18W{4TS&E9^;?xSxWx-{=xmf#t#Ah$p+GWWHg=sO@e>I33vSS?LdbGCj#SV$G>*| zgFh7il|+{+Pj&g9xW)VU*J0Rgb&>P`4mbZ#C;aynwx z?f*CWH}C7;Aee&49#4eBy#F(P81R3W%l~4M|AijQf4XODr2L0qQ~s|eid1>3%m4VT zv$Ot%$p6XbAKIUP+~e|p2H}6C$M~mvc7)+SSAgUH-7fxXh@#}iaO;0b!+%ksH^^L< z$zB|M{hQ=}1n2*KF8(Ei|JYzS{4(EWqK)oZ5{Z9slFt8Yi6RwGy5oOK!+*D85tje< z`u`S}|D}ZgT#xZj_iPEne`O`i|2Mn%uOo^^74uZbf3fVn{`YN?&#S0;F%WY8x7Yvs zUHm!1f3?T>r+d~!;(yBgzn&;k@ucIw?>2A#qw=g8AC~|2`u~8-|CxmUi5}yh?%5ND z|A`O7{I9t9OGHsYF;8{;mo@y4DD-)9#y{P&DGdMp7R>*LUHmsv zMa6LWpVRQ4Q|OI49|l9t|2F?`bMY@H{Ezn-|8&o)Nc>Nk|8FFUR6ObCzoX$lD$lC% zk@M{Q5o@J5v2LkBv|7M~{#gmTzx`zL#Jgde>=Kq~8|K}3^$9jzaivsh{ zzW+*p81Dag+{J$j(UrL@-1-;4(|i68EA*;(_1nHO>imDg#h)kqCs&2T@7Lc>%h5gi z$Uomd`@#KhZT?{-o&UEIMJk?j^S@E?=HIu20R{~j0r`Go(`9^=0dm4ApRo&UEHT`Hb* z{O2_MPb02F4UzeO%H{t8!hhdtd7kRl*(1w#esIo5+xVtc^PVKjPvq5dNz@#y{P&G!p+1 zcRK&?CW=%%>G&Vl@E?+1?XbxFf7IoFknlgzWBk)SOT+L#avse8x{H69C@LuCsgD2t zhrEyfBMQA*f;9qG)cOB$7yk;v|JW7sbxMa{<7U^o>7J#L_y^DE{J)1NQt_n2U()d3 ztpG&k|C28ND+&KeySMnKdzOabKXw7k|4+F1@1=^ihQmLm;XkL)8#OQ1MVu-w^KkkMe!q>wi?9RpYNB9l@UeVCTQ>{0GGp z|9vEosyx-Le=SY^tNf4J9wPrIpZ{q*0pI_Ry7~WRg1@Smr#k%QmiOm>6AHai@m~^r z{`2_30m}bd2!55HI{d|lXD9!I;}^dF{k+TnTM7Qm<>A)K z?x*ePdfb0-@WI5@m6_Wsc`viUmueHHhwTf z=l=r)zsgS?{=y@(GylWlZ-4*excomz@b{JFJn8U{Xz&*ldj0aOlG_lH|2F<9{69qS ztNhgAZ)otV{Eylm96vk%OFaq4|F5|GKTPnCD0tH0ul>_|{>N^U=T%hv8w2w%;Ge?( zBLu(7PaXd1qq8&rgX0&DfB)t3|0uzqQ}Cq2KcT^2Rp^b%|E9qF3;3t-|2BeO<);pR z;%&3Te^~tO{!+{vf9Ce?%>QCY{@eJc@c(v#U*)F`e|?tt4~xHj z{2O!me+R)otl&w9KVJ3be_WwA>ioYfF#l}-ulDmFpKs z|EG=rTQ2@J1b^R^@_DM`-?sxD7Nqa&h=l*!F8;Lyf1$_l(|1-x!v7r?zeVtm^ca5n z&W1?%zw6>(NASn4>aF~z?<|Of|9dX}O9=j4kKr#y#ouu8UrO*-dkjC_vpy34-*@q^ zC-^6N3_snoJre#OxcD~^{F$qJYyQ(c%Om0cp^JYb!9Uz%`01YAk?{Y>#lMN*AMY{z zbkFKY_;qL;s1$?|1yHV)MNPRp1qOq|J235ncyGmG5mDT+DQ1v zUHn4?fAZSi%740NX(aqVbMbE>_=`P;pYGWi3IESs{96hB(H_H3_iT)W{}(R)%L)Fz z>v}8y>7Ip=@c+`qe+9u`=rR0s&%Q|bf92x03I35D!%z3Di-iBbUHn%P{ITnMEC1=9 zZIST*+Qokr!Jq3f{H3V)n=byV3I1x2;ir3cMdJT|T>RG%{1ZKfpYB-|27e9r|N4!K z|5}1SQ|hhxPxovJgFkl!?0@#ZF8=EX{^1_OPxmYegTICNf9vAEp5PzvG5mDTo-p{^ z_kaG*#a|-$`)}y2{HJ@?gu&l_|IhDT{5KH%r5?ji_iTxT{|_$y8wvig9>Y)fEQy4F z!o~kaf9E$7X5% zhvmP${{PkG|5n0(p~v{A&#Z^xKlLJ*|9^4uzl$guQ_NEx|H-#|&;R6|@_7|D?{VCg zsPn(&;x7~aM|zBZ`pkMH{-@0UCx{{yPdfgK8vc>5PM2Z%Z_odKxcuKn_>bKr&r==# zPUG^ck3O>=hW}(A%>Tc;_-jN_Q87<-_?sI3M-_Vg;#A3PjXMAT<>J4c@Sp23{^>L8 zk@$ze(&PV=M3IUo9slWfc(4B|{-U;rN$|Kjd||KBeD zcN0Z@Zwj~mjcE8UDD+0<|MI}|pI!g99)jop$xR>l{?{+=OuX4K9RB?Avy=btBM<)v zd;Xu@|388GAB(r~-%0X+qQ~-|KC>Sw{~-bC`u859NR_9$^)FMO9sYyoKjXi#AI$%q zT>jrg_|M!NF8`y>TGxGMs$ ze~kak(SUzv7yn&^|KT3vpYGWZiGK(ro&Qf!MGBsD{14C4{13~26ZwCh%m3Yk|M4E< zpYB-^jDKPO*XO$U-$xYXLh>K~sQ3C`Rp`Ze9JahNy$44 z!}=d}9Nn`c693=;o&Qf0MJk?j_)8l8qvBMJ56gf0Sm6JKF8}us{!2Z^Ki#t=4FB!# z|6kzZA0dh+6!TQa|ComV%-!;NrQ+3Z`&A+5fB$j7|E@0ndkOzzJ;p!Xvn3M$5NJC8 zpCO7=Jn8r^e$0FQ_seHcxv=~F@{jyHoOX&zdm&xA%X4k&FNR zMA5Kfp6c+AYWN>l=#3hOt3%HJ>X9)2cX#o>neac_WBk)SdxG)LKL2T~g3o`*Ll5}* z&zH&PKNBH8|H-CjXZ}AE^7Eg{QNaJ6F8^;K{Et5%KThfLKWZL_9Z&Zx3dTRX{vF5j zpS@lDZzcHqAM7psbkCwN_}laU#V-E)3I0-#;ir2Rg~8v>|ChMokKwO|#P1vg z^FQI@e}LdmKGa+JPxmYe!+-npk9}PH4-)*v9>Y)fEQ*Bxr7r%52>#I?!%y#741>RN zAngD5G8g~D1b^Sdy_Ns;p1nx;_jU03I5?8!%x4n4v2qp z|Nr*qUvS|~KmYsyQKb5uN_YLA{`l;C{t@EyFaG@pd$|06kl^nh4wwHUk9mLpUsC7| z`?&{>yC(SOe?0yv{C|kxSNW;qKlX{);Xf??_Ws`oyZnEc;2%@)q{Cl(mpA{(d*peA zJccc=4at8S{}lc|Lh!5n)Zuq#iT}v>Q!f8?g1@NXNryl4N$>n0Rp<@NJC3`qgZzJ# z;8*#n!(Z3nM}IqA2FEY#e}1UT|HlaazI)~KREIzQDR2G@3cXR|aeZL^1^nOuQ4{+( z!LRaDhd-~u9~Gx+d|3SL{m&0~`TqpLKce7Chrg!7f1fOay#JAOmuvaQ<&fb{??3#ldH~7_n_E0vW(F2J_#PZ2oU=aoEPv+Q2apFcB~j zFcB~jFcB~jFcDBhAbElJ_wSIu5w=;fKaWn1S5g5InUH7)7Dnh;8A^ahZ6S{TP zOu+Hu3i;$)n7~oK21<)ARE_&8b>z#=f;r@ z@FwfzMIc7T?}5f&S4y8BlnEW*^fX5T-e_3cQJU`{Kq)VekK|ZW+MU_Fp9?kQ}V~f?Ij+w zk$cAG>_;F2F5q#%l>BjVdx^*FXQJ_7HX@J#qj4v$5ik+ht|CBQmlgY` z1aayvSa3W(a=`#L5ik)j5ik+hej=bc{#%;w_qU%28Kfox zCITh`CITh`+g=1z$A8Bh|F=D|4I&c(69E$e69E$eh=A(&KYV1g`{zx7O$1B?Oax2> zOax2>=57R3$Ny1t{GYp|8P7}vOax2>Oax2>B1S-U{GWj1f3Dwr4iGWKX1IxfiGYcK ziGYc~oQnWG{>z^K>x2DoN^txifiiO}J0BQ_dLHUUD9cdJIiSWN69E$e69E$e69E%} zb_7({|3$O^T{}kR4-)|s0TTfe0TY4kH3H8ez*mvq9j5%|U&hy80Kqw*l=QrU{_I8n z2ZNqV{!Ee%s)zRPNPg)U`Zt!ekN!Q?&eXph()SATnfvOVzopnYd(r}Ff-2|m#=bo@Wa@8Lu@^)*BOPLf|LNPWAL2vK?JVBaAO z-!Y_`A-_}?ZKM4T`J2j9ebmn!DW5}rsXx>Y?5DESE|sa?vcu$9POvN zjwZj8@g$b09{NjTLGgZ;jG@1$lE3i>W%|$Ec~S?pMPy&ptk84`a?s2?X;x6(ccXDrE#G07?0oMKr9146J=Sj6{l z`7mKbOax2>Oax2>Oax2>Oax2>Oax2>W;g;Rus6DreV=Md69@Xey2*p>D-ULP*)ir! z1WW|xKmcxjyy|gE*XFx8w7pwO} zdtq;ohxXBTv-%kHS1YVOz5(<-AI86km8BupJ_kY)$%W)5hNB8`EkGP|P>(@54sjgb zgW(^AxWyi2<1;H+ISl0p#5W0ijKjDQ;H$bj)02Vr9MmVE96o)|NnS^BJk*oGQy=Ib zdk)i6+?kc*aj3t5m4z3wa$*-&#-J=bm(_ve)%zizMgd13_*3YE@leJvZjhG~kf)dgCCJY)D3iOf z@e^-mc1jShQHamzJl2on{gye5r_TWyh_g>|BQ{4OFt&}Xb2A;ziIr^q8eYZ98MFW5 zaPxV_{EKLa-v9qkiH;)N|CEUShQBSXy ztv7Ao_!FA^>{VX<`km3tU%z^cT#rWJ=+4al$}yeM)1y%|Zkq_02$%?%2$%?%2$%?% z2$%?%2$%?%2$%?%2$%?%2$%?%2$%?%2$%?%2$%?%2$%?%2$%?%2$%?%2$%?TJpvQg zvFE(dQ1MW{j_vL87EM10PP|GkH*zFv?>~s|FW$`8M}>a0Kfa$Jw}sV9!ua8Nti1|& zsu!_(@)~~pSdP`l4hMPAH=JShVu_XGg8mHj=U&bFlS8Z=xqy}Z2e5J&;xLkhI_MiF zFPx#zmx({4^I7}o5v(jFSve-y7sp|J4B|F&78^GLl{*mh3USVX-U8@Ddj*i6fc(Jraf}n-!1fIA7!&ko7BRb{3t5TseTw;=gYhFU zuf{;{7{t2@@h*VhBjhDuG#=v52aA3OD8k=62z+r@lHa2|CzkLkrP;b81R;^ z<@=K`kNaU>j)Q-rr}A<+@T2V~@IMCmF#_?XFL9!HMxZPz*0&_&V+nX3hkVVQ1peN@ z+i%;2KPEKmZx!0qa0D$IDmur{I4M^ydV>Mqs_jfgc4Z z(GHd+@V5`<@2KEU33$%*Grz~h^#l}+zmfG%K)#NP^9}NB0`hnQ;|cMrLO!Ek{UxR^ z349b_{TPS*Ekd4UVEj1bdlBrTo)NHHfPQQ*p2qa|1HYq?=S9fVlHh*<>{Vet#g1g- zV`9AExPx}E9ESYshk4ouevPAlfU_UwDUPcu=1URQiz>vUU&!O4u)fEHb#V;*PU5;O zh!QwND>je1I54`6}tiK3(iuS}ZcMb3a{*FWZCjd_-$@()l zgFeW^0`QjvJADxM38lk)$k&(<|IBf`pTn>&B!#?)!8(xve={)ebC7>YoKKMN zIU#R`1%2bt-v{~%5Pyu5SoY(3jq4f+B*Bj&?>cjbs>n$iu!uXu9ZcKpwKFHe`%&UIDGYsc71<2nqVVCt_6hAdA>T$pUkvytz;PMvie5h^SAH9~R=)znS^h2l$H_ z$OnPq-H5!S*V|c^LSq!a9)={7u5TjpMM)fP6`aEB0eK0)CFddX$6toDtT`zMC1I0>lx= zXY#B)1M5o>;xO_?h#TlFVty^)<5B<~Mv{E{2>4L|ekZPH{SyM-KJcdm$B7t>L;u8b z{94{lM!?f29GAwxzka|W>KlQ48x!(1cMG$Vf%%Yw@ncZ-!@66AxW-_Mk>MEwzHnRy{OSY0`ynq1 zzzfRdg!LNR#WE@6(=h1oKbYC?7xUaMo+`H1Z$;1TNu&+;5L4OJgI}^hCQxcBHI3CN1o53!ugX6FsWMI9D z0Ur|(p9$bG26IXmifS(NLFD5}R;Lcpf>U|)e1YXfzALuWFo<3OD zhXq_En4iN?jzRwztTUr0FgqiPdD#c^eFFR&0~}Szck~C#BJ^i4-q-=>6XU@980Z^@ z_9FN-A*_%65T6XJH>hqD*WYWH|5dP?1b!w?X6;GPmxQ>ELmW!rM*;F>1mfKf=i?)w z5A9*u594wWuMFtJ{wmk3ez~ z|1LWxH?e*FF&r84$BwaGc8(?a_5!qz!h23gb@Hb~|G(odJ6G>z^7Neo1@c?^<4&<1 zh#pbCO4_M@v`gj9kBNYZfQf*KfQf*KfQf*KfQf*KfQf*KfQf*KfQf*KfQf*KfQf*K zfQf*KfQf*KfQf*KfQf*KfQf*KKxZS6d2+W{UuRVsZITF#5APz4bN}7)c8LnpWFlZ9 zU?N~5U?N~5U?N~5U?N~501?RDWX_{aGMEUM2+XYrOqlEYxkZTa#zeqGz(gQq1d{#c zJTqkI%rFvx@?G7{A8Urc&uLb>i^n9*>_(vQ0RLR@?0TcOUQ&F|rXOh}Oax2>dL;tG z+xT_0bIja0uEx!J+R-Ud?Xlx&N5LCqCITh`U5!BbsJU_6=qkuup}l+x4p_s9fzh-fqzG=@0oEZ#~I)vtGjF6Tgx3sIy;F z*HI2j>xbU`D3|&npa1z~GsB<#5`X@opW9mL{GE^cOyg^=;`2Xy zCtvThKi0lXfAcG|i#sf?%9Y*C*V?DLt3NDm>%SRa@oT!9AI|G|{FNJKW*rI|m)2W( zKXH8eK6yL#&$Y7lhtBd@d#F43?fawULF!y@oaNhizvHiG@|DGWd$;&YEn{|COPO8! zC*J;|AN7(yIcp{8zrmk8>W^AB_l(9{RQotS-{EyD|KniCua-i-@^TiR_}TJ2vk#NE zBQ7ix7yFY#`Cct+4SC#~-YeLl{v|AKiKYH<&orLeE%G=!NqKwaMcvK&^4Zvv& zzZHz%^zXdoTSv*`uk*jQHdy@ZHR0^&{OELl`82to`Ft?EwTtC?&|l|`yuR#!w|wn& zynOt>y?I4Dy3+Y-XY`<*isHPu^>cs6Z`3o>rS*Z%#-YB#n@_*^;!Akm{f?VyIp@#b z{5GE>$I*OJ-ri~dn-BB+#-Cz#ZDAhj?6wwmhF6`PY=Ze$ffD7LLLJ+&Oz+c~cs4&6 z4rgj_-hSd&eB9B`UN6(v`HN3^7ao88CO$r$jzjkCyuH*<`MNbO)c?%t&h4yB{gUt3 z`Bz`&FAky}Ye~3qq8_nsk9)5}qI{?7>8}KfTUfiP&wAr)J*PWy4eM{zan3uU;c5NW zJ6<~fDhD!Nvqv*ODp2CMrch76m(PRrG12@-JE}7NHD)jMH{MQa32S$tRE@`WTaYV% zjMs;9oi3aA^6{!4>Ti9l!}m6w_NQC=;-BMjHhkW%&^VCskouE9KI+1K5#7RrdRu?t zab>UY#~+SYmHFj7UT2iAtHyUgB`D1aQs7iLCe|#fBXd1E6TS5UdLCK&WvB^r&a3? z|ERzI378L``<=2=e+uxwkH?=E>Y}~GeZlgeu92^t z5)NnnF}WYvSIPBN6zw8DUA-Cce4_RZ7Vq>7ecm6xSso`9&dNqUA5?Ox_S!~y{87HV zC7OQJgJq@QZ4c$5mieQ3JB=b=530W+TxW>mQ#bSa^N$AOQPk(RZhe$L-ep(Lj9vS} z&gKQ;t^bJOshq>d6Z^%o4)-66?P2TnxB0Ux>aV=Z-#F_Ue{!OJv7Y+3KRxk_SU#lI z`jb!eGhXeyw|xG5?|#wWRzP`iJl5@ZdFOZe#lieaDekjQ3D=AD?*z;D^j_Y6X8*$L z%kRegPVdh9pHDEk^kZyZr2Zd2F7;Zzj&Z`$5#+Ibrpm_mc|2&>I?FpgD7USZ6}TQu z?8)NdJPh;mQF)xwa6O1|s9)+Gx7uOe{isJ(TD!CHH+?=g%#F!s1RH6D%+4$MW*|UHQ7` zhjSaxe|ktRp9uNAWcCX)yB@|j@OVVLs(S0ZaN|&4c0`_Ui7X$_#F4C?_IW*62YG9b z99Ix8mUYedAJ#!UejF#3)))EsS6^65+D{k4Gi>p8z-xEt`C z6#9#$^D?;|>=(=WfBEBC94FSxx3YQB67Jg(<*;s-nS6X1E6byDKN{zI&$s3=@^NU# zZ<)Hl+m5KGEclhbJ=pm8N;yyIn>vK&B)R_V{=xhdajWX_l(*mIcXr1v`cr#QjyG`? zvzvOr+dtH!D^u6Y?Wo2zci`>D@8;uBgL-@sYcKD}%a`wA?JdRnl85_*MEm(K1@luJ zkM-JXcz>~7Rc4P1Ca=(F;d*yzM z{xpBV&(Hk3__`=B)@ytEvm=gcep_y*qIphL)DyJcXn6Zut}(yzKKFwNYTvJX>wAp% z)Lq{GqCQJ_?yLUEV0mNxCzw3i70dF!Q4u=TN?=`9~4LG36_`f&3t|~;XFj8&w33nFUnPf{W!#a zUA=i8KfmjrV{xbne(LnhRDbgT?|20Dqxp)?>O=eG7j{Q)+~@Z-iTConqF>!AZQ;3j zw9|Nq_oMyS9#_1f{_ z;#S@&ALp!>x7%L`7l-;uJTJAXTz{wHVe|xxKtAC0U@M?JdXxQNu>48y9ZbHt#a~_} zUd-ns`iEsX<=u~RSf*a(E${p*7!K6ye8wLhln+|g;QU@SF1~=_O8rKD9+&@LfBxB; z&+dydaq0t)KamuguVMp1Sy``YX43 z$4xcPZ+i>woAE1OKEQka`_*IQydzK<4i@J$+@GM*YCX`|JSxARUsqIivEBXvlh6Ld z-?*~o`J2SK!Q#_=LT)#%*zY|B{-Xa_T7uoQa9-Ky(sf%pq~6By!QzBC!-`;vP*11JR>XZ%hwB3#>4 z^fwRV!sl0w3;Ff1?(_53X2|ysmtV`o#nUS~gzE zcyO+i+l{JUH@*e$39x*=2SKM#?5}-O9_NN)zcz8a-@2{1A5G9oT~0TS3Xa&!hS?{i?>_9ndMXKk9;1h?D%a@z`oOds1_=fPIbg!hXP6&G+dEVSjzpCzk1Jy?LtqjO9}kO6Pa1p8h$X zXQ(&3l<6xg`cV$cCdgymZ<+rqpC^fz$o*02OTX0{w`!d88h-w$sN?LOvr<2^jD zsrT}A(Qh026Lo)l+xzlzDdGDYQGd{S<3nUtMvA2dqvpyPsEW}9xVQKkZ%abl@`3mMAVP<#=rUF7`D%~GJ7qbKk;g?_#mFf zx7oOca33f3>q;BmJE4=q{=)~e-^t_QTrF?M@wH4aJ22od*CNJ8bYxVLa{Jgdw>ny%HyiW#k z*YJI#!v1tMc;Ad&=lQ{Lsxtq*&ibpeQ~B-8*iqRJ+HUX2cx?##Mg`R~*X0}V-pGcq zFK4&>PL<|H9$1(0^H#)L-_^Tcl*f7^;^%BN&3Po+30m6U2(~Wh^ru&ci;qrk*#71% za2}(${tK&DH!cnPLhIzVm417Zzw?-y@VQ;L@W)^0&mX_`on^t+Ckw6zTi*&czsj2H z!PE-5AE_C-&)sjlqRO=*?q^dzqBHAII^=#xt#`|LQpKhAcrS*B|KoW}+|A_5=g8%C{LNN> zhw3h#piWgbKaoSC-&Qq^Xq}wFV-EO^3E%x;TG+Nt(WiQ{m6fVk7roDe#be& z@!Ib=oty*jadR~9$!rPhWkPsQCfZ5C_fM7M_;_J|5i-^?tJ6}T_X5uQgw|AUr|UwiwXUB&m?@V=R#c69RDh~N9`^sD-< zx3P6NCA@E=3GXRXjmv(M#iarz$~A>Lwqscq)=_NlR%!X%U$pWMp696kw62!V&oW#O zHlBgFe^S2g*H$ur$|0`@{rcbXxeuOSech6)3GvLH;LTTJfByU;eWJI#%J0-o;l`=- zVSDBE^8CR5{Qll{;|cG6)FYO)gT3vF@_y^q9^w4)s~_d+KjeAEc3o-zKHRv}n$F@% zd?}nCI((h(x8OYy&ZV8j-)TQZeJ#!BMh$o_F8z6is|+RTX$W;}kHh`b`3Jn`PgeN6 zE%kkW@vBY9^P)1t&->c1mHXTHs{A;G@zIrW;q&U$4Bd~>{JK1@I)DB4w>}t5fA;=h z^5{n^;`dF7*LvqI+7U~uU!D)5oT^?H^2R=p`4QLb53ABAwpV=aKi2U1Ig4{Hk2fv& zkM?Um_aDnI?Nsml z6yv6=H?HILqkQ8B;f~MsH!%NF@O(t-9lZXu@LUGk>r|QYxu1c~UL)Z5@fFSWqsm_T zKt4Vyxo)>7{t}MwZuwO|$a@{@mfe}wYrV`L&Wd86q*}=1x(;Up_H)S#_wiMh`}0?) zU)672)m{B6yQ=o=m)Uw|NBq3Mthir2zpp>M&7=Iur3y^0d^9hgJ%q1|cvH_~>rl23 z?)XyQ9B!QGhpz6tL~bW7+$Vr~5(&9{Ss{<(I$h?4eUlnKpQ}SZtmk?2hjNKhu;WSo z25GJrYy|86#U1#(*e&3nnR{U{34wbh@^DhDKxl_fb`BvVZO0IIeKRMO-nQCun z_P_6zA8B~cc(?Sc^x7Brn~$pT*j_$Xo@e#v$lGz8s!YLt2iTwW`FU0S2YjBTZ}i4j z8|UTGo~mpK^UFRc*m#xRUTM$5_v7eq%jfqkmf}5&sh_a;#eIHWSb0HbL#?QU&rqc2}i|-+CM?3Z<-u)X@0DpL{fD@?=j(>luEx}OU8d}OENka*CapV_yuytZL~ct_YLKJiO$ zUTc5$?hlG9|Bz3=HQ%QPwQIlGpIw#SmT-St#pm@P>PrjPgV?Sst$4WjC*XQ8ew=)K zYp-bWK)+kN`O{N}>%dB%Ts|+n=gt=1r-Jsjw=yn#{;b2_g8d<~9Xj8z4wmPS&X0=X z`-0lDa{lc-SbP4Pe1Cp}+NrYG@eXY>V)f4M2=U8TqQpJ4LV?f!6; zKORi4=wIbM;l?{%x?f%NPghU9hpmHkpYv6x5Bpmq-g#Wt>=TQ6f|e=Gz821)zq|-) zSCn^z=c{WW?>7?lS^>Ww%D#)wPy0{N@TW(4eWHJzs@oNRel}0z{i)x;*F}Ho3;gMA z9meKGW4B=E3D!^j=@voxX$~*77Z9lKL9t>(XHA~M$reDhP(uU^-b$-_m=}f${d$RmZbostN9iFKDPQ>F% zRQsJ8U;l^qd5g|YTDTspkMZkW`fr`d8=W7Ch2D1ZG1gyu1us{x^L4aiE1rkLek>i~ zzTMUbc>I;U_&Scmvaz>!KgvZd%Z-__6V=bTGCqEBw0NceB+o0v*MxmTn|pi9p?oUf z^`P@zfAhM&p5aVzWGY;_*t-jsH6D4Sfv-+ z;~$mluPE%MHSYyLy`3&=A>V`Ad^O|WhU?-^`_(Od^&KJKg!AOQP#5jjpueT~d_Hk? zw0SSu3tMk|jQNrJIPZ@w)J6S{rXS_w|B&Z(<9^;A%115jBYC~~-}38C>u|n5s=cV= z<45uSRK6vTmtQ;CP2S@Zzvu0t-mHH1 zS1`U+dhI{(^G+p~dcSwRW^LwAO|g!u^kRE{mA8JBo9Qy|^L;m>U-{2MJfOt>I_zVE zbu1hIV)(P4<9Tgf;x8`E4>7s=E&k-o-{E;rY0eMpit|DAAItd3{O3_MsK-0>oMrlW zUVq!}uX#M!j-|bTk4s+g6XnD*{v^*wN^$>9R&oB9P`t;r{(rn)(XQWm3$9<|Z|RIa zzjpn~)!r7&ua+QhebbxQ?6(}-oXa9il*0|4`zt+><{k;+|M{%84zkf}4sZ$(a`{@JQG;Jt;}JN)HU`dE3MW}oyPZ)N5E^)IrxmWA(E(mubxZ)o0!JJWHE zzsNgJ;+OMrs6jn-m^`kD+nBul1h3Z->LSiWjh7euvEIz^{$RVKcyC4RF}XaB)0Nh* zc$_UE9;)%_dCYFA9L&D6D{oJwAKMcz3MQWy_8F`AeD7Ngu6yFQ%keaREa$JLkVpSj zrK7kHRwW;{y*wnxqtjP;E{l8fS~+g*_%{XPO{Y)nPr&<|#dcNQ666zbJ(xOHjxYUc zK5msAyzw*y`Buohi2qZ5JZ&xD{ZZi*+iP#<^)=zRlK+()w>Tc_EuWuHX1lx}2l|6$ z{!`w(*!KpDTlQ9eamj0rE9jr9O!+*&6vrpN>y1~GPk)=2uWSew4^iJt*Rx0P{@3o{ z`LW@8(9+!RjeaLWKF5yZ!; zt3Ltfxe4LEB1@=?_T$2Hk77U869J#cvY+JFY1AW@+5gAntatm9Z-Tt22kY5|jMv0j za(+>++hyf{gXMerx8CxtLs)<134d`ye3kRP^`e}rv=sME=PiGF6D!$z*M#%0?0cF2 z<>&G1plIKEKI>0ECC6Jnkl8PvJ~KR*h4;S2KP~r5#L?+`T(ggEl_+dQG^hxsgtMsNjv`<{)U2@)>>-l#3cYGcFD(@g~$9`RzP~68`J3ClB zvgZVo*ZI}0{>BVFx7RKIMZNj8d>)JaVm$%-;MP7U=PUKXVEXDCn4ZcrvvWL17v(ra z+^V|uNj5(FPBxF4J4c&Oq85?`HORWe{X-9iqC0V!hO8WFMG$yDe?XGb#nhw zU*+XQymPId{hK`g-S#v4BgR_=%I1kIZcV78{pJMEZ&~p@1L@AxE^e+^p+3nSE`?%mzAfxV<)VCb8TE@ zbavK-xfTcXC+qWbw#IFIp5b^?$|GQ3DL;;)bZRS`rxne0Ey@QioeTMOpth8+#}~4C z{b$kUL&EaTi?Z-NR!|(QIFXRqb+`Y|p%7lC%WRn~6w&eQA#-u+?yY6g5xEIZ8SfzEDIBX8H_xKaV% zH-vsP177bn-tTXHX7}h`_kI*{&V|gCRhFiD=o!)&dYE2x6Y~J)m-eI$62@@RE-bX zp8qcMw*@7R&uaF`t7!UBk61Pp?|(2p`X~P{(mtHZ=Vx*Qv630`Ff` zy_I9U`46iVvLEFUc>8v`sq z>QGl%h}S!t$0|EwyS1O(Ze8;{qNpeTt#HS2)KfoWX6I3JfX7|dJjaH9hAk^)K3~ge z-o8$6P4hXNYJ6%vZx`j#&#?ANL*9>aLCg9b-um)CXL({>-yOcKtAoW=#FvNnJl9?l z%s=~=-nd0OVm*IwFni+ou=Uov!p++(Jg=Yb3l?wdDSz@UpZ7UfKKJ*;=Z5C*Ll6Q zMgHO`+R@chiu>kt<7TVBzB`LU`rY2~NWalLFDhSS{Z5{bvxuv9zP!JAyj;IM!uwU} zv3*r)0Y4uR$6$C;JBP{7%E?@rb*rkw>{sm+7WA->KX9d2I*We;57D9_Vey{&TqNPSmd|?VEW2 zRdQl`eh;3%+Iil35&^I8Qs4I0hyJACy{6fK*Mn)e9z;F)#rHza1K#=2dd%wMxwfmk9pl_;c*hatu&jI^;{SbbTqrM= zjT5~65#{Yig2g4Jx&9UPcdBkb8ZI7w?I(o&(X4uR?Wz1~`P?TZdv7rREXBUJ<=-(q z_BnjsWMN-p(NE|1Og{dHV0k0z(ba1=bXUL5e%St$;=aGI`ht$L_V>;U>n-yB<|*>_ zp!S`B>j~;_YWC$vxn3=s8(BU(i}`ux7f<{_`FyDN%iC3Y%MqX7Q|ZO_)OfJt9ggc% z*?0ohryDzy&z>aFkT&u^5^?-fkmK0=;v`Mde{mQY7~ST^qA z<*~i>avnFf2QBNr35F}Eev~iY6wFSe=Dj}WkK^&zeeRp(^vUCieq!nD$n?i|V}55N z?jMDE8|#>TTX8*D8|HE0xK5SMF5dd{aKBt7=Pl>gALpk$?{Urj7Y^JH*7$$?IMH6( z=jW;7IKTDQDsTI!Cw*G5I5l1xOdjpbwKDGbi;um<-+V)SiLFe&^-ZSV7Vi5P^A*Al9RniT5)eEhtf69qOqp>(8&}@y9>l&3_Bz%OCcKFTO9YAN^33&42pS zs~R7+y$<(Zg&nUN7uTHssm5V@&6dX_4bL;zg#9=gmoWb7n(J58Ki5kKo_op)_gM$^ zyZI^>$GC9+Y5Gt;zP07v`5)BoT$8W)JRc6~cUiF?6za)e%f}hpRb}}^IS={Id!KiS z`sy{g9#PKuVle+&M|;b+PWSE??Td8_o~styb@k@q!PZ;Umw24{YYm6<+fnShgZg!4 z_S3xG_+R+CC467idNtoK>Td}18vFBI%74_~?b3QA9KS*RiiiB%xEAuc1D$`(*Ymio zjGX^^$oMoC`&%bee%4m-{;A}mwwLG2aYxnL>G7@4ddJgV!EjXW@Q$0c-dm5(?>fA1 zCJxUh*(Z7H%LlyQw|u3yK9zsAa9@W?4%@B6!r8&`oh~c)%ng59!v4;d)f@98eMD#D zmr#7K-f7;qHGQ=&F&=90p41BLyVnxln=0bY!v3??)BO2p{Of$ZJddq!^$*DNvMjv6 zrMc33JxmFo+tz-==TRc$en?sPUQNUqwqEP^#v$sh!~3nWJILcC%8T{HXZdmIJA>I5 z_4%!5Q+)jWj+-lT@xz1pU)Fr?=@*yt6wjC6aen2R!uw_#itp$A>I*98yh)yaj&OfS z<$ZEFmA&}YOun&;JbsOz$lF!=wzc*;+$YzB_qhkf*Idowm-2ajmJ*&j678ib!RD7Z zURO^*)-i-Gmu={-+t@cD-GH$Hz7Exs<=wS@lq z$=>ofKK?+kbqL4#Ep6d_clDKW{D}?ncAcHL#p6tG5$Xp7!`JwNw;ze8c>U;K`HTMY zu)Ik=9`$spY$)#Q&t5E#M`~9dclIc`T&MgK_2h-m=f(a`)#JbQ$CCq}7c|%LeC7A# z>v3U!sq7p1ICjeK^r<`_4X8IBljE_z%KXgU!jIGWlULkt-N^dGRTliz*;DnWf531h ze7@Jb4DzDB+WtIWV!v1~!{^8G7s&BCXYu+Pw+4%^Xs;1+J#gxB-bMZKhZv6fM|pY6 z;p;fgeq}g3@sOW`rmmL98U2~9G9i2qlUmHjr6zn&5!KK9I`25-?_vEZpZ5vr{Ha~R z=W+Zwd|fxb)BV;UA78)v(?0iK^{X$aTLdQ{BFW~TN8)!c2b)6iHLElFX~L3M7^D=+h5Y0C!E3Kk7~E<^Saxw9s6G_zKvG} zi?e-bF!|KGg2kbJcQE~kxBgC^kNQ>KcI|-gRX{tsGJXP^Kh~pi9CgM03Guhd>*SiO-wVK@6XDOK1HnE8dTu zP&`L$!}}r7&rX%)BfW98zRbr%w43-})}MHS&96GtMY&Gb?NP={D$e_#_za(q6?hM( z1%5e#yy#c`LWU#n^K%bNasJnY`=M;%b3wG1euVcM+f}6neqnzC?A8>YN4DjJ`%$tl zl-sr8y_xY5Z@y8ls;oTez0Rt}MQu-M?l*R7a@;Dri8px5r-jdFoA4gKe1^}z#6^5v zWv`j`wx=4`=<hEA^&EF@A%1*i9^F}3@`{B}x`xg_(1>-foG?*Vc zKmGRCd|nT>;Qpel;(9RuqhNUb`lpk#U*<1v@u!3NS4;4E8;bW2+9&(dTOao)hj>$6 z+V>Xq&$TlBc0S%Z{~G%QJ6`DYVSnR!-aNI0eK>5*^&slim1WKSVY>01>d$Mg2SqzA zg?#$gJfF?C`Qt0^bDmZ-&-G^&{dsu)y|t@9e?+`t>-Hk=yh6Rr_xO`Td0kl(o@dg@ z&sKl7&l`6lFXWRT-xQwr6>&J<@ILR&p6P90)Yl9sZyzkzU%y7)F51)8n|Jc@(aB?f z>y~iiaD1oA#J+MrQhWG|PYU)ga(v2%^*jGj-k;`Pa=%sjD<5R?Ex5lpadWWoD!sGS z-YoO+5dCN=zJC|x#CjtaY<;$8=z37}vs-ls?z2hxJiknTf~{|fC44?*74NrE`CSw4 zJ66ffwRY?GJZ|(aafNq&qFk?(mBWM0i=epjn(u3Z>g%+8^ZsyrRy5}a=x0;$xg7S- zR2h%)IMe@R`CWz*{b)eFCdgxd3ci=edaKsm{6RZnS-!S2c2iyYo?Y~Jrs@^V=YOfs z@Ohx}tM2oABGve~@V%2tuCh1tC;ngjdYibz+s`I^Zd9xD<5YHZ?M}$|_vrM_R(}Ha z<8VIUeVx)R|FW+L$BTU#<30OpZ~nXGcdzIzzct+Y=TyS+BE}{DzdS$L-?Do8>vH|^ z30@xcH5BsLKhtHp8ZNFg?WfLOE5*k-Z)_J@?I{)M6Gx>PH_o1WS+EMa6#C~0w z*4&4L<88REviq68^>@r}oEsl!epEu9*CMXUwetAYHTyg{mjuIaT^dZjRps-j#IBD}3Klfql5pzF3y8rRKWef#qo2k-fTw8)5HzY@}V^@k9Q@a zUt*lIr}2Kqm&@&n?3TUR(whzWTvWIG zjSu_FL%;T&XT0^r75fS~!oGnzdzF_)%hQ(6>!Etc`xVn`y#2FY94_CRM|kVSxY@${ zi_(j|dBJgFS<^gkF3PLwjUAZ%xZ?P$8aLbRDY%}g_>4RH+wgh)i1M8(^8x2`>Td6R zs_pFEkAB*AEB%Jdacs`f(hVjUhQM zdu_1!;0X7V)r8NF?TGtd+wI!{ixk6&kJ$9uAcu~Fu(FEnBB%r!N%$Q2-=?)_TvaT z-h%hdG!OKL!}+ZIyr(HVza96v?@(RyIhXw!xnEAedG9wa4aM`pm8v}d?0?Jsvv!rs z`}G6mTC?F2R|(1d-vTB7{(S-54j&${c`Vk zh|z4pzLYIE-iiHw>+$Ey?b_F~_VoYB<0R@&eaCzKLHWcj{^U?TY?%)DJbd{ie}1JE z`<^wg^EY0H$9c0{PkJC+Uh3>c?QbgX_e;a^s2uV!6Cy=L$tTV!d*4Fy7OvyyfF}@W+X`W*=tJA5}dcaDScbGr@RN z*`2HHiFY%6*`M+8R{0x$k31e(*ndYg4%@Sz_m|I&tNh8KUR~+D*Bf7LU+;X>>F-v* zeYtlWT6^-ivU{<5{^hK6#`y8&y?J?+-_7?jo|}sODa*fP{Rw#fvZ2^dO{KrAd9QtC z6Z6}7VK`p0U4G6-g)4p@i?0RmeXH!|FWxGBVcSzX@w|uCv%QSVp2Ekg*&*Ii7xMh) z755W%E6&a5^Yf?t43D#0cKzzL?&jm;cidc;t6bn6=agdKmBbId$LVml;Q65JNBOu` zgu1AwDfE|Nzn01YydH6!Q{eMU?9Vy3clS7#j_hkYBXr@q3sqkdKCfPCYB z0VAL_67`?)oFzGxhF7p!_E} z@9A^o{Mw4|qZ*Iyq@ ze^CE*@>am_1fHFDnlB9qIh=+uyv>J6;X&&#%7xN`Ael3;PM99{WCC4%_{f zwcVKC<=wsg_p5KF^5^#*3o*4+1vnYgxVXpX@ZUl>S>sCJBL>&2z z-uKU-ys!^USpBI3gXKTkskeB4usvv*4*2~<{XetILr{D( zEnoY2wDX~;{+1Q@={N_;^Cb=P){cB0Rus<(iT>4oE61Bo@%qGZ^*``=)X>O_<5l(6 zJ9)h-xk{RstNohCk@dO%hArIBqp~NqSKcY-1LYc9`2HQCV{~OK)<^!v^3d3;W4n?% z{oMg%XfZIbV(Yr~Th?tHST}gg(E}?t6gRHEY-p9Nef<_i`)XFSw{KXtvA9ZN zcf+79Z(p~OD4Fgjk(ag)Zd@hRL)w{P0q>^GOkBikV}~HWVbkSOyIVIFS6*rnU4r~% z`}*na#lcmpRvdM7T9l{lS18(7DcUcSwGVAwA=OXXrTR&`R6l8#>L&rEW~cj40xk1r z)8Y4Rk{ay^%?mHN41>-w#$E}Ld|<>gz3)*U@P-)Q@)qlbn>yR>~sB3~R@zg}vW zw9DhOe!Vn4Lz@+PHY@aOR_Pg(`?Gma?vJ%~4V^GT9u|j4`}!;7?bh`6q02VY**;C4 z}?k7is>;+6Pw*tx&WRZ>H-Z^0IZHXweBHk*Dnv|0m^#rsFMIbYjT# z(21dFm+2w-X>BGQviMWL)7saq-Kc7p`7=c1sXvF3eXsjTNq;@o^WxxoGGOyGyDK+s zSht!IBlttx*Kbj@ua>v3RmiVZ$dd!iG`m~TA;F)?cIuF{ofwd{Q-`GO3VG^~AWz*H zTBT|y4oT(Lua>tHhotf(LPGocRU7P;L(};h+9Ge?FgSE6os*OKa6I9M{(9uY%Jpm3 zZymCx#b?8s)f-nz_!?TVVqohrM^BTVY(MVUsqGtv1}+~Q7}_$pna>B-zIrlir^~P0 zRJ@Y7JS7f8R}Nk7YI5U)?QDeGzH!sW^_x}>t{+&tY0IXmdRA|_WJ7UaX!Vw@MNa>g z!IhT|3=LjR;ZBvGY~Q?kXv?O}Q+e62dILEt8kn3dy!_^kZinm7(3Z_^^A!DCH(s%B z6#ZBurZdpxOpQ@j&ZqBG_#rZmPjuU@r!&AN@N2Ugo# zHVzU8;b(|Mc5pMHb<^g-wW|lnNgZ?O=-3{yc|>M>Pj;Red()1ScKTzxO^&n<-G#GD z*SOt5CoQla^^7e8J$LhZMg%>Bf*$NgJ>#h79$rsNqGyjO{$M}q86hy}`E%?(UQgyQ z9@oW0y#0gys3*1@;`R`)#}@R=7xZBN zz`&v<^B14JVBx^xh370>JTL&31_rFbp@EeHgIl(2UbkZF7EDlRFBXL!*1m4zN^-im zdSD~TYNlvlVA=8o^9RmZc-FE-OP93OPp+SfhzR|i8n=Og)0Uh)e;_w+`TXouj|K+j zEnj-ZqWJ@7EnGY=ziR7(lhzfZYO#c&RaIU zoyb!g)8y$CKKqO*@~19ZvS|6jfivbU&kihIviLlPjo@8${=%iF4lG`}l+wYde(x4XALY~w0t>Hzi`QdMe`_a*iJ^d zjU-6eo?DO;+QHA<(nU*_6NP|)#9{ea3l^Pv>cH~za<2PC&)G!ojCuKK?aPQo;CRXq znzzeI&dyu5JUw*?uEVuc_;q-S{87hE8G!Pw`AT_mneG}!`B?JB+575D&1=c;>Op81 zQ}Xog8by!)8LAANpg<1o*ayzIra$rF>wIz|HF#*^_w=XO>W&tFGE(ZN|MtS zkQ*2vf0HZucAwBbFu?ar>X9fLvNmnr(iU|MkQ4Ia`qg%Fa>%MpTUU^CZTf@l1E;Rv zG`NMHsj?rweex7%vV(7DpGnXTzWtb^ZKg(OKkis;7kP0&UTpue(2jhm+LQaR0ivD* zA<@P5dm%xw9rfcu%snsViFe!C`8nnU>cRPoXPsjEa|B!{zq6tp(my6Uk3A|GleQm0 zP7-ADN91C$Et>~74h^o{vToDHf#Ozj!VW)I3~t^yuyy0sq1EhEd-7tI^tpHkS8f`z z)}Xx5zFyK!ub_#x!S&=aW2&B^bsMF6XuC|$mcflj%k0v2g}hWhk(cRTxq99DHSG!D z;+kx4PXM94JpqLF_5={x+Y?|)JGp|R%K?kr^mYb$dOL$Wy`5o@v`=D?vNKXE7z|kM;?3S>f+STE7q)DyL!v&jhBo3PPT8}w3S`hPt{{> zTE7a^aQZh7t{Yk{(N8YXrTR&`RR0!ojV{x_wYX|<%W9@-ia+Z&ZQ3m1ksNI|ZI+EF{l3u#B~VmoRV+HKbWXV-QO2<>eHLVMeQ z&@NdA){yUZJ)7x3BCGC^3mb6dCTGB48lWl*5 zb<(=BxM_;Jm-o7S$t<|*@NvR$Ts;~FJ~U?k>+lyTY!!JWrM1OwO=ncxk%~Z+q>eF`W{($#zsE zwxc4qeZ7Lm$#xW^3(DntAX{dyt8Y|K!Qj(L;^vOga~pe^U%&1SI^Jyk z9C95MzMy!HXSV-3orOWAn+h?_s<&8@M#(G4|DI zA%^T`r+@X0SX*Ix?bxv+=6Kp(ZVI*U(dBEG%tW?1U7fLCcl^j~T!EWt4)fSUhvn;+ z-A-ew8{h-G?M+j=J*K;Q1$#i$zH(q?zX{uT6t*8WNBSrnvL8FTT7{$42;SI_;V_># zPz}19Ih8O+{ZCvDauAKTdi>b_>DN>K17^znFm|tyKL>6&x-yxz4B4HK<+eXl9?M@@ zLWd&u)i~YN!(pZ=el=_k@vky|UJs#Df3A-NHs!ybB$p;P{q)f++yo!SHcW7^T+Ly4Z^jXlZMX9bLV8@)uJ-1A9!~oE^WI;;-3n&ach+tSj7* zJ!}s7d5zg6A6VRfz%{`XzrT9)$P;45jpdp-u@8KY`XAUQ^JY^XYrmesyKCl@r@D;2 zE}WkO2UaK9iP(>t%gc)<{pLz|cwJT`+)%uh#7t#aQS&qP(_F2N-Jd!;CW7K;^Y8F@ zWJK{egEC`>Q-hGbiWL|2b7eK`=@h?W<_Qlh;>;Pbqx+$F13bDPvfK3u6+BD`*#kU= zHDkvPMsz1<9$~vVa*XxI*kk-zS+z%?*s%!@rZeJ?#p9V)1b^h{wX^5TD`x+@Z031f z$YJ~;TTt*r?aS9452&aexx)72hl6Df!9m~DZm&F;1tl~5#>Lq2$6j-`!=d|wDNl9D z90vw#UhFs2j$MY@G0{`IU1zd{hbJ>Uhu{yU`0A1Besjn@vwuXpQ=Y{;q8NMdMaX`1 z`M|O{WTo+%#tJ29ia%-=<{XVX4mT@v%rXaP$tm8<22Rr-ir3`fz_mw^D1t< zWCz`;eR0wD;OdQw`zz)TrgjsTU0-Cd_GfAj@Mg`|a_|SlUPU5eH_4;?i)K;J1Rmix z_QP>JuHxc&jv}1!m-~ zesdHT>yJIUi}T0YGow&NFLn+&9zpBw?%N39TCm5k>76O;#jD>>;Yqx{kbA>oajEVvon0{7nBKgg5r- zAB60tVPf&d9*Z}5j>Q{$7(ZPH5)J^`D_B4ib~J1cI~2Bug`NMdOs1;gx(c%sd*~0Q zJYm%^K9Yt|J%_ys<0EN^*7G!NVSB_;h!;A{^bbPzh;ZP)E%Q)JuAVR4w{P*H^Y<<8 z+_}fB1HGhl@%aluonLVA6^rLzx%cA5OU}Qdc-eWAdN!*>W9=4y$zIcm&oc|6uv-}a z1G_2Yt+~bX7fSdI*iFI4*>K6B2ZdSDh-%Zwc zq5YyugB5a?V)4>oRhexsYrp97AVs@!Hc0`~;^KMdn$*O^8`xvwb@zbu1as)Vf?Z9xI8$X**sW#TprL)^MH1m2WyYZ!^QTCnM9cJFtD3M zgj(I^b7GG)Jlah`#Nuh80DdNMV4q14*v~Irevw&$h*dc8XQqGvZxa_uP{4vPP{bZ8poyI%BCv1Ywh)_#z#fwaw9`B| zp2$cO;*Si`C#(m{L-HfyW zIsLP4;eq4Cew95h4Br=k>-KS(J|2&OJ-8nspF^SvPhg)aOwactmp2n|m34YS)x}`^ z$LoDCn=oTH*B@iAubJz8)5}mH9&@wc}546C9p;OvbAjJNB<=2cFd1Rr`v2 z&7{J#4&fdVbJx&f=$;=lA9cjskaVs2-=W1-J9mure90v?$z~$q^2;Olp`at@UUc5# z1$L+jG>opjj|orYup5~?IQ!+7ne^=1u?zjd_1m~Uyljid{80Ptoq1x%`xMarb@(1P zg=^e>3|kUrGRgel^Cob+C9#vS?_ul@jkV)C^p3gGmof<4q8;^ci}nHFaf|lmWA7O7 z;PwILe#ToHUi&#M@WB1g+8aK9yM5k*UAsW+@SKhCb;AH3Jg>lBGML;?XZu~~o;vIo zW-`N_)t`GoFgGzXziQ?ut{ocH>YSf9yQ1 z#mCJXn+I*g`eW>|{#bjQKh_@SkG03m8wdO`^Tzg~UtE5y-8eK8Z(!fX*zG(CnST!O z_W3G--R?{+@#G3soIR9>2tJgDsC}A;sC}A;sD0Wlb~ZiEpNKu=Pt-nbm#BT}Pt-p3 zCu*PiV;V2w4(2Uvx9-H+jXSY+<4&wS)Q_V4(|%-~i8zGq6}E@+6TyeuD}tZqCyJlu zCu*PO$5wHiKM{M#pQwG>UQzqhpQwH6Pt-p3C#deQLy(`S-8d9)pY$VwpY$VQpY$WU z7}6Y0nk6)=Zs`c{hwb4yiP%GR60wKsBw`QMNyKi_fN|N*T{(K>u)C-l)Z5ZA^X!iO zi}ogwpvlao&#>LxI8s?U96X!Em<M6=%0mh3w{b z#$X_~M)NcACwM#sI5}%~PR`n$le2c`JMm{~kNPvUNBx=Fqy9|oQGddnG?F*m8xemdcsq)P z^Etss{h8vU{!Hyre}bMpP0%E7Q#?A)E zJju`09?j3x9?j3x9?ehGovA-)ckaa4gXW5{2kyk!19xKVfjd)skQ-cu5X#%cPVzIg zN9$*5kLG7;kLG7;kLJhOO|_fG4Y%*a9_x?o9dZ6xdz?Sk9_Np>$N6KbJ=P!F3xY9m zQg0BKvB&vi@p1lGdz?Q3za6*&Kd>CWz18sJ`RvmE{fp)%b#tqWx$`Y#-(Nj$ zo|%9*7){9&?V7V0 zd-d8le09m(X>WxI{(xCC9o&dZ?dC49;8tR4H+cIvy;&Z!=({#+U%vKQmme?LiyI;Dc6(v)fjPvs>{vyA3YR9=)&7uG3yRFuR_7Vh>6v z%mert|M7lF`v+0HyN}ZT!PH(oazkvt2<$QSKe_LcaPiLQPm*9R|gopXL&sf{R zg?Ylw6|%eM2G8=lyM1Eq_O2fIVwxX=x3}rU+1=E3@XZu&_P^!{9JBoHZl74Yz1wGo zKe*dxbs26!n(|wF-2H~uKDk{flm}~{&=dRgK@1W8YwQ!7-A}}Rc=|=eerP#vKV|Qq zGM6cwQxUwqD=C(L>Sz={6^PiYS09~yo`8url%OfzJTnFOjX>c6|Znq@12N}nI z<916Txa<+LZp1#xJZ?Qnp0PiKv7a5-OABtj2X42(Q=4mG$L*HjN!p1-8|=84P1&cKwI_!FX_sc3gLYTgl$>w7!MoK|gSd{&0AV2e%R)^NU-=V}5aq_Aac$!7bV` zzqmzv@^P*mackG-+{WbJe!}xP)_$h3*$=hb^+WbU?H3!H{ZRWQ#%4d%eyOq954B%r zZ1zL#C1bN6YB#3fhuZDG@dFSue|1LUmgXP!L-D5@oBdGxt&Gins69S!XC;ybYd=x^ zS&7>koBdGx?TpQSsQs6W&3>r;4#s9b)NUTR9y~ohYIpBnnr*K$O(qh-hvMVg{mjIj z4Bmby{w~I5Kh&N!Hv6IWyBeGQQ2X7C&3>ZxGZMdUZ1zL#zhP|lL+y7rHv6IWdl;Mj zQ2TEhoBdGxy^PI%sQuo?W}p_Pqo4L+y4?Wk1wjFgE+4_PxetKh%D%vDpu`?=v?0 zq4x8P&3>r;0%NluYQNCf?1$PPVQlt8?T<7z`w82p$4mPwM~XoAuR`r$1PH z_=&~tT9Wf8Y&R=wmTK_aiLl)~QEdP6A*bN}KYVWVy$p06Zvnt)$924RT(>{e?yOTg zt`n}q7Zh*DWBY@4#5?QMj>nDg*!8C(esBkOyjX`X(B3=S*>3_Ov?Knh#E!aLTv#i} zgZ$Lb%ERLQNj==z6W}QFAfEbz_?zGh#CL(`CI}4e=s(RTwih1vARc+B|M>iEV-Gw< zJlai~1CP+2g!jVO^jj{pqdysIG(TuZe@=Jii5+>sJh7Aa&eV|y?a=I#dPqdyk1)Y6 z?1lUjUBu7uz3@pg5Vg~!<| zjQvoIJ5R%cjkSCf&H56j#D0&hihi|1AEN- z_yT*(`fX>Q&A-d%EWfo|cc?$sZeO<;XSc6gr1l%GUO9ZdF;n~1t4CL@n=$ra`8l;8 zJ#y%}IJ~h};_XKn{Lxr^@LtFme}eZyGIkpl_0zt0?`p*r)4uBK@ms?1v3} z29FC_sGnxxi-phN&1}^2busY<_89*I`)oZ|js4)Uc%FmD;&~1pi{T0Gzc6o5r2ZTG z@wodkt~CvRLky37Z)Qw?x9`&oIsoOj__+Mo`#un= zv&tlI#(pR+pVqz{k3Y!Z4>EZ3HcCS@t9v*QjwVU@!$J)(%rQ_^o_>bkWyM^Ej z;-`6ibU;Jf#q1Vhc}%~K)iw4?+;O9^ABsE9g!fI)a%rE^%z1&~vG38I8UHQ+Dx+)mBQrd9zYw=yv-^cOyWKCu+3kKI&TjV$ zadx|3h_l=MLY&?17vk)0zhJ(hc@Fjq@%Clw=`7w1&+&E!Z}$r``8596{X)Fm63yx! z4us?E@p!vmh~qKCd943tIFGk4$Jm4MA-WC<-}CDpPGIlHw{NVy%De^=UIn>my4Pf$ z0p}~4x3|`Co{`7B*=!oGnIH_UyW_8)&Ri$G*z$Ahb$R;?kEJ;Q4~OUM@#}}@^(S!Z z)c;Op;8X@qW#Ci>PG#U!22N$*R0d9E;8X@qW#Ci>{?}yS7R1xhIc~iqnwt-G?|G*< z{J!%qcM7lb4W4g?-`Q=pQruXO%Nd~GEk`YOdSQpS;fxriD`xb^g^?b$r_TOC8tg zt^-c$=UUy$4LaRi&2PND8+E!Hfb$h^;>kMQHsE~ej+DCTr})it1^A@#wCP!QsMJmV zuHSeUfKQ6I?pZhYNL?HQrGI13{uO^uSNB!G`KtSDS9cuIQ~IYJ*EW=KRNkgL4%6xm zJ@e(>?$^J%XTE`FzRWxP##{Bw*YnJm>idni?3pk1de?uY@t~vBrSpl2o$>RD+WuC0 zr{DawJ@bt`^A+CZH{PaazM*Hn+`D!0E&xv2?`!L7O{qKZtebg{F5V*Ge8t;R>h?VA zYTG0KUR_?wfb*4?g)O?{myXiE#QR(vzWl3f=<meS+fnM4UZIPl1~^}F^p(0J&$@+I>f)^c&R4ucrEc;+oPWM_>%b?CFKeE4 z6YxApNw@eazw!2fPtq;G^A&yNIsc!!x+(+Cmu~v;I^A{8x*KJku6F;Cyhg{@ezn6% z`J>03_`D~&zLVl|zZ-vida}6Gi*fzhYj;SK6h+jgRYa+PrXiE`HJ-4`DrU zeCZ!WaU36Q4}9L1ls|6%s`cZjF2{%dOUHkyn;f4s4r%$cxX!1XuGBx)0VnxK^USqJ z_S4b)CDQKsWVAg>3~qWKa`4=)>kl5-R?RORIIwbf**u}@x~mtj-@3~_pymX)Daa&? z>e4u}PmQnp5%G`1r9Tsmm%~xr#?JV>R0to3YbtS6xB4^poa&jp5Iz=1)|D2L@p0rn z8_f%cqyBO80(HVyzh}Jeni8kg?cMU1gY`60KN=HVuI`J&XkHLU>Un8-^@+IO-oh z-;(;5{d_cD4p&m*YD(M)j)!pn!0Gn2d`cY63)jAdFGTaA9S=CZCgJ1iS?k}B@M*_C z&cECjqw#X%c>h*zeDSsaT_d`=`^WF!w0Rj5zS_Ox#|x7Rz-u+56UJjQfIDDS4)E<==#rszy zeBAj_TZ!uvoYp^1cj5WE^Hm&|rSpZEI{h}27v=RC)WvO?;mf>LcRro`s;dKOys86E z(xvg%SK{ME9w~ooper4(4U}=9ZceyQ6LFG%h^udR?`^<;)BaIR>W(|{?4% za;&nrbjZAvZ_zwVanU^IF9?n5YU9=7>f3dBK|XEWOZ^i0BwXXGI{#>%x%noFmF?ZfW z5qq>}bO~S|JrAO+X!%p;uL z)#-wgZ-d0a`KOIzpwy*&+mnOUK5ZQ9$~Y1~b@57ZXmv}#C*`l^S+}p$9eLI*{7hFb6~IY(&MU9) zca?nFc1!+T7e@|oQXE>{x>9$|v+h`_oB4&`{!s-!seiOQ>uxA@we6O_Nmnmrz)AJe zP}Y4%$)}AYk0jY-y6Xn0EBTkcwXO~dfYa826fgQGwMTbOU5PJwoB75+UvaG8 z*6Cv0BWC?`eNO+Rc*k?{N%hi#`x~V?=>2juUhe!C^C6wD)_yh0$K|hgV7~q#<&VxE zaP!LDyXoqxOzME+qq2Q9f?HRG08^ILgP(J0@=*jhDkwKCb^R5I$`^b9`%r zkE{EWtpiRsqa3fad8wWxAJ>1WF4uoIh%Setd|Y1gcZk*thogMlb%O@s3+ME1nU} zpSDhO50B?-5k9U?*H5wz)*0Q@nbA13^~~YQgio6nj;}-bxV+GI1zFJ6J0JZ?Qfslcu+qlzW&m8iq?TPUXHIq__XcD@pTCwmlv96E{^1#qw#9n zjf-R9B>A{F)|7me(aF^TcilO2muOzN{Lwsfd{x57K@&b=Jhha?&6jFD+10}URp}s-kiEp9bjIhc=NxZtAo~@?IG!Ql)BnD658WGAe8(o z&CB=U6W@>120mZymipd&{X>eka1UJ_V0-wAqdTXr6h|^MUmVi7u>gFMZr!u)K&d;P zQ#T{jY4JB*{(QA>3-|`Y^})pV{nm5pp7Yg#l$SE_`N~UYUjKyq3xE^r6cXdB4!U#dN^vCbqpO4T59aG{QoYncSMo1^Kb?PT z$~dr2CI2$_)zv`}aN0VMbX!W@o@d<@??(coq`yO+}MVDQ=xUabP(U+fp#p0!VFFD`+Wv-Una^M6%`RdkP+w(ija{@2i zw{Nky_sa7ZFMsT%`xf_Ic1daPqt9R5d+B+LmtVEFw7AvriMVY_+zur!AI9yy;<8IF z+P8Sc`IleeJTtLg@#x2#f92kb9W0@Zm#(L2|JWUeN#hG`-`bzW&z~kA9IY$uyf-(F zFAzTM{k7aWqczH>yzia64{dyseB645VlJ9L?S1*&^?=q%@^SZpZz%a11s8|*ICl6$ z-8$c@Fn`e4>U5>^BU;Z~{jCEZbhE_hIq`L`<;!l1w(n;7YM%M}p83+-{l;4%eA@oO zwQu(%`M7pV?uf?A^~=JQ4yWxO(s>@%r&RZK@J|}=2Y~bCAMGF9IG)+*@*??H1)MMc zwE62P{Y&lg+rBh^TwRqxSIS>!PXDC3!u(0P+1TrvxySKg9=YSc9KmtVC8-ycd3l0Pca7+B z{%PaIIHh_)oYapp57D(p6>z@BKW)4lpo{Tv<9OJkvLn|z9qo<@=x2oZKZ!BrGHeHyN{*tuxS3cepw+nZrsr7b_pM+JJjOH^Y6KM za}U?WyFhTGnPA zVt%E0i^91se^ULW0Vl=L1e~w@(K_IsSDM@xtpo13eTI*DU-SauW9QA_ybSZr;ixWm z96KPo-0=(L<8YbtqIuzPTD~gbqh_058+aKl0{)lT2^k1rbnm=y; zOL1JitP}q@TpG^b(9c#a{ybExTe=`xFPv_Z=x(+>`bu4lQ`&E7<1N5>DDrZ3&^^g` zSw5xi@FdUAxpvFJc`e4v;qd!;>z=#5x<+)l`zy5VHYR+&)`$wjXiV?Ng74`p4lmNF3}qspO;W#??WG@Nu}(;bp@_v;P_ABQVHHX4UEFWmizMKX`XjT==Zj>gOB_6Q$09*iF6 zH{SeZQ9iE!rU;I!gEGN!d^9iI{n+b-kHht0J`DHQoPSi8yKlQxispsGWeJWOpKAoi zwJ-ILyT5xx_&D4oAHw}xRF}(NNq_yQvdh z4!1^d+;J0a5AHl_tmJDiy1dMrXYRUH_3~(*Ib4h2xb*@jTc_N*pwtyn|2Q1YGgnt- z!pGqn1jofob-DASb;8HtC?B_eDEpXbUN~Hd;IwgYbN zby$bmc-cDm`)HmyzMk@WBh3p}2T5|A$l-DX$N5Kfxq7J+J`P9uIRDlNALn27i!RSO zxNeYrnfo_gXSw!I(e~hu6N?K`9JfEGad3Ps!pGHpkKnj?wYn*CT+H?la=naek38Yq ztbZNC$MvIig4?WamK;BG@s9t6J4%fj+8i>mo$@?LOEIoSf{5$fW7^RM9TcmZRznwh2f((>K}LAen|MZ_Z=sf zqH%DzBAk~==fBv#60Z7+s4mxTT0X=T;J$?R8y!E*-x%VRj{j($xp@n!TfM~HpF?#w zAb-;NboFZIH~QE5xA-{9uZ-qT>tBhA_bu^pG?couJ-G3Ywnybn z@w$m?qVe{aJR_e}&!hive2B;KfYw0`bP>nxj|#7f@^Luik?MX#;^oeJkWY$trahSF zs#TVwad7ijO@ia{hyG!_Tz{kf)t(r?e@hkRFKEXtj{o-G$-sCTeihkfLjMZm zXuaf!e_UP$1c&P^Lo&gyoPSg||K@03kdNY82ctNyeQA4e^-OVGyd&khhaT~d<4aYd zad7_S362|gwQ)2EALn0(;JD+?igJC#I^pBuSbJMEFWi2*`gR>|sPr%Yjwl~@T`keq z;rax}#j#L~@^Sl_<~yS}uHCeC&?NUmY?iM}__%(Vd}1^XuAkF5xa$i8W&Re3F6ZAG z!EtpzAUJN_b@5O%Uasz|1jp(22#$**L)MLG+n398`hC$jxOyHET>XRb`@t6RkBejN z{W{(1Ad2I3^B;)fFfS*&-=cNOwOitFRF|s*%7^~Z{a}{xaq}QGg5&t8E*D3i@NsdB z2#&iSHhmIBF6w?=T<@tJFn2FVMze;X>-8FjRLG>YTat0YQM9Cuuo zepD34tqaPL^$c9R8JK^;afpi}Pp+SH?Uo?dlQ~>piOb#5y+@m#U()?dX*HS`u1<%? zqBt%um=9@QDtSE0$HkiioD@g*^HDyoJ=TaWcO7Ew3sFAKKU()(UNYB5`8ZtlQMz_3 zD*0Lj$F?sSPr3c2wtY8qC*_64%N>Vxi7s~>HY7N% zA0?j@je{G9wE4>sK2EnzaNKd-0^sJ&AJ;#|M3=+Wz8=jB*FUs*DLz@p*HYrDfSWfj zTs^0r67`S6<-QrkZMMIai7v<20NlLsvi1DC(Kt9O_~Tzcqs6@;4wj zZhxfB-Us6))_6d&bzuLT{8!lcc4lQ5BGhf#;U-H@W#anv$oq~0ZjemE4N9QNCd8sRP zH=g9i18IIzt25#tA99Oo~3wubMpC$BmYN!<7jy1TldVDeU9IFYf8RuQ#Vdx zol5mGQtE2?3eWYMmk}Aqx#RK59b8_}PwseVK=zj$F8RkU4v8=Gy(o^`57Oft4wrg+ z^tw1V4_E$vRF{jRyQ1UM`ZxMPRF^wm>l}*ea>rN6AL;le?eH&dKZF0K`j5bhzAUIvkCIYmdw=qI?{#b4wkrbUMMEcbDKei`ISR_Z?0e z@6)%6@^R;7U4rBCym0F%A6NI8+eC3(zicF=YGFU>0>jvN2*d)#vKTs4wEZC<$c==@o< zJ-GFq*%wA}+PdO&F;3iyIN`pw8u%ym-!|a1=b_Sb{YFaN^q;%@`O>WbpA>J?v+hu- zn{3S&Z$~&TSpYsM-nvqE;f3>^2T1;nmHuU3q{~b5j&2;6;;kzAu%Aiw+yg#Icf+%8 z{>3gYl5QDrzWPx|sk=U>u2e7CztF{70-QEpNw*7irR9_AWu%NF{g=ABPo{KrUs3XD z>%I$oQvD4*>*oGSR|gA#^VM!^O5K5H-OOL>;w=KsSG+ByZqKuB>Th)M<^ks`-iA`Q zGpDXJzG(Yfwyn!c32?sh(pKvBJ?p0bRu^vpaN2mK_E>*})5Uh-){i%p{tZ3*SNs(> z-usHT{t{iD*8nH!mY$;9AB~lK*bdTuwfJ|sII4h?;?U~$l)4+9b@P9(i??}Yw4S;1 z-!ky|%1h=Poqwq_=BsC^4od%^)2#u{SG*-Suf@9I*3tHr{vi);x%2(>Ke~9OI0}H1 z_$r^*<*y9whJ4(-R9ERA^5B-6_sRW}^AB;_`8CczI?u}KX3unWin<(bK>XwC0C{lB zwQpuE8ZW0?BsflYMB?D`(jt7^JXh+aQUADkt~|kUx|k2#a(U_gs;)gIJi_~#%1Zw_ z1jpqWb#cqZk@)9m{GeOFx^+VLg%uhBZ-{L2wsvmJkZhU#+b4y(Twjf2C{yma2} z{*LBl0RCZnaL;cV-d(5L%II+DA8zZp+s9tF!tZfg*rCG>m3#|IzN!+}U~sg3xp4#I z#BG=1!|!oBU~pAn8`~f{`oW=;@_|tkE49-b#~?R`m##g`u=F1x$E&Y!pGGWje|Q6=o3D!-L(Cv z@~UVY9A8t3qj7NYYW?djNB!fDvxk7gafs{ZTHVG2-FR0LuJ5M+C(U;vpB9JfcRS3w zYt)tIX%JTzj@!{c30HizYmdgII z{X+8I@p(p^)PE5t>DK>K7sr|shw)1LEyPLV+WH%GpR0lp^{*9IXW!~=MkaSBc4u^Hf#ev^T{i6lCQoZz) z{%Lh-dvMR?Oua+bzGc8k`P2H>QR?X2r*3}4f zCI8az)cIG3c%}ADKOx#bxc%zdS9JO7D*e;eRq|cBdd>k(ig&EcOXktKc-NG=+IYvx zcr)+T)j|bV}%S-uMU3(OP&sYAmdD&3v()N(9(@FE4L?|C{}wi$l^)01n$l%AXW(Td6x-)QubHmo&eNILW`lhm?5% zLanZZ>w>Q2-%#t{eq9}4UL^k(KJ4-$`Bw*=R9D?={I>5{>0jm}y7r~x2KStk$`Qwh zdE{_Sg5#bKLUpM()w+a_ea^&cRF_-#nk6_cjx2dj3>U}fV>(@Ryt(=Mr8FL3T}k`P=DLeR8aK3j z1$ds8md{rl3m@0TQG)jM<=NY;9%b%97>ACJp zpVIj^@|?fEQa7!9t}fgR<|>*6iUsVlAfLjUT*IBUR*i6|H!o~ zhYv0;U31OR<<(Ui8+Uz+^07E!UD^ithwII_^+T9vX+9@EjE|T4R|cFm&ysFOsk=U> zt~Sq79h5$&%M0dN;!FI4SSt)-*rEc;Ix;&$< zR4)rkzQJ*)i@e-%d;6L5jn9&QsE6YLw@wgoT0UH#!>vOpeo>d_>a$(El5S7QhjB>t zlKPVKPtwf;PU=U!>!a<Y1baxj!}gWxIq`K}J!b(Y)pO>_(R$|QF~={^#oJcuYU3R# z<4u1i0_x$JVpXuUV_@*v@+IZK1Pl^}$a>Dh- zfzrPY$qV;<^z;jLd8vNOZ(e%9C*@^Bshj(AT^#vu`;DUkd{P`8rEamMiz6}e8%GKF zq&R9y-TaGmarBjZ*gvHGLi#%{FH#%@z)AZB)Rp>Wv*UCT$KC(7_H>6sUT!~=c}5h+ z9cQ-)ZnMW>^f;T-MgOHd51$*2gNqmWr1s7Iag>i+S33T#!%6-X-=?e6>h~OS|r7+g9pkp6C3- z`e*ywJ9KrB{-G}3l9I2YHKne0 z-0drMGhqix(Zu!T${56$)9VK5^$(Q(v&OdEk z4VAhzrS9mcYhN7KxcyA>ow_<0DRpy7zQRv+`Kup`#=(t43rgLtQnv{>%pa$_rqs>- zOc!s5^dnAppwwMc>W-CsV=xG>Y|<$N8%=393_%J?mc2!-I`LjMs&ITpjLOJ)YbA8;JtIw`Anb0 zA=QDj4j=>9{iNq$biqHV4o1X3ZvGGRBKenoLA0N9^JWY1K0e96HNZ)Ep70=?*fT~tLKL2I;h@87jIqZUkmtr<)sIF zllCj5W1nNauFOk5NzQwi_qk5=g!c+|fKTd2>wxo>mo?HJ?D5}wT)bM{Cfqm6J^!zL zTgR7!>v}z&^iRuobK#`tHvVsk z<9|ATqmRzlf2BGt|MGl%((z;m__TFO`KIg9muuDK{l^w>SUFZ%tR6jb_0rWVhgOc= z2!+8N-%~z{E8RiYFKd9)wy&g{{iNSKw=UEj4`Dx&{6n1d9D?>=xZ|snZC~0RTHWHs ze&g+2G9RBdUI{mV_mOJrO5)4CMAsh8%XIO!$bGonc^KlICo{^OR5qwZO^ z_#<5$RlrGkLH}{f#j&B(MIK4FGuFkS<;(uFuKuz=_NzPG;&i3)Zv?thUPj6|DnHT1 z(FL5OTlkk~{B- zFK#)$0ldFVsw?D?beqcdZKtDoX4~zSy8Tw4@Nw;?jiU>3SX?5v5A@}@< z_1oxlwS2z))9NN~r;Foc{mVUE_Z}TC&omD1y*KGQx_XxSM+@GI=c~U_|Jdh}Kmw)X zwfwK^;z$7w+l9+t8F1QoCI4u=+;R50GLGzT=*H&+;G}r*dnt}K@JaPTzDYw zRHsFFPo~tqG~U*p_;I%ie7^F$q4Y2Ho63F;iP8F}#Yy?=%;}%Rm$>JA@lNW2dG98E zkJmN0=SoV7T3$T1boHU-;7_>uL@9p@@E#ti{_249mA`>fckEfWcpqK8Q~~EJ z-kwqy-;afLz`Zwj!?S<*zAZ_&d|zGuI)L+)zr_7?x>>;a(yb|V+n#ktN?rOMUhciV z>8#72ue>yYPZ~G6o^_M=*VRD|aK7Tjej&Y2v##`Sp!9D|$%p<)<9+b~y8I!Z)V@{V z)8<)v4m0X%`J{OB57fnr@6VIsEd!q~|JIfMB_8Cr|CWGHinr!jx9^!ReU{(6RDe&) z3)ZQGOWw=xeAvdl{qnW%>zA*d^~=|IfR3*|xP7qxO=^$kgLHhkvm8$1Yi-f-_^f#UIadA+^u@n?J0FPJnQCn=-O@L1G>7` z=DDHN?Ep@y7p-n$r!L+s;3Qpq&n>=hw(;-oIwg0WEb*m2=<+PpAI2;3p?}gkqo#8I z)|+!Zh}7SzJ9NiQEx>8>BI#}@byM(uabLP+;1km!7|i^&;gZu}jw;S-?qo z$v;}x-?aXMbE)0BO8Br&|J?Ru}8V*Yn4vI7Z4i`pP)cdtF|%@k;(RflsRYu4mokxw`hv0ZxjS z_P5f@Hg}$^t}1N z<)x$aFLA!#{#yb*$vjt{)S3jEg$+PJ$EK|p)Ovn z?wXQs^cpwL;(ItsZ`|Ctn<>s0hcs?fflulmEzi0m*#BU@tK&0bpKGw8^e=yr-@G({ zPs&Tjvu**NH!S5P@dy{MBcSE)Pn ztUGvJbbRT&+r>}k33C_g@=}N6E6j7{P4RiI6Wtus9>ptl=UX%5+zS_9F>bd5kX41tm_aJDigbuX9S{vlQ>b zmAZJfajbdfLtUw^#-4RESGl}M`KtoX*Lc4%C!ds;{DLkH%<~YQbBF(?$ERiB)5a_L z*HH4UE91yM)^9!6JoDAx?~YHUy6St@9eL(!KF)8RvEHP-B!5e%JM`>dU8$>$W8j&u zH_+8p=C^hE!#JdQ!lII|1vsgFHC?{06wYi>q_19hjimmFR8Nj=z{~GWh+p;Q#b|x&wUL_K==qovq9lFU})z z>p(FKXD+Rl7EGj_;#c1Q30IP9s^Q;+cS z#KkM^XOK^dcMR|AMLhT1+6B9`_c8b8)Wvl&?D~@H zT)fzidjICeC9WT7)bSl5Rt(yH4tgdtQB;yw8<8p6q`tdfdr9 zCmP2CsUQ9ShD*&k&mfJH&6=+MI-ct;QrL7mKf2=9}!}^o*JXZ2$ zp5*c(#f!Q*Pv;-4Id!FY(Lbp@Qcu>!y9Vv6&5JMpFb;2gPtnCYx9*3}4DPSNzoW;` zHPH1{FMVYkm8QEtK&pfE@9OeW{jBTf+B%SQn@U~GtHd`{^5vedyKh3PyYPFu{H@KY z>#Od^O8-(r*S^|$0m;AWQ(a!9b}PPM&h`-c+Xm?R>TmhFu6;M=j6=$ww*J2Zm+ee=(7aY*Ah@@bC`Fb?j1(+=oP;<&H#gNs9}D~*5IXa4uZtIZ$g zWsPayKKM7ui||}dDK9?7j)Z|2#$I%ok7^UOVGrw2GGf7-m{|4`>&8F0RI z(Ld?_ypGbp#2>jheEC-bK51O5dDhkDrO)_xIuP{sCxY{KZi~19;J7W~I)LN0h~xCo zjyO&a?c9El)(i4+exV(4=m)n&9Qwg+5r_QT7I7R8+PQe?ID~wh9@-Jd#ff&rp; zamdeY5m#Dp=e^t(am~j%9JfVW4fwb%&0pp5j+gddZv*}R1RF5KU!f4<|mx#G=)0y|N>1<$xT!xzrKg$yh1xKcW= zt#oy`v2y+e-J|`8`d53gZvH^a*H`k504L=|t6TUBT^tp_`O@twb%&mHbAPFecL8v| z;$2hf4m|5-{z?~b5pcfZZ7Fqoo^?}yt&2AgIA8HLl)4?yx{1Hh#hV436z}@Wb>k_H zFLa)Pj+1Sru9k1)nXk}x`IGXZ^{?rfZ|IpX_qTrIt$XGhc;?Hz#BaP+&wM@4e5t?l z8?UzR8?W;_ZmfHbBm4J$^HTH7*Z0hq{s+JDRy^}{J@Y01(Qmv9O1{$T=c{|^ykY>l z(tdTU^bh;5q+9$amp@6j3OMclQqt`ybvHcg=GS!bYV+5alMk<-r!I1S(Br0c;L8c` zFGK&3k9+=j_N7h-`MB%sl&{Uaf1yVBxcgF(PpX4H@M-Ic;uaULKE873*vjF>)#~#8 z@n!Ub<{9nMeYll>*40ZBaP#`NSUq;s`f{@VCI3a|Uk-3{ z`?u9)>SX;}Q~EbJS^u_e&cEWn>hf0w+}!!wu{r-Xl>Vju&BZadfBDV%*8p8<|Is;F z|F-T596Z_j%l^BreM^9&`Qvn@c-x-&MxOZ!FN?32la05j@ z2EUi`ob33GW5F}unrFVTXTIXg{pPRbnQy~0U;Y(-<8656TldVDeWl-cYo7V~p83-M z;WyrjXTGjyzT~U?#=GE|Z_P8`*fU@8KmF#f<(Y58GhhDIe&eP4^YLBd_valruhkx3 zN#~7;u8TuDKEUG$iLa#Os{zhe9DSwkXii-zFNN3mt%Ig#zM*Hn+-v>DTldU2n3GSc z=gjML{i6stU-jHl>h?VAuJ>;roJaVIqx^bZ{u+SurMs@wO}t^gdY0;?1bouCQJYhj z-oJ3N=a-{7b)`58Z=5fGzT)W4sVl{ieACSnM}1CRDUQLMd{RAUdb<8w1f0}=Q}1=- zixfvo$)`Oo*-*xj`mg!wK+0bk_@sCno^{uix`{XYjkg4RQoJ?Kx_zbY$g^(YExP_u z0i4u7wDsIo>JB~Y=H9A{cL8v|;w^qpcmMR7(!a51|FGSpx^FynzU$o*AL>fuP@Ozi zoO?c|mhb-+T=!}7wTG1F|5x%-e)_4r*tX=3v;Tjo18qGwe&NRF3I4phobY;-l)vO@ z^BtE+<7Dp^y8Tw-bRBM_#EoyQfwm@&mu| zHazoTosNFu#!>t?-Jh>})-8R&Z(iD-`9_}k3Lo?vZ__j1&@*4|Lw@6}d*&N>=F5E8 zZ@g8{eAut0{ZY@eZvG>F^V0Clx9*uQ`%%B~);#lJ9Z1hn?|arQe9UiNnx6TFp80a? ze&els=3D<|oqq$*y2X#{bg@pQ^O=@sz75ZO`A_KLrRTM6I3ARmG(GbTJ@fV6ri(ZCX&p{mFTQbO z&;AuZ<2T-xXTA;3eEHA%jkn>MZ{0IrcBqW^GKZ7iZ>6p0wpJGirEz?uPm5J%*p2~j`A1h%byfS zN6A%GMg|EyP zhp+wRU`}0M@fJ7ci&tv5)|`A&zuW*mNjLS?`Qngt%fKh;;_;Bg*HQ8f9;v&oo4-Vd zTc0y8QoOaV>GGVvt!~{H=1S7$yxUm6zQvcBM<-g_fBJq_0CtaV>>UNa6TE4`$ zb#Y_?=PQnyQdb*CU&%L`GY((J2N;J`FU^szzaiiMw12tp{NL^0U{3#}_P{(#xZ-!` z%ZtRP)$QF(x_RaPNE?S1*SVQ=v)}jIzMV7t^7TFYx9-_LZTo6*wKH}3tG#Hxb==y1 zDIITU<0!mXcm7fMRb9NO>&w6K51sD+bY7Zs#;f&Di<9z~ypygyGJol}{))gS#j&9D z59>wZ)8Ynm>PmS|{ndQ=llU@s*0mePEAbV6GGG7D=2_BRQ(nJp%^9!cU+$;#z;M7eI@@gKl2-J)iYnuGhgcGx_I+<(c!dtZYXuNeCwY1w7R8V_|1z}x9wRs zeUslfDq6m@U)`Zr7ZNRv2U+kB+ogO?{Bw#5f1?}MatR#{^(6naxUpy5;%R>4XnE$_ zQ1aD0*I)S-e)H1t%%`oF>@EGqq1CN<)*X4~E1a&&OX045$F;6fSDWX0TNg+2Ryv$k zSBqQotULD1SG@IqPhO$(2&xA7Zq!!w_@t`bSVag;pswLSBVlzaEGB~ywmq-?q51|Xz_-XW0l3#W9F@z`xp0DmR1g9x2JVq*`zMz8+zu;-F z;YN8Kj%zpSANM?NimUC_>9+R7UZa$3m-@-k0_0oK<-}|GwN?q-EpvC3xrHfa~ zSNF^}Q1T_W_^pHDz30n|b{x;a`@1opwEoa8jn6I5{^jp;^TgZmt$W{_Ck}19l|1`5 z^2~>ENOfAcpWi&MDf@5Nv#vH?#7X@!m-U;MfoDF9Lu%j5{r$!`;vo6N#YkW>U zz~x1%gFN7T-Cw)znGf?K)j{@we(Rw4VBLPY?O7M&^;HMy2kGjd061TDF!aoad6DX% z{L%T2ccnbHly$Inmf!lrcqRW3C*>uxMOOz!!1=0!4bOZSuauYagZ;M0hO!Pio^`eH zmf(FNzS^zrnNJ%>daK`d%jb0Cc*V1>Hr^rVO8aRopBC3p=0(dl*rpp_w0w!JuHAg) zr38FZ|EPJ^?JIRhO5MUXWjzDVSN^(6-JxgQ+;&~O10@dYPg>uOIA8fgK54(@8`tqX z58T}~-}o%$FY_iHUvjq&hxwCq>z?@rp7}C)zwzeJ(T%57&$=6)`SN@G=B448FV%DY zN%gnxS-12Mzj?uaB#l>X&${V{`i-Lu?IG>=D@xt9@6LCADb+zkSue@6{pO|anQ!2k zFY_?J@mA;Llj^<)d{X;vc-GB7+~q~mEdx%fd+g^DU&k|F;vB#2i*ZQpRs&rr-u9gS zp+0y0xAJCPyCIJh2faR>d13r@XNu#V8_)&+q|jp`!$Wa<7gbz@r~~q&$j?^Nd3G_blZ1}=cD=K`qBD%y7Sd_ zqFX;l7jJ^818x14&Wq-`*V5@WpQpp+epiR%_|oS`{p0FX+a49d*E@T2?b{`M-G}S= z>i3MtB`=7^%i(CewR^|&Ef78qNBOGvjpthoGQak>jIPbiHq+IlWt=SZCN8?QE$ zeA+m&p7Y$eWWGF0{cRoir2JvL5?}UGU7fB$d-&3AD|NMTjOOH%uFqtCMR%O7^$&59 zF5;wi8(yYsH!WYTq~q)TH|0f&ccAo78?SF%@lm?``PSXInRLsKo-bZ$f7Ag!sSegX z>t-)^aY(u)z-h-nDc-hHw?C(@6i51s`Pxn5t9a(?D*5Uc&o@3x?U8$ot_~Ie=c^9Z zl)3}Yx|u6=@#1(TLPCNvonJG%JARxzLWZ^mG74X0$+JaeM}c` z9&l2>Ox`;F`1wAG2V&?a+}?~}-# z@O%7{wlCUgyWJe!+hvgP^x(k5wrMsro9eCEw zly&hI0p}~;mQpwUaa}$4Jo}el(&eQLIA3|`D0SC8>t?Uk#anu{5(j*~^3qrOS5xYa zlsG($k@ka?{kps~0Vn09@u%^}?R5WJQTC6aQdb-A!Zo^h>wuHu)#?tEx?|6}#bsT* zRlxa*x2M$YLLErD8=n0uAJFBc0XWG&Z5^yDbrT1jf4+1}z$YI6dDiVKbw{3c3l&}a zRsiQK&t0XiwqBAex;UzD(9OS$$$AxT9SU8q!mVpr1OG4{4%Y(zr23<}oPU`oxV)e) zhogMly0og25A~$|s#bS{=yLhf^5vfx%}eio@#~g0l=VV&Ilhikm-2DzMYXup8+FIo zTE3ITadp){6m1VKUTs~ClziGaD%a}#o8e>D!^?LK}XSBMF zo$=!-^-qiAbWgSpI6ms17N^}GaeO7^`bp{^H%^``j`Oc_R9DY6-*u(brSWogpIeQ_ z!QoD}u5$N}U$?$SbU7T2gXf^oTOxcMt^(~L9luaru6_GNm%~v$ZaN!qAH_eIFMqz`=*_7s#gTgYd~ry8Sf>)M z;aPXxGhgu?x_Zt&!*BlDp7};|@(q7_;&t%YzS2B;<(V!oQXMn_C+%nI@6@e-87ld- zapaz*i(>(BQXE>{HKp#rvu>uLi?;|kDc%ibKhox7Q0N|7=}e%7BydqSfsv zb=Q@;t#|4AQT7jAyuRY70iQG;v_0#Nl)C9Z@*8gj_@sE7bLvWbLnU9MuiL-X-l@a& zmAJ~gbbQHo>u}hQq`V+b+HYl^tLx`lzN(V11vsg{4Q_P(SHfxiOZ~Af-aO!Z={A(Q z9i{Hz*}CUrHlC~;|DLBC4?4gnoNe@JaR8dg^@RhOc<5FVN+=1vn{=-t$~Pm;CG0 zb@@yEiLUOmPt)<0m3$@Olj5x@b=Q@;BPCzmzRN(uc_oKK3!LTLnWWKJ#sJ9^bd+3U3(y(R4)Uie`CN&{*|8T z*T3qY>+;tEoaA5kSxW!fx^Xhq($%xJJ?6zp{jD>ne-dBfMY?#qKTzfw0v2_ZxVF;2 zg&#WqB;ApcPup&5pexlW@=5+RU#x47%#ZxGNAfRpy8SbCx-HNCtttIWjdlLz0VlNw zwwpBWt}AtsPttAurLH|nKi0*o)z#wif2H$J%hyoyHGeW+yi&U*{@TSMwFkx_@s*T( zHNg2AH~LDx{x9aspOly6HotYy{2RY~LnUAPmh@o(qz z&sY9>bLvWYNxkIeiKD^jVtwE?iNBbw`~9?#W%_Gs`s)dC86_@!U;T-6PgnA3aoTu& z<8H5vLyNnEl26-iHy19WjN|6Q6_oznT)4W@zncq}2n{DE>gU@2rmfSAGA~+OLCNPE zS6Aw4aoYCSEbeZJTO>}qM7x=e!+v(itgwK_nU|+7p z!5@t76@T9tUEj{#cS3Q+ypC_A#BuMVqPiOo(djlHs>9{a*5QUqT;^OIpBC3w@>Tcg zbhYiKZI5I@cOUM;ULB6R&xY24Z(VKObMLpJ{%P~LrEw$O zoo^mk;_L66k5Aekb-_PLcc_dbtz3sZf;c4Ih1clfP4Cj}SJ#w$*uGN!=(xeXKXeSb zQoP02>f$XZ<83MVwDE2LpA<*xb-FmTx@F*#bi2y>t0?og?m3R^>veUi%}Y(m*9M%l z-_q)il)C9R_^pEq@JV&hoKsig8+zu;y>Y(0NdDD5^9?-nVO>da6yG#oUZnB41$>fj z&$DjgA-XvFfRp^g{7LcVu5`yu)eoO}!uj#s**gEUx{3dCd{P`)!1)@7YD(Rg&-|D3qb%X?>+n^;HzoZ29KHwmo`ip(!ACH#XOz6AKXgwHvA8}JARlkn#_e4_9C8A>4&UCy6^gnxj;r@BxN*Sjq{ z-ag3T%Ybi7{112d#A_VyK*ARsz6AKhM}>Hw0qq6&oP^)!_zSOvcqROK4nG8ZQ^H^1 z@VVDH{+@&{I(!}QBMJWqhaUhw^D!Ym7dw3B_0FG?gum3`tAMXd_>#l-0N;`Dk9PRf z8=OBw34evd58vnTsdXXVD;+-feupne_yvcr1HLNZALsA`z_%s*Z##Tu;QSd#_{TeZ z74V6V3-Oj6z6bc6gumM1Qy*~tlqLK%4xhWht^aRI_yZ1K2L7IeuQ+@M@FNNT1cy(2 z(D|SFgpi*@4qpO%Nx~m?_%`6{629v2Bfxhg{85K5e8~Afl<>zKz6to$Cxv*gclaUT z3lhHO@VO5=f2tDxNe*8Jd|Sf*p2H6SKalWGb@il`3I8V!KLY$v!vC4W7uKEssm}=U{<*_90bh{tFLL-H;Hwh;FC0GiapzB4 z!vB@S*8x9}@PFg*1HdOfE5!S^4xjmi^Cu_a|IXp7fGb z!oSqv%YYwA_X!az6AJ@gnzfgw*jB|f{>s0 zI{XOmB?MKILOAg-#d_ltRclZ(Ds}g?M;R|p+-j?tO9li

4kAw(NY=wGKZ3d~QR?&k={ueAe-nCH!>`Uj=+q!mm1f5AZz+f860y zL+8&(!r$QVWx!{?D#UxE!*>8*lJHM<_{8U&KXnOziJN~b0lp*Q>yEz-_@RXVeTN?b zKJ_&r-lsc!;q%V_f`osj!#4q6mGBLR9|FED;s4O#b6;@&3?%$>9KH_t#Mgy*|JdON zfX_+zro(5x==>>5_!l^Q74S_7|ECV$1AI@yztG`RUvmD8Bz()^%Ye^(L&(pI9litj zl7#!kz;`5k+u_@QA4>R_IQ$6ksc#DL{=LH&zT*5ZNcewr_$J`1 z5`N9$hk$QO_1;d`pP;-yMDc_?(3AIDF=-&Y!Y`e}%(W0pFDH z|KadG!1pA4*WnW{ar3Ly1I{mYfA?C4FMrM9GT#>R^LmHx0KO#Q-w6JE-SO8Ye9z%a zfbU57H#>YA@IwjzR)-$}J~a~JeY?XKzTx~YNcg_PHvwOj@b7Z?A>i8*{yh#~|EBY2 zAmQKV@R@HpeBwJoyaR_H+|8X|9li(no`hd__|&gE ze?}7i6AoVneCE4Cem>>!9l)0){I?uF@f*&cx`h9>!ayYK9h0&lqLMw;j4geO86f;d=KzF2ESv=o*lVeJ9q8ancuN>+m2m3ckI}@+x$Df zd(XD~uKc!bTet7twtUw1Z96Uwb_II;1-o{bzu3BEYktq}?OS*3*|~k^?rqyGd2ZX* zZM(MTcW%#Z&+XZ5{+al+t@-Uc z@;i2J-L+@i&gBPg&tKs7Oxw0>+m_q0V^?m6vFEmL-JZ+m@;i1L{_Wd$ZOw1pWui0w zZ{6kGH~iaoZQE*qJGO7#x-GY7`%d${`EU2`{MOyuw{6|MbK9=m@>zjDTesz{|9cE< zTYk^ZojHRsBC|isXYIaV`?kQLty^~Q*}ZFzab!n+mkD?0?p%KBj-A_f@7T88q`?GY z(qR10<;`Ez5+@a}am3^%Z#LUg?zv1w?TRZ=U68@VGUk7~Z z$3nb6clg8`;rK_w|H9!1z+aW{H#vOfHqQUHgg4JIv;b70=^^Rf63v8fFDZu+dF*jmz+PTp9%5a-QnwiFG%=|!)I>q z_^T5Bo(`XQki)kn{JkB%1o(l3zpulO0H64|5O3Duhi5r|auWUl4qxBm@MQ`AAcxO9 z*x{QJev8BR0N<1FTOGcfbNnL-zun;zTOB_03n4!{!Jh{>d`ZIZcK8wS*CqTOhi`6k z{2dAZP>0WLcle=%f0)A$0H3-^h_~SI)g6w%AmR5qd}^n|S0((p4&MQMTf*;i_|h)N zKalX}Is6Fl_V$42f`9VQoWnPFJN}%6Ki}bVd514c_zN6<0QjbaztG{UdmMjH!r#f^ zQx9?Yk%TWgd;V*Xh+`}AxDB;g> z_yOQkw-Dm}9fwan(D4@}{No+I_i%@=O87;GFQ4P^Z3$m?_(Z|s2NHhC;oE>u+){{l z+2IR&9e+;3U+wTiz?UWbeuuB0>-d`z{u+nR>~r{@gg@Z$J;0A7{6U8=pXd1h4{P@U zAUAQg0eI-9i*EYRyU`V&&xA7c4x*bbYUl_;FFFK)*$-Z=4VSFI@gK z_>^AF=os%A@cz!o_g(%h_?SL)`E%g)F33+@{wusb@|J+Fg!g|YzCZ9ad}zHZ{~P#> zUeDy{&+MpQEs1&pm!AVZppRXCPWY5Qb9oQGqAy*3E_kyP>i32@#ydBBLT_At9{7?z za`}1T{iRV)>hkl$$Ml8EF92WAtC=0+9S*OTK|Q|9F9;vehc3Smd`_RZ{KD|wvZyC_ z`9GVm3B>GI3Lo8?izH>+d3 zE5Il8#^qOnFXyj;TfwLF-W-ncZVhkvdfd4DHt;2VSF26mzvaf&Vbc}Zg z_>|sv`7!W@ua`rY-x0o~Ph5T{_?WMkbC=&4Ui0;G)&}C{W%dnqYqp@h7auPUza}xzM{`u{#y9NzW#Oj)8YLMx&Je-W4vd=7xc#E&xVie z>tC1uIlO0I|2n*%ZB*x7c*`*MM*RkM+&eU%aH8u74c(x&Md%O^umh(gj(}5C5j? zA1C^mT7Ri;kIvVb=kHXizR=|0_j661@niKYUk_j?zUZ(Xdp)$U!|~eszo_dST#q^z z^C9Q^1G($<`+4x;u9(l|{EqpYz^mOj{}=di@9L-D=%=~>`6=_w6y&c}_r%V>Y{y1_ zE<(Q99rdSEkUw~S?$_8}>et9GnXiUVU4Mo(=BK&@`EiK)!>P<4-r>rd32|5qYE+!OW3Q<>j-kelTGbrtf}UdS(}GQVv0|7zr?%r^^7 zU4Klo|0(j#-l#vF%6zXmKd(W4$$Yi&)YU(%+5hX1AMbP=l(Cq*9$k+QKKcC9{ zjhg+x0r@%e^&(T(pQ!oxb0hM@pQ8SFD)Waox9?5JSNkEqoXY&F+5d6KPnmBPox1)6 z&Hmqve6v65Pp2|}Of&yC$S;|%7Mr^I$2Pa`Ey#}#K>eX3U)>6?4}{MhUV6T^`zK#C zx7TgR&zWCMVZPm;(arhxTjYlaq5fd;sq1IG`#b65`R&M82O~e5!hGAGxVgPDap1Omv!B01e#!iFD)aqj{+-B=4@LcIi60;Dfq)KfUTsRz=0J@}*b{2BQL^VQNrA8+gRg}wg{Z_bDNkRKh1`opQrPnwTce_{R? zI9@lO!hHLFfo|4+Kk~h!P`_U0$NQsl_>4Yw_{nXrRzK&dzgjo{nn|w%ryf9la5U=4 zrZ9hA#H)>(`7=*9@O)D--&^*_$7|}G=6q|_Z|}d!A&vX*gQ!0li~6G}%%7F@r_KDo zBHup-`Gq52{SCgL_m`Wp@!IXR-;s^&^$^GVYt$1?VZPm7VRL&u%<*1~{Co=Y?f#74 zod1s?KW4sOe#-h|_c!Xx%MZ*iZoc{rF!rDMu_IqS2A_U~`+Mo|rv62fo1YWwY3>g^ zj(mLy`suAOb>kh^e7yQQ@+0O)Q<-017JSlvK7st4`Nh=cH~aG>^1VyZAAiLk?~nQi zd`O=-ylZ=H)Ew_Wk)JU?pTc~5|BajX-vasSGK^QR^yA}|>bLjbvCaGMQ^*gPA5USv zozELJx7WXrpEAF6W}wFy$tVN zh4H3>AI|qJ?Dndk!7TjKg zPw9iMDI2f7zb892p08g=e#QJ)$k$UkAKpN|NzuNG6z1EM5RL9r?Bq4!x~EX}ljL)nn&>b?T(g7m~OAkA^tjM?0+Fj<=xi|9_sJ_W8GHJpa1J z8#X?Vki4DGVdMTNdE5WI@%STo+n;iX{XDC~?PcrHjr|8#J^OVyUORs#bXdRLpQ$?R zkM+Z@?QA|z9B+r-Zr`fI`mMjD!~Rh?R4)g1~;lQoG!}{%b$8}Oq zJ%3haesE+5^I?!Ljv1OSJISwWvHgsPc>fJL?2pYK)1kNb_pn26=cihrv-xl98PU!XvJU-a|#PxqW6z_G?&pOj?uc*WAYwuri zhu+SgyE?f)4yxy@PV(#duuA>kv~E=={U79uA#PuDRA=+e))V}Blwoxa(-d?M=Hg0|MI^15i|3!z}%jU;Je0)xZ z`uN<*c4c^A7JXc6+5moDXG(+t=n#7-Ih?beM0Ck4ie(UUh$FufJNivcvaJ z?0mSS!+iVrlXmFs`3UOJ&K}?Fc*k{^KODnV;q{&6*PChJc2|e__VsMOT?da>b+WC$ z^+PB7dv<@d>M-BVxB760j`FR~I~=d|j}Fm$9gf%Lf6>YPrG9*{zUZW$LH@2z?(c*A z@J{L<f|PT>b<2 zkUnzx58*TV)a5^dSJ(6NESLWnKA=}yIL2GSr}Vzde*$08hc5pgcyj~lPh9>}_=G-p z`On}>`pV`13-8~Edi0i#{(KG}(+4j9D&}YYH1cDY{~z+hXW%oJ{{mh;3tzhYm+&dQ z7dXcI6})*4`NrkHhA-(Om;VMn9*_Lg<-dj3&%+lk{~dfzueNfG_j~y81?2lKU%#>+ zc>H}4K6LqM;8Xg<<)?)=FCjm7`RU+G`pV^}hmT)IzTVo=pBdowEAWBK&j_E>$1Xn; zeE2HzGnXF*uS)pRAh_nnb&S`858p(-@A7lOtGD1om!BIxrB7Ub9(eOM@^hD;7rvygTz)?I_#Ncy?Hv7? zA6`#@4_tl$_?$j=`Qh;4yU5R6enEKk9(?KY3&W@M-u901E(&knN4|0S#ohep$>kr`zmtO`xr&l{T#=9JR_!07bmtO&1eGDJE{7UdCed6+~z?%yBxy!E# zU(#1D-vu9kf_y#3(Vrf8{U7+iN9XBbVP2KBrGzek*wITjUomzYTmyuXb{bcRTou-go&O;MI4iCv^E8 z;RE`_<#&Ql>2sIg1-_!MTz)rr^F8X-ZM?{>Jde`zMB`{07-Ie7JDG2T z>RG;%`7_A-L-b>YSpV=&`ZMV9q3mS5gZzH=Se)B;kk>=3r@xc=Gblgoq(6iFgdvW% zzmx4XD1Z4Oj(5Ky)?dl>FHvurf%|Ri@qGMdcs#e?!@cmlX=v(illXC4!rSkO!{5dI zSNpxr8@QSJ&w3NKZo2hH>*vAGNA=tHLz+K+qo1m={$A^Mv~G4?z54fQ{(k&JV|~A1 zZ}cIZ7vI}_WBtIGK9YQ6eZq|1t~=P4-(3HY-jniA!TWo5eMN5{)LqUa)E~p!^&1Vn zU6-+~o)h8i`j8QQEae{$Z`Yqp>Fv6bZTXG$Eem=rJ*E3B6r6w9OyIey)Z6$(-J!VimcHPr9e+2UF z`m6e<=!;!fwaquycMa(6x~*;gaOB(dV`KVgE}{R8^=UJDyY6gTeuVsq>)+Dbb#2>x zV|`t3Kh$B@&296CAm6UvYv}E|yluX*K5#@Id%}2kLB3soIHkAi3b*C&3~$#rF6iyL z#ch5kc)NbG+8=e;b&=crj_`JUW}n`!yWHl-z)xKNnclAJ+~#+Hx9dwM^mg6oHorZ* zUB5b~_vaM)xgES+AG@MglHV5IuD`7hK(1X^yRDvW;O+X}0li(fyUlM6Z`Tix>Fv7U zZGJ0wyFPhFZ`U1f^8x(C_0Q?OIfVXf32)a|_YQ=!>!!EmZvk)DZ#VRIUG_G=IlNsT zKBBklzPI@`;qChKDZO1+zRj-=Z`Zdk==JQvcvpkB>*uS3;Ox5iZTbE1c71-I-mbgf z^rn97um88!O}GAN{oK#*t-lXzoL``p#rp{XKYvNOCVhXP{!a$)4lA`hd_|wLo>n$* zllm3m6Mp_ux%|rTK0kla2cthWy#79E{s{PjK5%&-KH}#uvCDVEd;I(*bNOEQjJ|aF zKKOv2zj%i@#@i2H(Hoav4L;%LFOkdt1m5T8FR9C~0bkG;F8@!QpC0k^7j>v(ylW!g zAC7}&q1H!i<1@)Lgk61n`Q@IF6( zNnL((_=3K0`42h&`T2`F+%et&`5r%i@m+pv_;5D7-VI%TTaGt{Ph5U`_>B3v%a4JN znP0j5$LNom9rfs+Ir_6R@&o$7<#&Y-uSI_B^1H*Q%+FkY5BQ3{bossDlj~8BcZ6fS z-=aTe4tV48M>C&3a{00F`Hjd=UH%yOlKF+puQtQL{nwup`RYi=c#lPXH4ff)`E`*W zGe30sTXJG2SE4pP2O+m%j%25%VLL zzYad9PhI{7j+gZmE`KuW_vXiV)p3sTjzfM(@4NhO;PoGnAG-Xl@EP+Hm;Wt%umJLN zm(Sp%5%87d$KrZ7^+zoOH~aZ2|ElcYTc6YqzTS;WW*T@tO&&qMKHkyKJ5f(bAG`cT zxE^c%Cf*l_ZpQh()%!S)xB32qx&S_+FPWc9K7rTt-U+Bbk^Fh^#T%%{(1(IIt$v}2 zy7kSzA7a-_8P`}}MV*WMnE4U&eIZ|+1Mkxp^h)w)!I!V|eU=k3-r_x>pJ%`)^gewm z`P1MHeMlck{uKD?HPn;P8_CD;DSb}wNq%$8&w#$7FW(i$dmQo=y*>&3$pmk>P3v#E z{+hUb?fN$3o7?vo^3~DsA$>+4Nd8E8kG`bWlK&Ze{wnJ6VvM(%AoS-j z_=w)n=aN4ZUeibPiR2H4FJ3`CDSasU1L0%(g5H<>{_sA%IvL|N`{MVtJ)Zm&KKTd! z-KSSVzTq6Gzv=pG;(W08_e+}V$L@oC!~Br>#XCa(_kypUL_IluD)~L&Q~HWNlKk%Q z0lhwj{gM2x@QOa5_awhFeD(zDkLk;|h4JnPAJS*^ndEnX_vlOdSn}J!=YK~%-l-UG zAo*?JBYH!x1#dV9>TkOKYMT#Pb3SZ^e9iob`PExOf3}1#9!LEJeJ=UU;bVGr8pfMQ zep7g#-lvbA5$f3(zI+Vzg!D%88^R~_3B4!z_2CVDPG3GP)N?K#|Eot)Peq?eejVhe z^!jx4Czkx$@Bw{59|+!X4%FXt{WWnu)Q>v@x3P`$XVqHBSIm!@uZ4WI27LAi##_=? z{}%eQI($g)oq_S@lK%<3M{np8$*%^VKa6@J`cU$t;UoH#J{yVuzV4H@y&7m(eLz#| z{a8(3(EC#UDEQ(blk)2W7+c#brH|>$ zr-Xj43LnsC^qJrddsu(d^%weCzo@b2`)7^yf7A%%E9RGWyh6TO1wMNa<27faKY`>| zf)D8nFMXw~k2z+@z>d`;Pc(u@fwJ>}_ zAJF?J;lHo%+jYf*ZVSR2`j}oxegXLEFUZU2ixVfGZ|Yyg-=|x@we|Dh&)=iQ@r`Oe z!In?xefmuD-{SxQLm$$|lK&3Ax(W3p^nv8Rg-_{o zdM$WU*FL%VV4q)xH`c3B-ylC=er4;KfIhYL|7&r4J~_=rBDSCaoPyrxg-b7B6w z#yh^b|L_^|i|bK;!TjPlVS9ZFAJh8@#+yq1Kkz<%NFPc56ZrBv&VPC%`3gRv&*?qM ze++NvEBf+SVZ0x~SJ$E*eLlvU2>n+d!UyyLeJ1690H0lh{FpwL{QK}BeMTP$UYZZ~ z{yw2OAKpX0$NZA{TF6)L!sjXKHy7~!evHu13GfkpM4wCk9e7Qj(uY$2--a))Mm+_6 zBIUmYAJeM~QGY1;H{r{xknhv`l3yC{qbKwsy^{P=@P@a3iK4}C28dEoOi;dA;x z@^is!`ifpleopw}4CL#JG2Uu#VZ5`$$MgYxF8NvEefpR_k^Ic?<>{y=qYouN6MRBn z()*I10p8Gimted~^3%arr=cE0U+g9HN5QA`5q&E8@A!EQeM%om{u_8jU(g%Le+8eN ziu%>17_TS!FW^IZpT68v81Lus9(_okN&YkV{1nua(8rSh4}3(Q(+86O1YXlu^jh*2 zd~q`B(U)=l?;(u$WB8appwA`$5xh?y(Y1fmie?^Nr-+hR;q!Jq5id`M2OhdUXZHTkbB@ z|0cXg@6%_Je*->00riCRvE*NekLVNnK=QA_YxKeeYKk~-dEvcdVMAO zlS}>;c%MF?PbB{`e0dz|iRnYhzXYGqXY{`0UxYXGCB2gT3-HyksK>hs<1Ka-`tv+| zN^j^>$&ZH*=p*__^3TC5`jp;C{#p3!7}Q_Tdy;!*t zd@Sk->0`-103XpO^nv8>hu8Euy_Woa@Ws)nr=qWR7RGxoe6=sUPC5T2e>Z$eAJ8X~ z{}X&bAJd1D{{y_D&***0-wB`XgZfK)CHXtxLwfHT&i|c+{@f1l(Hr_y^0&d~d!wF+ zK9c+`@DY7VZzO*+yrwVcJ;~n$U+jf?)U}-dI|}2y0Y0Yp=`+b+2k+B|^s(fxfiL$& zJqdjv`K#d*`kY=%{z`a5U(r`%gz;VuU+sZ<^mUy7lD`x_r4Q&6$zKc~(8u(l@)yEqA?h#bmE_Nd59z(@IsbPM`g0z_7Oa35ukKVfp;|(N#0DQg^>M`_M^7R5FtrPv{f+VjZDBo5CCVoIaKO zCh*k`sHdWjB)>6yO0RF`{Fi*afK#hK0ewL4Nq$3kwGrxx>C3f+@ooSgZU~>zXOdqZ z-lH$+W67@vpKpMC?>C(Pl3y1-qBrzf^6S8B`iQ7O|zU0?n{(7j#zXknKl3xwp(1-NJTEcky;j49#pU|h0?}HB`)SuHw zlJA8Nm|xKw$#=smdVMR#>q*{+&(=Zx0e!iqFy0ZYpFXC~B)>AeN1xHhl3xMdKLq_L z=>y3x2Oq7C`n}sQUM=}$;5EIWuhtO8yA*t3kRQ?Kl3xNorcdb;$uAD?(--ui@FMlG8cUJh2KBmtkKQp{XpV7yXp9wx+9rcv-f#hd^kLbOO z^I!7Q!E1U$U#%vLcN+NOC#WZ)&n5po&aaQ@Q~E^m-@^O!1$`*_ui?wpP>;HU^I!7s zz$f%Ry^{Rf@PGDXDf89uIsYYpJA6Rz z(<{mU7QP&gdP4f5Pw3BW@QV2feJc4|;lriTpPW9D{4K1X+qa@OlK&07$9(+<&VR|@ z44*H>`A=U;$BT}GkLY9iU=E=_H^FQAj9yFrM)+b$&VTx9b|L=;_?X`NBgUIc{(AUw z3FI64MDo|c8~TVol>D{usYZTE?@Rs~ctu~(E6Jzu+2Y7of5Lc+*@XUF4Ik3`^r_^p zg7@e{`bhFu!sm;jo`l{={tEbrKBxC2e>uFrDDo@%cvfM&m%*2d!0WrvpFr}L!YA|r zy_S4^f!x;PxuK8gt67A4E{3lbMm-sQF8N=^sCzKpNb)DZNAy0uk^J%Snm(lW zB!3)yF&yK9>Ag`sq=Rz8C$`l3$(Yvrh*f&{s1F z^&gG=gg&OvC4UsWq0i_O$-aX(G z`j|eK{O<6EKBG@0zbkz8E$S)hL&@(9pVE8xbN)+yKiuDQUjHK61-^btv$xjt`r)=C z@&o1@<|`?Gf8=}9qW;MG9}*|c-vRlG`6+!dozVXSkRLL?aOH1@{OlXlqjHQlmGTcn ze#U&C{)h4h?tVY~bsOY|%n#`!DgPkktLacr;>zC&`5yCgdL!i@jQoK4l`DTstHS)TG;Y3*<-4kLk;4h3$JN@+;0x-kn#^le#!j8mA?t{edepbV!T?) zKLYvw3>dFZFK*wBkzalZAJSLT2;28a13@@2%~XFh8fyrTn9iUogLNPe;C<5#tT$#r|x7{OSw%m_C&9&qRL2{LGcVKJruMm-N1re>U=S=6er0 z=Kp%g514PPm-5d+zBd!b8(IHDgC>1^SQq(<`6+#&g!ywW@nBR~Hf z_2@^?A5Y4^2>B`V1A4JPD5j&d2-}@+;^%%yhrTiNDDo5L=k&RhpCZ3te&xzv82Rc=)UO{$ ze-bJGTIB0l;RAZHKMNv1djmeE52gI;ksmQXbLB69{E+!2efgr${~M8?GvE8WWB$*F ze2@8tK9llqV*eMzcq3Q-Jjl;qhfnEaDgS2ne{uN2l|L8qBj&3oFy27QzlHs0zE3Z1 z-#L-5nIF-uVK77ef5H{eQ!s;r{ODC{>;danXjKje{w1R4&;Z- z59r1I%!GWO`7wPW<^K-(8S^t&{tU=3ON_Uq52gIyBVR26@BPCu|EEK~VZNdFrTjl4 zKVW|3%AW@L)vKr{wO-1<3;8MY3+sQ_0F&-teUJ4*1LmuLV!Xxk!u+`h`4#hh`XAyO z`#;|zUok(VPo?}nBi}5E@g}bPuaTd<0-w`IQvQ9&Pnci1^1noW$b4O(KSs*`3-U|m z2lQfp{)hbhWz-+jds6=W$oH3m&s_QcMSjHmlD-@-Y~LLDG4s8r9P|HECxbi|HB5D^zr{yG2f^EA-?hW|1$C; z=7;pDl>Y?s&2p$Gapk{={Ng$IoIaBBpG1Db{K}R8Jo01a>u1p)Bjx`S`6crMda*yx zA>U_yOz%ngPa)r59^=hi`OhG~d=|c>FP{;%@4t~BGv9m8G5`OKe8YT0pGo;oBfnsN zyp+P>=V5WBxyk{Ni8mhTfO*-$Z`E{K%F65b|T@ zr`AjPZzDfteqsF&8(`AM|Gy#MXTEw7<1PLz%%2I!ubA)C{}A7J{QoQR%cszvkUo|2 z-$TAx89s64KZtz8{G2|L^4~{(!u-mW{{Zr<0`=&Z&>th^e}w#!`2oGypB(uC^J98X z%CC^`uY!6qSN{FTuP<;suwhF2@?XOC{SWeE=6f$Y=Ko)q|1k0meJ169iu{84kt_c` z*HZz}oQ;1ha7A4&cectao28_C}cUp;_&QhHDFH^Ha$1%3HX zVZ1lM2lVPSj5m|~b?}Pbr;jCn4SbfP{*XS9{MGOweL}A#e(@E|CI4%9O&`#QlD`PP_zUWZ>3zvx03Xw5^h)vxyiZ@!7f%ZPIS;

AqJt@5>`7_{C`hvcELKyF9@BzJglk;El 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%0DBh4lJJ93PtRTuZE0 zE4M_mf3}ow@EHq>?NLWQ)$cEVnd<*znt$T;bho&9eZ*X|e~y%Ii=jt}x4k>^6)&4+ zc~j-{Xne)`V8mWe-B*`{n*DPrpO}9)t!zJ1+;!w@EO@nFq{-= z!WQ$-(ClAM`HF!x_PuqRSIT@{?O!6zzpGo!zeKZtp|pOvurA{Dc_f;9oVnTC)QuHx~cLR$92B{G5+7YSDTc*3 zeE7=um-#y0U#ZKb$Etjzr2T_;-`VF`=_wumj5PZrH7q#QOf@ zAJ%@dtk+tyYvbY2@+N#|oqfhPWu4`{w_%W74d2`b;U);rf zo;1Eg7CW_=FV$PTlHT~bw7iM!WpG+>S#j6VKVR{_LiyWN^ChA2U8DeSJoe|4O1`|0 zHT!2$|HS^qtJkd6R@`;uOS_nFBCQX^`uNbzP8?L`D)0T3_4+qbT3^j^*!AM`O&$4c z#rq27?@{&7xT5p*^a{6cDONL;TcFv$K+4zsxG%(Np(9_|#e6m$FA?kKYnOOunM%0g zf!#;1e`BP4|ZS9dw%`+(lm|`P^R&F`qle*Hj!A=kjHXckaI={a#+H^!Z)%dGvm$Sl+CMo)fDXEWcg! zO_B1wx=m+3TX7tlt2dW?ZSQsF3%lr>LE}+qjW3^RpE+OhF8W4N|HSLx?FZifdD%Z# zaom)v*P`{Q*l~HT*S6o4zPO7%n|xybd%Xpo8(I2H#c|2v|2uA~<-;MLSWzA4?jep} zb<7vPi#~Hryj~FF;r#yhf0w?ri#~^ZV*Pi^^z{dnK3j1dtoZ+qo2uRsl5ekmL&p{{ z*3Vt^`Q#JZ-^14W?!D4y4Q#z$?g&@>rOG#&eB%5JeO^0iiJ3mdaVyRjN%?*ovC*W` z7j)6*(tHuGpRJSLIHmMuUG$Bke4@|?7waXqZyn>|D2_7~|KD*_^=}IK#Qf{s{`R!u zuEUph(P#AQoX^i*|NDPRpRG6!(GjlrOO?-~{)y%H;P$odEq!4ZeJPy}O4QqT_n#gv zeR&ss-KpMUx6N?2@F$nPP;s8k;{Q8ts(OvPv3(N*d+)06r^Q{zcm#^$5U{EH7p<{i z$NL}47vKRa{da}ZmvzzS(|CyEEi10{jI5&6XS`mOYN zU95MQ)W09QUHjZjUl+$Cmh!n@t~jprC0+C-l5g*y)?2sqS(kUMe;(BxT7sof1#`lK3mVBu6jqT!iWaJa;s||0TICFh9vWxZRl5fX{r;GPLus-PG_R`p) z^Y#9#2lqI<^ob8*h-FZ9Q!Q_%Hb^r0D&w8?p>lev) z;BT96Ui$Jbj;|y6KD+Ob(@S5_#eD6>fdkQZvH!f?`X@{;?kcxzu-@^UQPT3U(f)JH zthfE5u8r?l@`>%`rF(z)adC(F*G1n%$#=(Lzs#I3w&J*7*$mbE>t=WEZ>+rf@;8wM)JYHn?=_(l?=t^^PRp5{2mO6)zBP19$W<>*9PFBl)gtyZy@2=UmaX@y(?9 zJbkG@X0A^|#c`72_jTM<{wXnr5D_;Jgds@{n56^pTP-%XQd?(cTLvTNhvdYI25<95UM-MzT$=%2ZI z*XoUj!zcDnKlrL&XTH^z>e~8#MCW)!XPkS;%zXX2mM@d?{d>UJ;{7Ppn-1!lukSXf zS1fNI&UZ}lH+;t6uK67DiT#a_E;(eo(iivdnlH4`Kk-KB@L>pOZ6VncGb(JFY02xNUC?Yvu>DK@2E?t9GdF&>|M{n*U?`>cz;u~NR5 zPTS)CGN0MrwS0-xzxRLN?4{Bdp4c_tM9H`CzYi1dcXw<*oG#|eCEs;(U9)NF^SkIX z`(ynljvp-X^uV)siiOJqR%0pc)j)5-FBh^jT|l&F4wu zd&WbH{aE_kF8U@&^Y3WiI=}RpXLK!JRt&6|%VMGJ-s1DNiDExrwf`JS_0IF;keT%c zU95K^y}!Ryk#F={Uln_+)tjaH{%Uw!=lbfB!Naz#+6*J;+q#dcdL#0Qq55iKZ{5eB%ALUl%{_@wzWvMX%m&f5ZBDkwUcHI%h0X z_l27IrqKMGrw}baubDP{tLo*mD4&?qhwK-=U-x;M`Etr9J`WeK(*63n&r-Z@Rn3=n z$|uJ6(w%;uT=&_U`RwB{pT+nt@#6;K_(A2CY36gK@tyaUo~u-3;(=zq8PfQ^b@+Af z)_uO>b+D>`!=&%e?7GvFThx7NFTLf>C|2}hu88@!MxSAS)P43Edh>6jH2>yb?^m(^ zSGh%+`MOa)G5|b-+TRvta#vS=8I_liPyi&KlT2jbziWi zUjN2O%SW%aF?ZE{j%L0@T0Sm+X_EN7K;`Brj&rEy-vnv-h=y*|=%1;X&y?ohfpb6q zO(k6MAl1y5N%^LI-hY?6FYBqdd<>htbNP7WfpKCpSGk3@-uTXt@|`_zTO(hrnXkLl zzn$J}=5rOtbyVZ)N$ZzM8xL>f3pDdtQocJDo!IDKrkT&&uygx+$O(J?t1=kH16MO& zUn!rn#g}4LSh@L%<3y_d^_BA7eZ+OUR%FEkOEaG>lyBuXMvCKqm0PHp zFO~9LH22>RugHoAX%D^SccheW_t(-sbziQTZwloTE2>YP*x=&2FVf6soY1*{zsEn% z*sAVxx7Hh9W24UP$EO>gH=*wHHS@*vdS7hV&O7&OQE$ibKjX~Sxys+C+J0ox@tjL% ztoB9ei@SLIV20%TKkS_ebQDGRw_7#?s0^qORIo*mAdABukfqt9EDnko5wQ`$Ac}*y z1aTQfFe>Wc0&&9@M1!CXC=k>aTHJzw45%1fM-dDzFrq>Pfq&iU>g0A;HRd+&3*Y$; zbq;iTGV|njm%3G5y-br!W|#32K6!ylE&sv#^WvXBhQqFuy@B)n*_*+6r!r8_pP$`r z^OURQdCY#FYF_@+kiK5?rsT6XTl%K^)0fS8Ffq7r@le>Lc$!ap<7j>8wuh#4wRvHm zyadX>K9R*4HZSgTeKO4Lh5q~b)W@M7r0mW5)Zcn%66w2kR{jQ?XZW-?59#~m{JS^W zJY}@Md@(qWl|kkE4*8ebJoOQO`J%M3>J_YK&lqxEmd(o;JtXEOaOVxv}ZI;@+ z%+LJQzXGK1?+XUpWb<^N_L@lFoA5wRxsbdy`xr=l0JE1q;K&0^=10huKxU&c9~VL zAfM--b2D6an;L)BC;ahL&Vzj3_x2f3W>P%k27mF$=hs^R?}56Hmhl2l`qP)m^#SO$ z6Q5)MTlzvi{TJfAx(xJZ?PoXIyogU;4${}X=+dao3(oXsufg*Lt{2F8WY?cIFXmHU zKGz5Nysc+3U{mpp`K(tl&V&B@b;~iA+q~Skzxo$L*XN`STTxa|6F%)NLi%=X84R|j z>;WS1YG7k1cov8^xelb6AHkk7jpgbHn*(%oOa zXoz=TwfD++NuTk}<~*oZlTOM0*wz>HsV~fVu+aHw@guWsp6-*EhxFB09~fryqCR;= zydFUQwb}UABAaLW#^?U}TOsE` z{{8k%-xfB{@X3oKeGj$kS$6$j(x?B-A?3$!7uRb0uKm1`q|fKSlyH48p3m!@S2kXT zG=Kd~Me#lLkD}Xc|3!TA(l0MR9^5-8_?pcNeC;n^f=J)vdw(s{7xSqvi|d2@JHPgI zm)iOgK6yIlLH->-ymi_2Yk?mA;!(=`FYumRI=76M*x`?t%k@G1du)8avV75e>Wgw7 z)V~oow7s5fQvKK1=}%t)(sy<i3!8;$XZD{kNK6!zW<^6Z)Sr_XzFYeQSX~QfY z=-U`6EL%TNdiwL9%6X8_(QZ#xxAg^m^1>*-W{dYb+B{>IKYf{8ALQTWXRf%`<^})o z$BQ6+-P)Cu>C=7M8{+yP|Ee9B^pCAC>XVm);=3tp*_}4e^vR1L-ZgWZv8!vW{+sm4 z)7T6MCK>7M-&0HeQ#Ri){_+=(7}p2&@9G(&Ke6?xz5MZtI1ln=R>_hwdqX~XCd!wz zRt+25`XWAg39b+Fr9-nS!);#L7yjy1DT?n+cQz^;-y%MF8N6OWJ!n&<@-?=;gim|3 zudwPB#N(>v%_rMDt+&7U7IGfczte`^U3Pvj?voeiJjlO}(QCKc`jkHY^y#R7^gsXE zl{PQD&mT`2Uhcoe4;AIxJl&^06X{!c`s*`nUZ9^peJa0y5DLMJuHUV(dFFfm@;S-v zg?L=@-TQrQo^hPN`EJ^k<>T)?`<{Kn=4n3d&E)phW}r!5PAfZJjrzQQTIKqHH~#Zg zu%MWlUzHU5^Is<7MSm?Q^IzDfy?VRyHc$7-3!(n;XMSdRz4v%-BKv!(cAWi#Ya2!S8Z>{TOkc99 zzkG?Ic)T}v$X52}QvEIJ(_Vw;AFSuR_TGbwY@XrM-XhdLKInScc{b1VsV~8KF#c}t z+N`q8(~kG&zif0ovvyRxtp6%L*V{|EK9~>fxP562TVK+ry(W(boUi?0)e~j&A*HFm z{u|}j3qX9^epmG|TVJ4tKmVzhmDkhT1OFLP#%u3SpR(BE!HK~SioR5Bo_c~$eQZSo z#&Y28?{!+)^)$wX{`3X8y>PsL;-vEDeQ6%|F|oI$npZv0xV|&lyC&asSJ`?*+^0Sr z@xJN3b0)*4>VeYVpS?M}{y~3RTmRa3Y@XrM-U!#%kbyQd?e&Gt3;NWj@p!=b^IKm&(qU#XRmSV}CZ)yy6>R2U<`M z*li`s1Eq)myq0_(U#R!`Pc_S)hZ6P~-y+UqZd3v-7A;_#RQ?$r_o=bpr<#|&G44MY zKdLP+EjwSPc-*(eajECo*gxZ~$$2n-)NXRc`)p(N51+g^;`NG7E%Tr0lb1leP0eFv z*LNB|$X$vtD8Y+sZ!}KgKt_=4P80^T|^YuWgg%zuCO7$9-Gu_o?QU zFG|qT2le#!7lysY-~O)~PhR`-I@N9z$;b5{5ZP({Gl~JG}IzqwCvWdg9H`9Wb_|5wCAAU@O>QFLbhtpIrjy_nob| z{JA$?`f`!~ZXS7lo)gCYR!E-LUc4mtALPqWrBxd@FG%!X5c%(!YIzAaFF^EPjQbA; zj%!Np|JBViiT;Zq|Be0hq{rR7FwuX(epY^> z3z7fENcirtEd=ixd5q&g%>G5%uI6jodt~B~4!z&p+_rnz5q) zVnqL$+<(;=Z^VWfKe_c8M13mq-v!m~6Z{t(OzXcvx&Zor*=L1;~GkCl&Q}z}SvT z^k0z27v{S&f4cNPZeD`uzYy|YuxpB*i9F|GgVTp!FQ2hR9Pn7@RH{xgyPe%bI4 z+@IoT$$GSWF6Q|M^Oyc_EIsIeu^l5w%Re3YZ|wL_g=tBQ=)W-PzxPzWO_;x^?3QmB zTii|f!~6}!$baAd85!jMoJsUw0`=cVe~An8muPF6zA*CN@EJugjdrxaCA9pDApcE~ z_%E12(^r7zFOR)(#U&1LY$rJU{PMVZIT%f#$y`^4|?(7YY806aANq{CBOy zf01)&`IpwG{CIU%&aXqA(O}>AMD$;h=O6fQp2UAKqW=u!zf-HSlY*`m972o->c96( z`fq@ke=73dr(=d(?vlrDQlyO^rKtZtDe1p~@icp5$bW+?vxmI8T9oKNgZmH0-xY>9 z{>B^A@-LJ74+e5ISt`u`;&o~MQ`o{TBngba@2nEX-!RdCCifo;i}Kn}OW$Q1M@tg@ z7eo1%IB~Kt{wB_*`7ea>?~UE5`$-)745I(ixc^}NV8>sd3FB{^=)XA1zt)des_ziT zc0!lZ@;Qp?U*U7@m^Ym*aT6_Ha*+QDavp*6QH~ZS`Y*u!2la3F74HbgTfrM?_9l@3 z&Z)ZTY==0u6C?Vs0Qql)#D6iO|4crAsmrvyR`RHDysr`c7e?dnKN9~%iT;c5_=3KE z+KsQf{TCqWGg1FNhr*sLw?G_sa!h{Rr0+O>mS9)e+h~IRHFY3t`7#bJ#{Z1>DFfw^#zgt8cO^Zm_WAzv3{}L#^#cHgDLmb-)67?my z|De$KpS49;zcPvbOQ87H?KAiRw?2iaFO%mV%%3kqD)Pwt)r zr$HPoeljgzl#Uh;5@p{LaCM=xnPUaLU!_5oc zMC-q$D88f4_#Vo%qlJn30?2>IJt_JxO3XhE#rLn`e(dbLvuQ+qCi}R({?g#XS+6*0 z-g~UuOPh}3yS+{Gw(d6ti2CCE`#vEMQ>S!)gl(X!C?U2qAuLY7FL?9PSHyk~pM!dJ z@V57a^>O}jVdKS11}z@cmsKquFJ_yRKEvntL!_bS-_JR9(Gr`N94ha(woos9O6&6e z`^AmF{%rG%DgOMI$@M`Y9oW12KARWx`TYhey8;;E0oUsdzo0?X=9!oKvp0nFow{tm z<2Elg)t|lW^C^9>kiB8_95~EO#Wy+1A1{vX7rL}TZkfI6HU4-8zdi!;?;iEtQd?j2 zW`F)G;rbvZvjZcax9=AZdYlJfZ%Z|={7WBgt#{UC@9H>b5j&nqOZm_Asn48Y#RJB- z^G97Z$L1w{@)DeP8sqJmll!X83$>AtYbj&de_r+~SC_Bvz80wahRsuN@fQy$C=d&% zSH<_4%r^}7NCfzMO1p~j66~$;e&`rkvpe-* z8%GP@Vd;xacG~ZyFTnM|?}1s-=EX}#_I`KW?}EKvd@o)J`vBMr{(E<>Fun4^rSe6_ z)F)WH)QO6lo9|O#;j;ow#)6Lp`dax1*@w?B9FwB51y$eE9au_WSK^ zjL0+4{NUp*_X^{0gvg5zE%#rqj|`05eMe=xuAJGPmyK5i0ud2C`}*Q+6erwHrW(P8p&&NKhG zKDa)j^Mx(5*~ZbLM14`NkCg=_Z_5Fp9wdqS^1rjbue>qit?4>to9TyRkT3B7E&syY-cy*cnN4d6>vaZ^ z7r4yQ2lJu#2N@r-4U}pnmLazjeh1Af|MIxL+Uz~2-Puj3&S9cH1M!}f@H8T?5b>_P zOVpRBMT9>7Gm#hM`k=oBc8%Tc)~6GBD%S_~U`f`GEIQ5>B=Uls2jk_+$}5HS zu=t6zcw}*Vq5iFVs}mfbJ6d3ja~^L0(kovy6p!jRiSaOq`jWgJKs*Z0Zg+$I_w8+% z$P1x(?Eg%RheqV-C?2!k+9JdwK;(rHujix{0x#ilpXhP6LtI;(#}^W>_U0+mUB6ah zL|!iELA|=BaPvAhFGA!+IS=BS)@`3~ybvPt3Xr{hx3rk-)|aeF>mLyw4;Xkq`|@X4 z-*B|hN3?osa(#6eW!;tggzJY)qP`f{2Sx1>b`7PduWg=%I^5Urfp7`_? z9i1@t{V5*zp?me;0%j=q57u8!zjw*+ZeHkPT71*8tnnO}4-EYK4mZyr>WguGFu(t( z<~=>#yuccoJ{9S^OQJ7K)R$mA3~W7t{p-5?yR+Q-y!O4~k%i9p)RLUMKA2x;kGX{kroe)Wia>;<{R^uKPQYw$^=?HP4e^cQ192C{PqiO zeerbKd?Sb33+v-gCwdHV^8z>1>@%SG|vOeK3A(sr$i? z_WSK^oT#sq`!97q>WcMEY>vGR5&akFXw?_sWk*Gx5}@^uB(ittjiSBLTv|MGc|C>o z&f{u`&!b2Zd4Wu8Jc8rtTPBOgZ^`lUID5rcMZDW2Jd?=F+W;`JT< zz7UV#WSalN$bW6}Pw3zX2HT0>K+C@f;$=#BVInWsrF_1&a>hhPceeNln!ZAme|;lk zl1>^sM?mynIxD0wpM-q=WzrjexOrwiOVDOJ+FEY;LjI@ zHALj+2$EOd4Y?q_`>{jQS+>!HqQ+Dvo{j7;sFz(7VkXV$L6W6 z{qgd+KFGg8E5|=!^OUy!cm}d}Wmh80adLM*ws?96fBuUjeTi|^U_CLVFY1#Qyu`{sus8Sok70hA;)Oc; z)0f40P*2}_;^2In7rEOXPe=MX|ME=P^?wnc`bzotAA!EpuZtSCzQB|6c{BTcs(IDF zjMnA-x8bIbve=tb{>yvDAFq%V0;s33zV?n}eJxI0UsLY2crgE~Ct07=i0f-6*9YTy z6Uq8ybgewjUjEBO>wir{;`(HwI&FSXg#0)9ByoK*w2r1Pg!G*u(HA4?iz9u*B>DoM z(DVg(eBt=$`rbPj-Ps~UeZ^cKB=L1)RtxjzI8k2?^53i5o8ReF$F8d;>dQFkq*VVn zi-F#nTYHI{rxJM@KOX?|mvwcY`rge;rqS|GN4)9hb-%^UGl{$i=QUuUY7Zs1xOq_` zPv!Xn3x9vi5zp7^L|%gD3motF=pr8Phd0pjIl}V=){7U{yt<{^-XKw53D*bf#gXEY z?*!gPn!X_FZ|BeXUFdIdkLNaf)xRX_Z=K#>EA+P{QJ;qD{e}r$h2ueksIQdkgL?nn z<+FCV{TKU`=D!f~Us3m6g8#xqeF~enz<3Gu>cf%i1pkFUqv^}%`B#te8h=$6%yu+$ z4Y3{|dv}LLdjmv!(~!M?J|@~5{hVg6!RrfLkN)k3&xG@hiE1=^W2pc3f3oHdhx6D@ zjK~Xcd!hfg2!e=BY%U%I$^uY3mJV-s9#)i)r?jqIlf+`&t-=9nJLk9s#d< znt|fcb;Tv(^?I9W`T`eN^LrSNZjtDV67>aDVqP_^P zSFnC?P0O3Eas-3z#EJSer0<0eqP`$eUli#(ua&4T`W4N8*<2qBi?VSCdpMfA5%n2d z9~|#T-~N8D8yEVTrZ0^24I5Dn%AljgJ-(O4tAFHi9vE6{@TbCfZV-6}(zpNqG&n8g zXkjAH)#~5YVXNED79jF6d4Gd}yxxb`?{?DI{oUWv;t^#tDyXF}f4=7lasI3k z*Y69t|A09$Jz411m#9n}f7uG6t*^zJ*A_8eYCR%+ZoSm&Zoa+ml`lp+iwDP-L%*H6 z)#fQ4^YDM;#SpJ})5tQOdVxF+|Hcb+D%W?gk9hoRj-&Z6Fv6<$&_8Bh_U%iyy&<3a z5-b7`4;a{@uWUQh=0$w+GPpjd_t(!}S>`{Dzs_EkHm~?*^UuNh?)N8bf&O9Ti%(u2 z{~XlQTbG`Elg*3yv{$*z@*mWL#ar(A!sdm1-d~YyY2825h=G27@2gy!m++}Cy;V8y z7sLx(=r5l&#QP2LG@ra2#QPob!ajL%e*FRTkK5Z6^+UeC z{#O1eC&@YXAM?s*lk?zsrr}v5p_`=gS@-#UED6qoiTJ*8<4l_u^~qCal-v8-PU#2hVlc#chaD8la&EJh}eF2aAgxK#>%_|-n=fV0_w@ZJj&o-%e zr~~}<51sP>G~&xz7u!6=<32U^`&9GN7eTyX&7ZlGy*Z^X;!~fA#4zmRdhrT44}$RU z$xoG?-;esVH^zBzpwNEWWH`TCq2{G8&hr_r7ad;j`D`0z`qWp5^aZlN$zZ%x{w00# z5?mh~uhv;Kfc0jJr;hNK&q-wO$y0|dw0R+)Jf*#rFK|5AWP9K4HZS6nSHk-TjK96! zP1|VmVm^5azuyW5%9|IL?6i3apS(O?Uru45qV%D#zLtt_;3|LdQ26safVXZ|RJD1U zPoBm=cK=

9)HV&(V_K%5{474|M!CNpk!aAs)XOd_02Vg`Y;h{vz9?{1^6VZx*t5 znZ#aWl6;=!Wv_B!`SH=c*Pjm8zc^ZmYA>(PU}Wp23t{~}Wv}7W-Z+~a^D$!n(*FP9PF4_5354K6!8~15%0@=GpVsDaYZ;;yy z^&q`lOJRPWtVGKf1J#3HTHSu5ZLgxs`x*Ovs(HmD$?b)D|5E#3R`Iu&Z9=Z+zSzI; z;we+Ce1YT3%i5eQtT&lNdy|zc9*n=6>adH#czlCC?G5q%Ta|%EpLT<=ew85Fo5kY` z!oJChzx;7V5LXpYOx|j-z?SS4Z}4 zk=Uyf?G5np9O}!~mQ$LuP0HS=PkVJ_?^zOil{;zuEf>|RF5Qp2!Qmvf6C~QJB767W zIvWmyQ}&uZ?G5n$2L5~NtE_X}`gEebQDpD&nrN>=v^U7@h5J7$HGLoIOUmA)PkU8l z@6@kFdrhLf1>9b!&mUfM$^CBs#gC)qi^lDR_3RI4jl0ISR~_lEJ_otIP@jhkuMK6( z(bT(W`b-qx=9Ra?@wuagiS`zv=gsvW+WSWaOT{q+wD_j=x8{?lGSI-Z z=a;y7F(OY#_U=IT#(dhVa(ytcRo^oTmc<+`Le!Uu?AQ(>2JIAw4 z%HF`${_0hT+Y9qQ!`hJ&0d3j#*T02>XkaM z-ITqWUwe7}!FuBAJvD~0jiZ@FdviDsG+xuJ_f`jt?dU{agvS@gkLee_0h^S)VW0L! zxIS1fNiSS^4cj=1bc>?7bi$d|yYn;~CP_8LCzjd6X@ar2w5 zSjRSw7C%7C=OWI7eEDKrhmH;y+cAi|82b#^3&+2AJ@9J}wn^C=_i1k_itl&rx=my} zM++161qPI_Z#?ndu$LV$wi6)oqG&wIy>ID143V-|@%cR846d&(1D!lL$6_IoiT$+r zYMciXjZ>PxyB48RKgNhWm=HjGLD>83yQ27yO3rx5kU*ntG}571XfqE9)W=D#4% zKR90PdK~*QCRdAJOXDe>Eq$ruEqyhd#&k5Ds4olkk9WR!1g3$GW)SrSxIU z(g9;TCQ+aIv}JF7_Sqi?-g&m07bfacxjx9}#j9U{Wkp9*yU^mHbN|77=;g_yp&L7z zM${MN`XI2Qvl{Giz}QZNs4ti6gZb&YoNQq|EI`z!aed&pHT?!PaqCME^+i$t$Y~xE z>**L;JPJ@gtBtye^JgMY=k`KA&t5Tgs@q{=K50g`Nx$P zx%DaCX!=a6vmGzQD2zrgMls9bER;6lz5QlKNacAmFUxn z`f`!Jr4oJGLo|JvTp!GLYhDyr*9Yq_e`G%1Qm~h(FTwS}!s$K1!3*3xov1IEZH*rgj~@MMz_Pa$ zW53U*LH70;F4`L=+M7i7etL;$uSv8wI>o975RWl4M12}jAFLbL^ZVqg;BGh$u1NDb zzo49N@gTl`=85*I4}0gIjG4~_fj+iOq5Kb( z{!0w`&xn*9gmsRJG%tM_?89I$h)O!ro^h3>59X6~2kcr37wA-^dGU%+d|S+Ky1PL|VC+3!yiET5cCfeg z@>@2tP0C*7J%9GX1k&!mX*<8%dluWTNb}McJPmD4wEX>y!;m$ zYQ-0hFNeII`o6Z5|4Mw;gE-d*!XqNA_3z9iQN zfqi+$-NNypmtHS>liYvoFiGk4>O0%)a^=ObU-#lEx@9l)kJaDY^~mA!!n}V#y?_6s zGp=NtRR0Jyk)Ic2zfU#LC({@RTl%2>wR@(+g~~|l{r~pA7cY#C7dFghyq^C?vVQNy z3ov1jFOYv34X12SgcVOYUuG-3Gw%tjKEu2v`RZ6A8=hC$P%iOAIDX;9 ziz1!@ydjQ{De<%9&r$T^1yMZ41sU&BCokB@o9BF|wU_>6dA>}!wY@ODB^S{0CB*f? zcvO7z=LxvK9k=8m^vQC@;Qj;N-}4!d?c)|Y+uL3lPv`oeUKL&P*%!*?nCAVnj0Nw` z<^F@?j!V@kC2m6S5dL$&7xtr^2Z4C-p=B?)-xGVw`}o)WUf54Z&nwMq_BpJVr23oc z^ZB9$NZ<1keaa#1mH9BlUJNi%)!4sDpKUr@8ODC7Km(SHr}BCVy!boO2Feu`fN_?L zm%(}9v{4r?ILIy!tx)sQXYl-kGT-RsraF5FZ-tsn8+=ej*T2+weRQ517CXw^`zMqzVDw{|`d_n(#gW~fO-F$oB%iaKAAA*_H(ig?&(*%g? zR}sEm4D;P8-9&wnL##L1TJbiHuFq+D(Mjv@@8IX?8lwNWy^t^6(#7ZNB}UPBCFuI5 zm3QiFHt1@^>vIZOpdh}`Ke}`lpVyZl`cD~Ho`0u2qwjX9Q{wx)$0PT9VLyoc*IVMh z7}0-8)+4}Ph{w*?+rVM4qZvefc|8BXe?2As(;lJ4H=X+r=6~^TLvK06u^o-5FQ2bx zgU$VFpKH2#5u*QsNZ*66jbO7kXA2PZMY;c=-cMb>XsVOO&ZiLlr}FFJPG_LYe!IDq zo0r&2%fA@%U!6Ll|3XCnWpV$(FtqNu!n@r1Vnlr~or2hc|3Y!mf6Ak@{8RaQ7%*$y z*?&3PI9i0LuZa5(>}@`xQhx`G?Wjcm>8QTEzioC`H!nogm(TMLj^F-1_W@yjLnrz# z7xj;A=J|iP^{GUC3FN;!?-Bi%yqXqYjrWh#I`M5^Z*}WSdVG(C*LZI7@dNzVe~{=u zljuL?J}aMLeQm+U_<3%9CQ)AjKVJsI_xc?xZ zvwJMv<$$rB1kryg&p%lI+ts4&1~<eG?`LK6Q4iT*3*{)6*w&3~RN)cY_|Um^0} z2#No+8MOYZasR>bQKt*`?{WK2BkC(f<45ynvirMv@sTurN#wsu16~l~8zAZ{LgUBZ z*M29&!yx)Eg!~s+uy>8y-ozeS{|I!pj%Q%}*e&s&LG)kRAd3h6cg3c!9&_u95%rlo z|6u%mKS%VR@)#|?5!8R*S+ZfUTVI5zFN6CJ3e}T02MgW2FwuW1@?YJ^^V{4!m8dVw z>kC^ZQckX&JHgGc9H;4>xxEFG|#xjr^CkPV`@Z=)VxkztgtN8ROQc6ZJ)r|E7%< z{ii-o>%R$G^k0HrJ>7P?IRDd${!4KG!SV0jFWwW5Kf*+PNnZb8 z{`X^7$^4J#zaaM?tY4KbT`trEji@ic{Rj16`UO`C>wiI_|4h_>^^+$G^Me3UpU&-t z_|D$Fseo-9E%Cc|zR2dhX4uLX@Sk?(&l8nv9XQV&V99uiJ{GS!`@Ioc-tTa)*9)>j zZ?E5fXPo%6qIpVk{K89LoSlFJ9!o=|Z`Y+CDZLyY^W2fy3U4mq-`@?#=S3H)lh_7Q zTM71&#{qr^&5IXkXX%6Z-m|s0&NeAt)F&@}c=`GLyDy&xtQ4>G3xC(k2RRSUcW<4M zeB0)Qi~aGkkiHkf*S~7>OrQ2@{CSK}ulkSJ)y(E4eezTkk7r&>UT5<(kLNbA-=~^a zd~>;?2M>ILRWF{;9?vzi|BM%}0OjAoT3?-J^CA_n*Jk6biFglRH}G_u7xT$0 z<~*nes~VrM%;qI3z?0b=Lh)!=eeKz)z+eMBewMM|t@=qvjhE*(Q~L$;STj zudr+RdVALX1#$QrxFs&5&4no{|qb{uaNWLdXR3%f7sKq)|+Gh#)}u{JaAg`zc(CIy4jyN z^j4+~K9SYUiZ9fJTkfkp%T0+5@s6*InLzrAx0f7D-6-mYO7^|%O=A-c&<6gy`sYdo ziZEl7z}QP(JeBjRviJP-%*rZC8~NwmugYwN_muMaF7Tdiy-Yk`OPuejXny*bWPYj; z=cfvr_<{dGpCQqw&GL>f`-sru%n>$k-K2Gby#|q&#`QsbFZu4nhlD?vPtzAbyvrp# zoyb!=TK2+xZOZB`FswV8K7pn$$a!%5F?acMtQtC7kjN`V$G-(n^ncAsW6zX0#PNdr zy|5o;BRIqt>hsb+UMzsuaElOm33Plkf8JRwF$;bU5qW`&ta??CeRloxw|(j6sYIUg zyk&1X0}U^}R;Z?CQa&zu)dQVPtnB`=?1eo$-1=e@X*`wdJA;8XzjwtmZeEnAPkY7s zzG#(!K0R;Q8aGcT@)Dfan1SY8-*KUv7bNl`3oLz&7--KmZH4tAg~(GEmh(y_y!cL9 zJWRyfE8&HSytEGG^Q&2>y#0dPfAKJ_zUZ%(+j~HwPb2D6UbA?xu<`P!iNoCb0z{t4 z>kHJ=y(@G58!%+@q=z_>(&<`^5RI}oC|UVeIX)GrwGI?U|~W!ll=H`Dx=&Go_Y^o#n29~>~Yll+aw3nSh<3C|?*@(}N32`@_I z8Hl$)!qbVoLe7Kns9K-3!`=Q15_xgXgM4}D`nZrU3XvD$^#%Gz^Q(4W;?}1T>q`mp z-}>MFQ|ji$f2HM%!k=#e`4^Y)3?eTb@it0$VInVxc$*|VjmXR5Jjj=R9hamo`^G*D z5P3T1L7}R4cFP8s1wSW#p~WMD>dT1q4Zpd0$y;c=T&@q+6VKf^=~*`~M${KYyyg;K zgvbl>?+XNdEhW4Vk(Y&dttC8_$kRCw`p2++-~ZwEU-D;SJka+e);&)gk4z#jpVt@2 zztS=Lg!AW#8)@^GD6+RrpM%196eM0xQ-FAFCA=unUK8=!OL#hwSB!X_B)lMzm*hOC zFTuL&bKLo&5P4~1tobR7M@v_U<57G&E&pP?zOZEzrN=dsE_3S(+(zT6Tp#q0jay%Y z^+ZQAi25=S?^6jcOyq?S?{f)HBl2<(Z?l9KAo3!d2l*0EGv+y*$957Ww0Pum9@NvJ zr`{~qdm=Bv>kGtpYsd9X-1^kowEMAR$ljk9m;8wq zk5a_@UBWYoyaeyRY?)1I-}!?d-Tn*a()7W4uD#y$Mp(T6TqTYl5x)Kc>*EujTY1o} zFEoj!FUa-5dfnXv)(Y!&(ebqLEg!89J>Kq|oo;>M+iCiAt`ClpO!)o`!grN_Yy9myLLrNqF&X^1SiNmoVa8A>kQBULNPccv-j7-tBfA>}{CHGdK_C zS8ptN9ZrKdnnvUmB6~Z&Q?I)N#&!ZkUL5f~Bl46StA9W~ca!iU zL|!`QL45D-(qW3*e<30-$azqh)9#ypi<_qsd0CtX^Q$i3-rmX0Oa4fUhmLq%B|MYJ z%SF8I5}ralev2YrF9|P7)K|cHkS~G88E_clXgZN+avt>G-SxhI)d6EWK_agh>8taB zAdg*CNsDh1@lKZT;#+9Ew6W#=?NkZRAo5hit1sb&iM&kCgZ>+T_>{`-cxXgki1Q%6 zGw+B9_rnH=yc}fj;%>*caqCO`K#NBN@!pW|Vnkj(;w_QzB1B#c@s>+?AtJAc^B}&l ztGB|&(NrQY!FfM_Hgs!30iy&&TGg(yJlZ2oS!j> zJQMN$knqApUIOv{lJGPlPcf|HbFlYs2`@n8shoEvROvKY9Jo8&xJQAD- z`Oue(R3nDdBO5uI-{&!zjLAk20KKa%6V{M@i*VArEZ?_4b5I1U0=Mf-`8Up zFSWiA^7vj@`|llR|KQpdqwf=m7~^5t$^1p%6HL_Bx0F0D@(x-&4746L{L9~j^{~JVa-ClK ziqLxEuz!jU+V+%f&!h2TTpt8>d?T%68HfLnxSqy~FyXKkR+as`qsG&}yLl#2pNaI{ zEYTOQMO$CXL;CKO=!*nt_Qp|suad+!M)Y4C#rH}{d=o@{38ZhdL|=rcuNdhYCDEs~ zrui?)^}&Th4Q7h#?IEJR1nR%z&J+8uLDZ+P6%EK|=pVBO4j1}|O4Juc`M0qBQlWn+ zZD{^WXJ5$)`rzM912XPp8%HyU{iB5Y4;KDnHDbc?hfdU&!M~3g^yNzQCCAb1O(K0u zCHhRFzEYIW`>$Os)Kj%BO`p-PJYVV!67wZWv=?q11m8hDZPG!^mk3dxit@REM4wL7 zmyhzfxkO)rs4vL%!TF=MeRl}sWtf=HY21G>DQKM|##d`ci?4?Cb&}{)i2l=Fu;L5z zzi%b;KaD#7L%f89m-w1Ce+i*{x#UVQpX1lj{1-v`ew65o5cL_H2gh66PkkoIHjbte zdFiOXjqD@#H>Ewz-fX@e0g3#GmB~d zOXvFFc<}6HrJEcuwxbhyI;!`L`u;AAM;dWF3UYk_`lm_HN8S1qqP{G|TPfigU(oyq zXP{ud0pq2bvsRoBb)eNh9qBVA`ZS`xT*O-?;UzZF?2RJchZ0_d$SdGHI6w2vR~Oyo zj;~7O1<`mksJr<6U=doAL z52iVz!LG*~OREPa?;lWOcGub~Tn`)}>NENLuRh~VZGOeQZhb0|r}6#<7a~3X(g2o? z&Zc#w*_%M~(^l6kj5}#;{c743nkAf1R*AeM;vFyHnd@o(OS`^&JuFSa(}}!76pzdI zi}8pM>z|7B)sW~@i25=S?<5J&_=M&^gO9&(Kj#-u)e`1^dM2&@g}6Q#KPK;)C(Q3P zqP`r?gZ|NN-))WD`J7lsvp2$dFkgFR@RqS|UWCZYN4y0Ro=W7!5bsq9&s>0!ETI%+nLgbZl9>jO^pe3nud6;Req1hX_!Kw!k-{*#j$6Feamw|Y* zCA`GPG<_Q484_NE$SdkzUjJ&&i_F8mgP#+Fi2auxDA>n?X(jCWIj$DmM&xxbKVCR* zc>&vVwShEVDW4xyWtgrnRNCvJDN&-n_^svs8$B^&zMB^xK+~7a{Rit;b6dy8yLswQ zG+qhPH%_9@AnMbRzWEY;5u&~X%D=_8^cMUVChE&U`jTze3jRwF^(nVm@rCi|`qe)V zaK}R<>I-vyFhA`)bAr%6v=Ul;(~-WLB>DnGeYr@VCeddQ^+kFAh52ON;dP*_I$EMX z&E5#t2ZjEWyM7b=7u-(c8C)NnuRWvgCz?YX+ldkN<#BybU(P+yR9HWa67|K9zD5## z5u&~*(ifEIOA_^&TpzI(T6 zBKptZ`XK*mHTwOa+uj&apQ2gg8|bSi(Wesi6(D`5O7v;J(EJzV^##WCHjO`Q@3uF2 zA&nQ~`e1wu|1ePK9|loh7Sgw0qR%Ai3skb=0s7A0BI;9qrP-^a`n+)PS1?U=v?x(u zA@?7QAGbHW`U3}y?dU{(xk%rEn?-#(QJ;zQt?eP|Gl}}5NZ*;Si28y=eMLy$Z?}s2 zLch`CTY&OUJx=T&3Q=Di^^XxN#r%sA^_fWDFA{z63uyMHqyEv%6!nFO_p_Js`5(-$ zcAvdb=pP1AUondB`^jvfe`I1Du;Bz7`M&zaCTJv#8l=nW|EsVbrB2PuUQ-2nDAtEmm z@j9HjN6@Ddc>%5b_~VjEqW_ZpXz>VfebC<;-Y)V?A}<@QN4zLmk5Gy05n;}Q^`Rw; zt`yFPnyYE+C3&0&`O;!qy&-JlXgZN+AbZm$-4%7fV28*nM7-(}o>4@zH;#BUB|MGD zD?z+k5?;gL*LRuQRT7^E4ta2l1|u@DlIR^hFTwN(nDQ z zni8I|l4frpT;AVKl<+hnF9Y#vOLzeyPvbo3zg?E?e$ef|#0r|d*_;RQU39{YLVROH zUKrWizJKq>-1;I!ULN9gknlo8o`HCo5}r!r6(U|22`~8{T0G*M2l2gg{&&K7X%cxQ zoCopkvR>@JQ6f*7P~JcC=S&s)uTJEpBi>UIUXaKOBHl9+oQ*6Ui=+ee09!) z_>Rf@d#1a87(`w!=fQZn_TZk&-Mlc77e)HihHnVhH)%v(0pgt{;RT316YNtD~kvDvh12c zk0`F91u%i-)cCD|Q*BQfEs2WrzEHe3|S*Bsf*L!W_&Y<<*bfzGUiuPT zA6r&bieH(vm-2mlGJ6y33>oMHdk2g^ce^sY0^-vm(t)U)sYK59aqL%*bA&^sflb+g_FP;CV6yuWCD$frrP-M7%yv zU0X*H?vRr6z3dGkd;im{|8t6P#Q=?$d5h&g$eDfX*PW>hl7HU)s+YbTt`F)#_N_N= zS8j8EQoirS)7TL-Xgh=boBQyT&2W8xMVc2c!u0`jZ^!=2mEIMhdFM-#_qXZ{)BCbn zSEg>vt^m?YpTb5+yZ>%_qNvf~@-$Sh{yu+Da|KR(SD<<6ONK3dVDEcpZ60yhJT?M> zy-@$^^&I!BB8*6Kv0nO=2^J5o7kwwI{vc(n{PXTty?9yNe{jAwZ`6_=N?-RU<@;W| z0FN)|+xX3^?GKxW?47ai;o@-H0E*mez}S?FCOFv z^bf$8&3Z05TwW06OO-bZFI7Nj1)7&W4e@TeA~-K4_Aq$)ygtMFQ1-o%`pPvGfU&oD z>5Fk5%s1+Odcl50SOJvty?8}P-xTASxyl&%=iRS*@pP1bt4BVzTAW6PW$zg|?u4I} zs}7GBVj$>mz2m(isG@pr`|S|h;m7eSH1LwQGLGt9BxT%KAAD=aK|I4Pj)<(eKF%jrL|m-`&BP}>4?P?iS_t!gy38chd=OUa-D5&&`7U zIM)Zm(42L*-Y0vH>@}G-cwdP9v-9P~TWh^3`>gCWFJ2Pq>(=w!A7r1Ez2?Qs?KEio57;nPfM#AhqLF5_Sf3RLWziHQHZu^qUX!%#jc`&ArJn_wq zZk|cx#ZkWeea72DK1YeXDEA-SkF$8^K`5(^rW1K3TpxfoJ-L3G1IBiOM4o~4oguj% zT_N(KtnfiBs<3~jN$wYN>$Ug2@;S!!!S(IkCD)_Jm(ubjpX-D9^T1zE|HuCO|F-qg zXCi(5CC>{oi2CB32mLoOrz({F3N?b}nFIks1|I5(Ik7qWmyz6r}FG$pv z;QDGX&=b=;tZ?&U^=SI?x&L7N_*$Y*A?iyaeNRjDg%7bF=C%d)V_YBfj~m0$1@8C6 z`_k$atVcrqgY$zoTr}-EH%}+7uN5JEohOL;45GdO(w7+$^{J=P;+x?5p#IhCy>6S^ z-Y`+0%Jsqc(PZv9-@ADUqP|k3Z|t?AK8>g^i1gj|p{UO|o#wy5r1J6O!DmH%0ir$) z>C4|I>eJ7l>C52yp#GiSet|B;qYtfrgt$JafAd?674EkRHK6I!xIU;aXMO+40Jpvv zQJ>EBLH+yg)oJbByg);mzHFqgsYIVbd|pNv>DwyN7boh|(D>2nmjxlWy%D1SB1qq_ z%SLr_^P*?c{1@i_gX4wb`ws}~ry-&~gX@F!_H)$waG2?6A(f^t59#|>qE992Gm*X) z5`EfPG<|W-gL=Afi1@sgWN%vkO)wCQZ*abL?{DJsT9igKeF?4))(@I|G`2U}IGRb+ zSHkr{VB5a_-T?=U?U+P;29Gb;{LyKz|K#RHiTaXUADo}Ay1B!vZeHYUn*R!szI76P zI#FLK(pOWWFWi`>FUjKz>uW|670R@u1&R6;27*|?`qk`y`wlu_Y)2=aFN5pPfd~5L zO7tm2eF4sce6GAn%;$J7T7Od!ueyY15P3ml?@JPU!$e*hipPtRc!ZnM@+Hpm8Ri?G zHrTg{Z5&M_>eINrFy9z?>T=BiV>@~VO47Z%VQA*Z4lTw@4tI@1uxG|T@NSw!%@zI@hJN6{l5zn4%vs;YhL;cv_7Oh zJx^F4N-U4>*vi@2Vs6M4Cu z2l04R65k+^7e)Sif`8S2gD?s+HmaKQiW3>31h*#wXalO+Z@`@4fv&AAWOyngI zue4O;X+&Py*oCXrW!c;`rX zQ6evacqdDEI+0h3cr||P{G~gegG65739G+B|2R{^Q;56_#5+O4i@!>Xuf};$?_=tn zFwJr_gUHK9ybmP2Fp(EVysusz+rS}??P!PK$>wb7==$t??s{Om;yxpAD$Rce*9YTy zgV@Ty-1-s=X}m(jYa`*sh`c!BjhIug*sU)@v#cGz1|yBE;no5guh4{rNJtfx^TPv^Wk zjJNgust-G@WyjNp;K}?K=Kh1@-?k%veK&OhID*Cwu^uMlMG)@*@CG9o`%yc@`jw0q zj(e5bW%a{oc%O@Co4itUKq&x-=Otz^PqB9_z6ScH zNc4q>`c$NEutZ;^1yLVg4`W#6)1NY+tU8)X)R)2a!Fu+F>hQm_gQjjNVn|={I#FMes4t52O&%lai)*z0W+HumS9(tHU%U^^e+670 z%qMSMe&4dWN%pk95RC)TSl zQD2bjgL*XzCP%Ioynq&u5YpFlp{P$I>eG>g!>QlbyzLxixKsOk-l~X zqP`eWUq06d=NoJGfBb5fxk`knFT(Y)%YKylulzdP%?tFW`7eg_T{&LV7b5D5B7Ni5 ziTc7secIge$crG}UWq=H$TP07>OJJkE0tr{tHPuQ-4G>~#)tY$yIA zEniHo4{mH6`qH|fn`aPt>0BT5-x~F^h3hxML|%~dAifV&zqGMipGM?mAzq(5b_&<) z1&F)^@?Z6dIl}rzVlFKn%8TXmzvF_7-*wv?Bl1+l`_G&KAGmoDB2VMI(->&^&h-o3 zybzJ6^LW5~WAvowh4mbj$je3fm;P$rmpF-rNJ!REDs4tOfqW|JA(Bi8i-hT#) z{xgWYOwNPj^N%`r-|voZn8*tu-c^rYCGa#NF9-3m^F|1~0Ff6#y!7X?1YW|R#Umf_ zYR~K^@M1(>gx4z=-|DA_=egq%A@X8eAB;!u#u{Jj=7os7LcZPvyu0R#>k%q(J;LZ^ zjUTXHGQHAo!g@)ZxE>MXJXpV9^yZp=ZhMpaX!9$buRp{2+Lg~XspRGb2hi4YiuigC zEUb;|8~WJIGl}|g(E9lND#eewc~PRi1kyJ_qAyC+7e@MCm*`6p^_6mca3X5LxJrMx z?bV6;a=AV@|JyzD0inNz2GZgixWlUVa6X{vX>*=(>kAU~#d$u%`HFcAsw`fmi~-y%u=g^BvIxjx9hos#@Bi2CwS z{{2Uie{rI|Fw*yzL|>SwFN*ZNC(#$Yh!)>Gr0=J=T)E7tk_Db|ci26cEU*TDzzQACb|4O(%IKKSq zyLX>=+Z!V4)44vl-nLop*Y~@5VWK|e&hqusUm6a8X_lj@M15hTuhX(IdmJ#f6DR5` zLFYqHtn;fIrzA^h{UgHl!NOY2-@g~0R~o#S7TWdzzicZv5!1clPFN62=o8{(( zE}_LYi|d2=!TMhYZFTd4M13(dzCBm?xu7pb)Ti{Y`Y-7FT%u1Q>MKP0=1TMhhS2;M zu1O5mA9Uf^lVf3W^i^MsZHFG}QP zAYPZ>AG^dI51q)j7~+F+Q6XU*koqf53X( z50dpdgUHK6@py2NxLy|~@(jdlR88z38j)9sc&8r}`$vGtiz8muU1I(vo}mxXvQ&1hKU_FwW@ zT0C^lgX5W-{yKP-n`aVvxts^rv*xLHmAH9PA}@;U?c3)4EpDDppFbB^>(-a)VFB! zgCy4nMZ9-sz1!5y3lMn;lz**18PdefOFT`B zZzk6V{deJ>3&rOb6L}@*dc8j-*Q-Q`yb#w1`CKI~USAR-@^Uy2>iwsZ>p@f^FM@b? zTp>RHKKT?a9{GqjL&7tOycqJIeqjH4cfLf4ydutnd}%V}OV~J?PUIyJ@6CHfUXaKu zMZCEW9uV{?L|))Is~!NTjf5A^r^Pn|@g`P2se!|JY{ww-G|q$icjMHzh3_v56M5N4 z-;;yR6ZC0BUKsI)O0K5~5P5mX-aUK8>+2G;Xz?%~v*!13{m}L2l|1K;M~uibkiBQf z>K~C;i0rL&$`3+5hlsp5;?eeMn%sY& zue(H_LDUyS`UXn$#fbW1DE~T1;u|LF%U~lej31DH9VPJ%Tu<{~F|RMc?Dxp5Gug(` zG@`yt?msx6JaxdCTOBaA6DI0Qa(yuVj>~+7%?6zzfTr7 zYw6Y(A?nLU`FFyEMZ4U*BvD_irxjn&_nAarh^S9T`szsZg~rq3o5}qL^Q(UC&r7=P zRf+oIJYQgb@WF;#=ev0^qP`H)SEqxhFS(1>KN3h^bfc&*a3jrsIb0u{PkDLuFya0; zlc+Dr^}&%_`*+iax&0R=>I<+7*C6*&^*(3yK{wB6NAsW7u{@tQMAK)ioyO0Ksh@-)P2DZAd5$jjzDs4w@(uD2!f!iZO2a=mT*QCd9m z5U-BpdRv3YGf;o~RMOwVL|#xW&zH%P>uoh6FAMQbmRxU}c!cIZ9q~?(TyGmA@^TSx zwg}FXh59_{p=|Kfa!Tg}9{4?-VGQ-<{&UadSX>F}~3N~MH{6Kc};A~n`8qb(eZtqn) z&Y0??dGE<`1>POwJSYPn)@t&gH^KQEFJ6-KU_JKIK$lg{PkHZo@syh^dtp6$^M{pA z_a-=h zfny#x=7D1#IOc)>wg)r@9M!APFuIVwO_Y&+gs2MO=JIL`faYgwK+D|-rBF*Tzd;_Xd3$` zw>HP-+FSc|n`>`@4NYVJWPDqk_{(--7tR3^fF%KN`z%dUT^T06=9P_|24;=Hr zF%SIz;Q@`A0oQ`Crow-4JOIQcGuVZHN5jv- zBm8%5KbIb1KihegeuV3!ZLfNS|E`@^#u1LM?dQxRY_I)yV@KFtJHGl6w%3kt{0Q4? z`?>fC|J}0j=m`7Sj&G6~eyI9v&o|6b*87gs)*kndZI5~2mDl!hy5^l-MS1#PuEswSx*{FZ9lC7W z6ZMX+ze=ug#u3(E;Gg>X(b07_IED#G(=30LvPW;*^A?yxg}E+UcV@KwK9l>|=j{9n z@z()&sFv}F^?CPu!miidx}sakb-^6VJVLr`du_e8E~UK{$BZA#b-`RW5VQ7ef0aIL z*;|MG?jz){fXiN+@7{X(%jVkeck8lWhung>zy4p=mF=P59mldd(OvA1?2te)`1MG( zUcA-Vj-6ll_5a4twyvD6qAn<3`T{GCvcILV7ys9~V!S`%zYq5o#($IFrw8xT*uVd^ zF1t>^-?JOs6BpibbaiF-5aS5nwQC+_U7=p0uGFp0b&qa-l}dEMy?%k6M>mc#U2v?d zA7x!iPce@0?7-Mj)>R?7pJi2iVbQAprH+_bVvaUjjE*P7QqpT}_lISmZRz>nC z>oU8Dy5PK{_WRMzFPXm%bsm#RJ|g3zEbrN=i$gYz{q}!7ZtIfy7h4)VWYgGh|JS-? z`329MJXF)zFaOuNWOd@-Zqh#zx@7aOGY;h}_PZmYOE&)!zEsPl^GN8D%_kZ%9f_k{ zzp^r&>j2=IGugk;Q9d3@N_43p?kMZZ?*$U{T4zyLBc{u|(Yh}OT<2~Y zd*Odwze*&!V2vOUKDxRxyNLd3!gR%svaWSE#gDSCa4*qc z@TfHPkE1&drS}$fwPL!$M_E^(uc#}?beTt4SD{2#Yo;sk=h2O$-cR&b8>UM?%DR$g zi@Mq}T?u}lG5b+y8hhn`JZl7{grW@rNch25E(1#Y7ZXz>nP{fG*MRv zCM$G=btT3){Uw{jdC48vFM@ z)CGS+NjuM}Yi{K#O8(LHS4vlQ(5b6el`6_pOqX$l{bl>deSX`hY~{bvwuLo+nWj=`>&~WS&35G&l$(67gtf9 zW4e+@IF5E)Y=7luSh{kmT7FARsiMqgy3CvZuf6ktbEPWZ|J-{ip$BQ9haQR$dg!6Y zf(C2>TNIUmA^|}osDx?|l_-{gE%wl3LG!c5zV=`ZA{vkqQ6MNt5S0H+X5RI_&*sc| zb{#H%KJN0ly!%YDXTEt(nKNh3Iq~ner5%yawL}o;eP>twNg9t1^JDR~MF$ogSae{~fkg)v9e8pan9SvJPrahn!JEz_pI&%Y)cSbS zd61`m{5q5S_$Mn0kJDXk!tnxk)WMtI?9IKN{1pA;-dy{o?t#gmMDUUqnx9)~@~;{k z8y$DoxO<%8)w$g`q+Fr5c^dMEmI?a7MBW8z*>$C2mB@O^m=OVIoT3t9ruqc&oXfS0O+^_&vo1{2=(sWM!Wgv%cu2uz4JL!zSYmf>8)*w zIqNL3apL+A)ZS^Q{UickI^t9CCKG2Xcz+lC^wv6g-{kA9B@KHvgzH66Ph<3s^@H=( z;k+hJdG3ho?Y*^6NjC$$XM$mzxPAn+$29Gy6s+%0!a9Ewr##2Rb?)9;sI2oe$6M1G z#)<1mP)}p@j?Dyo%`5&h_Te2jab|<^f$Q15wNX{apHmRViR(*Hd*`0^)7{OlKc%bu zew)0oY{yu z|3Pxrx7U86M$S6P$>#gRBxhy^&50U0V{hQ{-AQoyJ|;N_z=;|;3nb@wV~%r;W!@R= z{g7Hp`-vJk+h1OLc1#;z^UvrX#dWx*cK)BPpUa$QPtpu)=hHiCPSn#_!j4J1gz1>t zrANtp?*k`lWa^Rm&eo&HNY3g`+E3KTnLLxLM{N207s;90S#zRB&IZZJ*7tvtoIT(~ zjhsW0lP#Z*lbn@Zw4bPvvv?Ml@7*1^c4-OOE+wC?IZ-2L>Wv&HTRxYPoHM|Q8aXQ@ zCtKf_k(}jSwV$Ywb3}5o{iT&i&ctq-6E$*X-^ArR%egYi*#%D2$k`z|%a7^#!lvud zDkNtqt^GueoUux@ey&P##&_48sFAZuaYUFHKIAwkV?kiW@-M`wE9vX4pPJ(o_VUkLSn9tnT3(-TbjRH$=qP*K$hb{@pXr=3UemnPe;s|8 z@3@UOj_HjjOS(d3^3&V%W_ds5{TPM6QSmuNtP%_V#g}K0D6PH*n%QSk%tnqv15=d(t&z`Ft0DFyg*9s2dS+n(}=s7ijr>M?TTG z4-V?|gVFeD%J;2ZkgBumY`zN@MqFo%+8IQ{Y4UR$7l`o__wPYH^91|p?RlPGt{$O} zqH#YT)WwJ9=cimZv3)c7x!uH1`*SXAS5eF7VWV(j`)1`7s0-tTabmk<^3&V9$Z-y`<~!~ag?h9=PHdNw!F-oy(7&GGx&QOlIy=t6)_li( zqfpl#S(u;L?=sb+^n}x%@3@Z?>f}G?$0_%5*iSIs$6Yz$wBN^dVZSTXlVq0r-}vhA z@g=E8*grItPj9a%rhMZ1c+`zmrr)nDhpv7VPV66=%I6-FzdpoTK5?He)SY?eyKrK@ zoBZ_ll4AVCeY;TSADv(M6i)0Pn*8+kmSXBV?&F1eI8RP*Z~m%xYWOkLqrKht#hi_; zXGUG=pZ-2q_e5DpPV~JbE39!;p>v`*grJo`==%e*zCrG;g+3q(R&(VIOMoybH)prx;Arnq}zGt7SIZ@lV@O4u?GI3@n zoOVBlz=;|;Y}!vgoTzPF__`_IP3`=VZUS*<8*4jXJ5KwF8aZs*lv-%XrHPdM#<_JI>Ma@h2Qb4oojapoqRc0a4n*M6e5apCK7-NbQP({=Oe zNdorkX6gl+6E$-5nd>J0k*iJZ{4?CwlFqi)>t+u)QBOH#=pj=*GI2h0!kMyiR$i$6 zL>&q>vmI8lc}O?h#?_2}A38uofr zE@(edBTDMJ@ct*uS@@>EUf^j`_4hs00ZHxt{>!X;}>#u7Ip{mgc>f29+&MyTxd;rVW=?TEx$Q(@yFZQw$U z95y}SoYJo|aUM6}+{wyWc$xMOwT%m3mwdOiOSyOW`La2i@2}IG&dWgqNP=mX=Hch_ zNk3b_g&HueQv785$=6R(wAc51QTvA)!Scj)6aU83rt%)Tl- z-)Ghjzi#5zAv3oH&vEzg`vtvV-bFo_kA3{ah$XZArS{vWpMMBksAta;7+btO{Q0pr zU*G$g*u$INt{Iy}Pa7-`-2m5C|bDY8ztY_cIoqz6WH6ObV+lgM$VDt`YxP~W&e=u z$ZwZ6Cd+5MtU3F@jhr3J^@z>)PS7sB)IGtpd@tUwxiFvc`@-7)3U7z-bIi9My=;;I zUytN`QPm^7-!#>ummB;Pp4o`&w@}Z%k^4pRon0qYbd#Ny?|3#`7lj(%Z_`qbZ2dY( z=ZlkH?Dahf_eZEDJ&CsaBjL2w_d!tKHzDi$5XP5gfLr(^)-Cm2IBor<%J%+sb1Raw z`gL9Z%cp8Bd=gvacnF*CUz#Lr&v)$4qZU4iw*I{MY0LNO1AaTdDd}hZ|FnNyxDOFN zi6hHA7U9JCir8N&?&RnDb|h!-eVVg$n%2T6F?WA>e@QrPeoA_s$uIVN$Ll6)Nl&8f zx+$F4&ZD1_-dBLL`itp4b>RArTGEpkyCHl$SvYatFLD-AemdK*`Th;fUp!rF;gdKf z>pQN$K+e)GKIaZ3=S){~#m>-L_#~Fe^2zo;zcxwOUOwBvgFV^b^;!AZOv}K4*&LEPo5Q&IB!hL2QtmY<>U6Bwc&Hw}1;Z zU^;0_J(7MMa+>;|uW(Pm^y{3Uzu61E2Us-nv06CU{^u)6PU&w}UhC(#XqF4#C+%l- zYds!<Gxi;x%7WP*`jeIqWpYt78 zd^PDO?gN7wIYp;}am5nsS0jG1<#Qd<&-&TAzM~c{iG7Qo!pZIn7biJ0=V(sU!Y8qE zPI$ZI@7f{n{!cWupC`F*S$^N_^jkHLq%Z(Z9JegoIemO7eVN~HDh5%~6F=E~3)dz6 zti46^qn7hatlS#juakBjKfmevUUCy=+IjRDweYb~{KS1qP5HhJ>1Q9x18U^!-4X7m zj4NV)z8$m+GtfSqJUPJ<>pZ~f+jPF8MowG1CHq++r)eGEdaj?#oa5Y`$ivs6q|Vix zsFBmA#ZTPF-n2j1DU$^4`-Am>6E$+#{FL&EpVw4A*C)$orKnFQ^-3FweGr)-&IXk4E_`Lw8`u@7WPusel^7-0N z)X2&DiS^x7J~t%&OkAKjQ6p#UkKyH0>JiI%>f{9W`=c&!qDD@eo-gM{q@Se=wV$Yw zt6=d{+E4a*@#`li;Gc7)g8O%T&Xs`Yakl5h;wRp3n#yN_^s{r3_7gSwIlM8v|2bbj zPn)No@qico%>7&UKUqK7{?fLjpD~y>f*Soy-WgusrT>ZL)71YgyC-1!pE$n-HFDbY ze9Py?q@RVFE}y88t7ob2>rZwDz`ru<(}S11`)Tj`o_~ktnf=R4^l_}G^W9f-zJ6{( z`q=_b)U%%__@zAH%BKVAn#$)HZn{kQM4wS3r%j8W?EcA{l75b%JfKFd_-)~SuJ6b< z@Zeug*KY_8OZgnVQ

eE7|W=@+qqF$&Q0sHcI(q$H6uy{cOBTmj~2y_-+p`pTW0|&-pWxpJ%!6Tz((O`em9&5|VvX zMdLif`R=DGezMOIwjli+2K&7VCu%t^G4ZExKc#%)=QsKJMmJ%me4@{&g^!KmC+3T( z|G6dUXQr;p18U?eS^S)ge@M~apEUC?;=V1 zS$mK66SZ(j>{$F<-CJ2Ok9n#U@U!xM%_HZP`Kh9D{-PXbqxgyY7MjZER-~W(U>>b- zpqAqjW0vtx;biaMwJCF4XweYb~IB~qr#CbN!nf!n* zpQu?rd7p6Nd_@!IIV9%{aH5v;vr)>YZJw2+_w&gw_IgzQp!O5Bq$jaB3a>}vCtlY~ ze!j&`m?@u$hUP>qd~6g>yl$E}-%4_JffF^$C+`!^7OY1walVb@EM1}fL@noMqj2K< zA`|DiBqx4P3Tl>5-Y4}4?^{jR_v+*i?e(Yw-{*o_&M(pS{T;&TBy~QSIL{+FiyzYI zp%y-gG$+h2GI5?ya>hQaIZ+FrM3xhukDE9zAUWH>iCXw1vYc$c?n08Y@Dc4NYT=W} za@yv9N_usY)A^|8oTDYdAhMj;4>9HYMI>hnI8g(p!*b$v)5Li($(jF{_7n9&IobR7 z8p$~ZPSgwKw5^wsbT1(}n@#N}YDrHboA0<^x+&k^L2~9kt~pT)pG20^wjM#!yOiV{ z0VirnPa?}{n?EngP~at?qKweU&o zZW%sLV78wO_eUnq%Sq1KXSAQFg->G4@;wg1$@c47Bxm}wniI9~No-s8ffP=5{PTSz zXCF9G3!lU^=_lI{c|XZnZD~JI3!lUS$;tLZK0tD&uF{;Sg->FYM; zB=(bBeP{b24U)5Rwe}OW@JVcuezN_LD@e}dHJTH(@JZ~Eob3FiKaiX=z=>M;BqshA zKCUS3659{?5Xo7-R{M!s_#`H;;mRj|FO}(f^kI@Sah>KwEqoGlBq#el4j&;oyTFNB z_+}%y{+<2afsc}$rR%kysAu_tUs5C|d)@pP$r-;vbD~DhGMVq}b+buwc7PK#ayCd# z_PY6TlC#*>exgRsF3HK(_fL?VvCnBv)W|s`IdOd6)GmFR z^V(0;$XO&g+5Y@zNlxbrnsbf@&|1WtSCO18;6x3WPK9hgSwF8KIrCrCexgQBhuj~G zeSY*!l5-54sF8DUGuK~Y{k)FkY~HB-M2(!yi1Ymhk~8-u&50U0D`dX2etwSR904b4 zmDUJ zYhTrVqDIcr!`$_Vy+8UE$(e?IUr{4xmGqOnKl(PwiTl%{Mo!!Qw36@a{n2+wPTUU= zHFC210kY$Y-z7Oyu#XvP(MVr&cYA0pQw?uA2H`INls@*bI#EKS|G3Qte?Lk zIa|Pq8ZaFv;`-hvIrBf%exgRs)DNR=mwruhj)4>P9L|XS{0+(3{E_w(HFD-7=DeBY z%>7t%qDIap$;pm?Zbz;+904b4E&I@A4KL;ddt*8A&jhrQt6Zcm%mCxHq&h$;16E$+yNlwiuS^kao6E$-7$m=HV4{vJcha_j>x0(|*a#l${+3Wi~Bxe^m zQ6p!Mz z>k;ecUrA29Z!7-J;wM?(SiOb{cj{^8#qxTXXc@3?~DIVau$BC z{X~tNHIkF{^Ffl+xm9z{(EwV$h4Yi;e2C<10Vis}bo!*9Y`^XwBxn8)+E3KTnfeFk zCwo2GgS;N)9@3m+;6~2EpE*vpU3!@GGdIwj%|B|5oO#kumUFy7PUJ?;O2nLxkerR% zw0|S;7db}}bN+LIoXCxw4YFNg^ZhZBGkd%C6E$*n$a!mQKlxuI=MXqiBj(Z^pTzcRYk5268h>Q`ljU5Mkz=;|;yX152^p5)Tn>cqMIm>_1>7ho> z%w1ePV)vgok-5oz1mOI$T=c8+5Y_6 zWPOj{r#Vq0XL?PpzO(J;&ZM6m;6#m_iD7uYui^cH>rwS&{rOGLH+OM4ndh7Bkxs98 zzt+fU({epx?~m3Y^F0QfsFAB`$#?M+$H7c~K7E0HqQA&#)8Z#vK6fR{CqCaOJP@Am zbxZl2FK3$MZ2b+mP=kSkh&gv(Am_LJq@ zpX3|^Cu-zO{gv~R9cNgNY?qo3YClmUXCub>$=3HhNk4Hs88vcdf6n>IjxQZZa*kl! z8}%H{9i#EH9E^wTMRFoX;~%;l;OkMfOWlBT?*(#Z9}ee?s-2Jj#VhLHL_jGJfgW!BWH!YFScyw-_z=>M;B*xd~{AA1L1|(sXH)eB^Gq$qkL@j(0)9Z5i&h8tt1Y58R`k7ge z%XeG9Zn(Ff&NE3rouf482)L26N0v{vzHdwV*;qq!qDIbIM1EGb@%=oE^b^-fWY^T( z$jPpoVC(yKq@P3JLXDh#(ofs{W^RAq&u5c<;(Yn~TH$`O^XJ*}xjpG;W^K)d8vV?# z&((L^^{BqBpU&Z=pSUh+0NltK)jFy29X{uCNY4HzwV$;_!E+pe3*f}hTFNk6fC zrk1PkPP$OqOB0o#l_-)~6pUL$#7i#o# z5Rspqz|Z4IKe2qy05@{7<&&-NyO4gCH_(2fM$Ytx(bV_aRem~o(obA(l-N*nBPY8~ zimmTYC;jXK7i#3JM&xH{y?#2+C;jZaPIJaK(Hc3M zui`k_`kp5JYy%f+r0pZU$TpQt50iJ1gfk8GUdYyEUyNcvg0LUWFRTlgd< z-^X#X^HldF{cLWbIZ+Fr#9Bmt_5wd&us}a^TWW6MlNhz1dy#&QfD5(oN$it;vfszI zH_6#ZYX49RpTzveT=}%M^QFW5baG_A<31eOtu(jrNo4osV817HAJWeuaG@4HiA~Z^ zTf0<$!1wb-q@V3G^n9E8*5Q5*?&aoDv)^aBFX?Ay8_k7Ue3Uqf$j{0RzMlosPi*H0 zz%6_d*>;JY$C3d*+ec{MNhlK8e{)xcYAEC%5+U(|HEzCw|XWdOOW6d=lC3 zy<*$XgUNZnec(bZd=dxbJb$)bI)vn`Zm<1AEqoGtJ8}8W*7q#Qnc6{fq82`h-JLnk z_))sO!{_gk-k~IC4>(avdJ@~agmcQiuj8Zj=Qpk6%ekD)y2zOwb$XSQ*22d|nWxI$ zZ|(r?lIc82;6#moH?*uj5a6?5Rs1(6z2MolzWeW?d;A?g zt802k{o^aUv2ya=2RwT2f1>yPecXSUAFVeTFO%pUU)kTp#r^F+Ki=_-d)$lOPs2^r z+n>SHlE>b0{K>ip=EK>#^pOdtL@#}hvviZsDbYL5aOOAsFF0MlrupglEPN7$GjZ(( z6JI2n{PB)w+eqI40=GV0YPWe03a$I71 zxA5!xeEmFfo_-1k`dMBYp3m}k62(tje_r0dKk28lyDpz|v?LhBs>M&?WY?V?KytQ# z6E$EuJ(83C-hl&2&io$QPt?enOox|G@snMLauCTm22Rw-StdEz@_8`H+1yk6i5fY( zBq#g51BZ~DxxF+eYUGRuRGa>1S;}?I&vF%-KgEc2=;gdLy znDaR#=L~S77CwnNGT+(u^SLBv`4H_VYT=XEAUWCZKRTA=Ok_1DYT=U@Ka#6Qte*!> z#u@DE4ZFaJTKFW^$>&^beLs%$vvjET6SeS3ERue*<4eyYIdT8~_+gq`_#`%i^^Br1 z%Jqo#vqW-sfD1KpI45)EllAlYBxmI$?O*Y5t&uZz6vxT7^DiVhWAI!aHFDOE4(F8T zT=*Q{^qlKOE+_Nc5a$n|MoycS@@c#8kaP;9pSTVhwWKGJT?fsU&*Mo>Tn{@(3t$l0 z^{{L^|6-D}1?zTE1Ey1XR(Sc8d}sZ93CWp<=j5o7GZU<9!{efHe7-U8pZl4f%N*@L zmsu*$WlYc2@%c0A3_OR4Eejv77eCo{>7}Hf&75v8QHxI!tH*Hp&X&)Yk({|_Xin6^ zCoy$kw46nfa|E2Ig->EL&vCN#=oKVqGa;AlBd zBsuHP)|^A&7Cwp9h&f-iKu+WqK8Y=olkI=LhUCl~qy0oJd=hKqdTo~TB$9IgoT!CQ z;_xJ{e6r)oCzG7D=V(7s3!lU$*`H_kDLsYcOg~q1q82`h*;6<_Sq*WYaH1AIiM3~P zob0^H(@4(BaoSJR!Y8rwagLK+A6F(hlh4zfsD)2rlf3U>_t`t0GBlJE27Je%Y!oS^+gEqoGZ$Z-bN&vQsl=f#?HjuyZm&X9hx;~{S&Ia|Pq8Ze#S zaa{RiInO0I^DohUqDIcdnH(oOKcq@>j)4<3a(15=E$4Y8XY-}nPt?enjo8ogNzUBM zG$(50Y(GC*KQACTN5F|1IZF}yc_GQ!c)9iyHF8#7!1>9}|GbFg%oa5#YUHewezNmF zFD5yMz=;|;OE2X7WXJ2?PIA^?q5VXSoE?&r9k;2GoS9c@PSnU*coF9(JFoH*l5+r@ zsF8C_aDRI4^I0Tk`c;|}wVYpKm7EX8*7tXkoPFR# zEqoGd$8+VA_48dMXZ6+EPt?LU8&3%5l=o%bU*@cbU4iQj%a-+D%i{!XBd*5*d$yq*GmrvBfC$aK!u6(kbSCX8GQ#2=P;ggss zM$7pjlCuk(sD)2rhva0(8D36umR_sQ4n0^J9?`;3` z(O9(|7F90Mn6*kFhvaOWsr^KaoUtCgWjhq>Bo&f9T*GSIHn=~hCJf<4_AYU$a2Y?h4}U1pB(bnB*+}M*CN) zYK{3m{%kbmvmN+(63L1A9zQRfGpc-dg7L``$%*5L9Sdhvy zqgrPg`;yOjD#?j{jxC(5pSFH-@g|@1^(1HUgWA95+qK4eWYhBe-PT{~2Kjy>$%*-% ztA%s2`EK*G7WjD@$%%fBES#*LHqK7p&-XIPnYc>(*SJJ$z7mG@{rQ6p!u&T+E!{nsRC^1Yf9HF8!T<2c#+{#KH61~^e8 z=ZIX#$8!FLg1u-%%r1FXDRi2a>Z5oT!m=Omf=BLnPfllAQRQ3$>&t zk$uj^&i{M|$?06F^L>sMz#x{%b!Y6n-*=OoE#O2Am`=sAPHMjO=r)ow{~_%sYUFH? z?Gn2#@-mWh44kNuGx6eRuba1%oXrnwKT#uRX?5mA7wKo_<2v6_BUdKke19*=IRH-7$XT`I zyZFgokM1TpYoE}5qDIbQ#C~2*a;872IZ-3$nDmqFfBu=|>;orihif7pd>;zQiMvv)s~tq6Q47 z+~V3LcHHKJBqu(9M~$59^LMuWe1POEU9J7>!n^_G?2>-6oPS#&Cvqd_kmO|Zy+Lxu zuhD*@Mox#^pMmxB?<8jjI8h^K|0=E?v78T*oW*OkpQw?ua&@$v50RX)>og~7x(PSF#NKcI zi{xwpCu+cSS|lgCfAYUc&U{<@i5fYpWWKZeCqGVdj)4<3awa$B@}1q6*dgZuHb1BR zM2(y|l9O$hmXMse&udQ9$k}4^eH;C~Q^R+!>BPOnE(>Ci@G_Ef1e~amv$8pt@2sCI zk(`Y$Xg^USXK9OQIaek*vtQJlsF5>y9oNpYey&P#4uKOja^^@*TYb+w&(D|DNzT+& zy1dtK)czu8_3Cx}`hYJ4TJGa)?Pn+NbH+%{YD;rwz7)<`AUSRQkn{_E&NWER<`$Z3 zVBxGKxbkVcZWfO9Iaeb&`=8Z**1oK{F?-XbpSFDOzr*KTi{y+i(_HC}*2tNNN8{({ zQlE2elC!i_bM-BpGwX1iw)>-*ult;Fk~8-uo$uBE)7pCCDBfD<)x9e1a^il9 ziEn7`Ih?^dRy;0R@}1@UEXj%c|8*^#{??&ChPa7MPT`|o|uvq(4+|N8x@B@8>ve`99pq=e(HY#OK4AABS_Y&x>vM#WN+Jvqo|jKCk^8SU8Kn!~cN$(btGxc-LiCWTQqqLvw{d<$->;Wfgn~`S|8O=l&!oe&5lI zg_HgMBir+%>~sBm--+ZLuBrVi|3Yib_x^fZzT5gC<*od54k0-^H|y(W;+Nr^-3PgT zi0!#yC-8G;lC!af=IUBFYZ3Wb+}iguOL7*D)SRVXX^r__*pJJ1+x1=29g^)Qu9JxW zI-Ii~@j8_INX`y$p_b1*8`tyujk6klk?Rrb=lvun?)!=wFdTN@SKD}qr27w&Gxl4Z z&!{CmiT#Z@KiTz$kCL2i;6yEa64T^7K-SNtY<=%*KMSCRPhxE|&QF$e6_V4rS#!?O z0vN<(lH;^p-`idPy16FFiQ`}`FY10s^OkTw^W^*xTlpN+{qlJ^$%)?^miv7; zC;L5Ow(^;|!}oIok~5yrTq6r-Z$qvhV(Whn&-FRqM{?r#n>B9L+)#}o`@XZ$sXpf= zBqx5qZuSr1ob31Q+Wd@Hea`ojoapD!!pVMroUI#@ESzk<+uHfzg+Av8NlsiBRl6%=hY_!u@3P-NxAtIIkc% zaeZOxj&M$Py`gPhP(R4`caxkrAFOBLWaop~IGr>6e7|ggoRvGn{bV_9`Q8um{YsJ( z^F4W2I47I$HqM!geLp`$a^m+~%~&|u@4d2(*QM|FIX5CXGiz)A%6Dsx*Z2JTT>sN{ zeJ`KwbJj^t{J!GEFr1V9{$g9ckAi&vFv*Ge-nDSD`EKJ(*L*)eLUQ8wf|mXq?kD>_ zp*GHH!1>Vya>nn8hSOF)D{t}rd=JTq<+EeqWXq?Gvl(!{cY&P6zl8hAa@z8}af$Ee z$4E}xk0JKgaL%aqkr)P?%>{C{BjU8R^X={Y@sK3Rnf{s{w<+8k?q~Hr?)lN+K%Fkm zugmZ3b8b&^Cc8R4=e}^x^zS%M+jGO#?SA=OkL2ubsJU7e&MG->W2^7UJN)bK*(4{9 z)8_Bj+<1Lw$7yZ#z25dYParw*In3C?$v&5{-M=@3d6jP?IdNWPa}@3;JFn9A9AO;n zXZ{wF6Zb*PJrK@`D=Vk_wz|k9G`Fe zO>?7PQH{?Rg69Y?Avtlsy6oS>IobW|Z1t%AQ{T@j$vJ2Kr-d`B`Jc^T{^vy`=bZVU z4~F~6&i}O4_ra}xIe#O`*|}0*H!}}~a}KWZugh3&MbFlE%e=MWAAQa@k(_hpe_A-% z`JcAyW_;jtRu;%v`$xE+QE}#i=Q3|zAZPmF6~kEx=Ka2Xft>w_IN5!k|4GhgsE)ON zsHJ{L9Bk~jd!jMM@IatV`w}m6UuX6uPCcSIQ8zc-VCp^``3wF2a!vNF33#Nwv-3l) zCiA@qoT$+rTf4N{)KBF&nY#bE@pZYl7fAt=i z?x*}cM)A|u59zo3^7C=hPu!O@`Kabb4tAeX8>e%X&-sZ3a?bphoa+Q14D%%$l;Z-F z=WAWgrOqoRrNzs4^hI>}G3_5}c^?}k-)+}-N$)z+&&0npCu&JgV(d`v`fkhjRFLnV zBsp@DM=WlR1nRXuAE7ZcrMk$|I z&T-sE(rc4`cA#BFE$K-tL{vU2LB4;Q##7i!6GiNnLf+a-Aw+j&zx`hv^3#3{O~c>U|UvuwIgg{AskH`Z)$p)X0^z)T8-wc1X_V%GyuV$XO;iTZid%P1mE(lAO6!bb6?f({|q>ezKe` zl5+%{sFAajl@=0T@%4N;uOc}ct7<<{BTe1HDgAkTE@SG?f5qio;=Iz@pU=iLCu-!h zY4H=UM_4|~fAa5-)+hZeZ=m}jL*PcPH2M6wF&oH{w;; z{a7-(KZE6SaGu|8>_T$3H_@E6HMGCT*&x@$Rt^p4Ebr=b?nrVbV1I`6n&F&Xa({;G z{^6X3rq7usIeV~=Zr{S$Pjc>l;?5^T-?oM)6 zuGaaJT05MxW!azB9jBc-REzaU%KggjFEMAGCEg!}jW6|p3-#bHFs?X^O|EgxU_7e_ z<66=#*~UYfEBp7Ydy{_VkJkBKSts1j%mLheas2?DPv~dk<9@#HL2@Rq(di}Q;ha57 zzKfr>{(OBE|MTuca*m#%{hYCIHuIdH8OwZ|;wOAR_ar&HM`%CG>xTO|j>yl#s{ZHQ zm*rfd{Y*S9oHIr4pKP1I)ZE+mb1#y!e69AgYvD{@4AhU9c^ z)tsgE!u>4Y!p*a?wM*HH{m;7_$=SU?bH>*X=S2Tdi=VdV#mz1J@_7KsiTho2ES&6q z7dFnBfb+lwauzoT_cJQa`j)<*2a%l3oUZS&4Z}IB$8hcEcw?OoUXNzWi}xVbS!dEI z2)n+wfeZC)dciO4v$*<)I#a%PUCt%Wb7u3sxrzRKa$c;LsO5cZl<{Ot$289HEtiuSpGSVwET6nj@|`W8 z-zM`tx2g6SwVYpKn=GF!=XXfX5pbdwK8dL#!prA;{roP;+1O0`iCXw1Hc3t#pET9? z?~$C@%{3=#;gdK+a$-Ad;`~0zIRsAB!Y6S=a2d=3!lUR$;p<_-;kVr;6yEa5*wC$mwpKLKTX&7AG@5(oFlBy5wQP-TKL!~ z^$623)%Tx}ex|n3`HmX-(w6?baI*FNwSm}eE*rtxzst* zn(tWNQ6r~Ki=UW|Dc^ri`kCBLe{R&sRVDMCy>9-Egn~zG=EYDtPaAww}E|GNqr`LFYSa)8CnnOFhE-IFp|@PxAd} ztDjxqL~Y_R9hZ89>6q%#@5u65N@+h)BTv!NF3p$o7Lqf*qvk}7oPClL>ygRN-;`vb`t+gWp>M$QV!iS^x-?|&pY+rWt$ zIh!OWo9_dXv#^Wy6E$*XPmQ*G-bQjdPuHAtG=SD4=DeNcYyl@~z;t4-kJisWk(~Km zwV$Ywvk)=o9VF)%I8h^KkL0ZFtv|o1zTZ!BHh0tMp+-)}(yx*ie~=Lk4aBWLb3vL2DwqY=s3*j@XH8aeZ1zO(locaxmiJv1k3Qc@230Bzq*`Donx%`n|R$ojhr?u?L3?B_mY05_tE)|8oAmL=lgvmXCF9GBWK^j z>8*G2elXun_wTz*-o4N4I_Qa<^1tf7+E3K!+hD%plr)wDx*13PdR1iA=9{x$Ym*;6xn?HRVN zqMm{hdT6%3Tju?icJQxjTa)!D^$k5AEV;ktMyTF>;q%re^M0p{*O~I&dn+?fU*RIJ1~?3&MfRBGj$TR z=UMQ6T&KSh$(cA%bE1x~xxVsCe5(dNCg02XX=;~NaT8?bd&_gkR?;u0qJ^jOSIGC8 zpYMsw{Bqg}e3JK1@?FGo(Zso``<~@Fao(sTA(*b8Oi1L0@ zzPEz+b*H>P?&g>`PbX}C9X{tl-M$An1E5@RzRKM5#-^=5GI6fvrpIu~bKU$_zMrDS zpB&EfZ}@)p1HSq+PWj{IqG_KK&&Q;*?(FrwdWdc(B?;^=pzhuQe$M!uqku04`>UAR zB@^cwz?uBObWZsm!g1iIX!#tqyMVLlbCv?W^6mVLffM(MM?J!N z6r8;p@HOUgPA#7%POm?(JZGXY-A~ysd{Fma7cFKa?*>0xzMnGzUvuvDNd8ns6Q|c- zU7oXR;KcE1)YU%&XK?m*z&ZFY{q*jqmgg*8G2KsG2aGy_?NZzKv%Z_(&UZ;aP1jBD zyVaTNd;V~J-9+8Nd=LB_2;Y_5b<@PTF3C9#ICI|1B(tUIM7UQA=iw-P0u;{>|1B(tUIz`M7mLc|Kr(pYi5iD}s-!Fah#ybXc=1yuUG(Frl8;XmC;IVJ$;T&(6a9Fie1EE> zi+(&&zCTscML+Tdzd!cB8qtqR;K%=JL_az~fBk zA&UF6p8Ie8$#0J1^^fIs@6htU2XA@Ggj3y{gd5!tcbq%1-TnB^uI|5Ic#B2cA8(C= z{A?Kfazqe4KaTMJ!2R*oKFRvs$pQC&c;E8TAk7cHeEV;G>~qD-yC#q!i{$-3 e41T%fgU6PyeCfT9uADvivhCZaxU;wC{`^14N2$O7 literal 0 HcmV?d00001 From 0b727c06fcdb95679f265aa4c8aa1c9271c03273 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 29 Apr 2025 22:42:28 -0400 Subject: [PATCH 011/109] deleted --- src/CG.c | 614 ----------------------------------------------- src/IR.c | 395 ------------------------------ src/stacks.h.gch | Bin 1745332 -> 0 bytes 3 files changed, 1009 deletions(-) delete mode 100644 src/CG.c delete mode 100644 src/IR.c delete mode 100644 src/stacks.h.gch diff --git a/src/CG.c b/src/CG.c deleted file mode 100644 index c550dea..0000000 --- a/src/CG.c +++ /dev/null @@ -1,614 +0,0 @@ - -int generate(){ - offset = 0; - Instruction *i = begin; - while (i != NULL) { - switch(getOp(i)) { - case E_LABEL: - generateLabel(i); - break; - case E_ADD: - generateAdd(i); - break; - case E_SUB: - generateSub(i); - break; - case E_MUL: - generateMult(i); - break; - case E_DIV: - generateDiv(i); - break; - case E_MOD: - generateMod(i); - break; - case E_OR: - generateOr(i); - break; - case E_AND: - generateAnd(i); - break; - case E_NEG: - generateNeg(i); - break; - case E_NOT: - generateNot(i); - break; - case E_ASSIGN: - generateAssign(i); - break; - case E_GOTO: - generateGoto(i); - break; - case E_IF_X_TRUE: - generateIfTrue(i); - break; - case E_IF_X_FALSE: - generateIfFalse(i); - break; - case E_LESS_THAN: - generateLessThan(i); - break; - case E_EQUAL_TO: - generateEqualTo(i); - break; - case E_CALL: - generateCall(i); - break; - case E_PARAM: - generateParam(i); - break; - case E_RETURN: - generateReturn(i); - break; - case E_INDEX_COPY_RIGHT: - generateCopyRight(i); - break; - case E_INDEX_COPY_LEFT: - generateCopyLeft(i); - break; - case E_ADDRESS_OF: - generateAddressOf(i); - break; - default: - ; - } - i = i->next; - } - return -1; -} - -CGNode *getNextCG(CGNode *cg) { - if (cg == NULL) { - return NULL; - } - return cg->next; -} - -int getAddress(CGNode *cg) { - if (cg == NULL) { - return -1; - } - - return currentsp - cg->address; -} - -TableNode *getTNofCG(CGNode *cg) { - if (cg == NULL) { - return NULL; - } - return cg->tn; -} - -CGNode *findCG(TableNode *tn) { - CGNode *cg = cgList; - while (cg != NULL) { - if (getTNofCG(cg) == tn) { - return cg; - } - cg = getNextCG(cg); - } - return NULL; -} - -CGNode *addCG(TableNode *tn, int sp) { - CGNode *cg = calloc(1, sizeof(CGNode)); - cg->tn = tn; - offset += getPrimSize(getTypeEntry(tn)); - cg->address = offset; - cg->next = cgList; - cgList = cg; - return cg; -} - - -int generateLabel(Instruction *inst) { - fprintf(cg_flag, ".L%d:\n", getLabel(inst)); - return 0; -} -int generateAdd(Instruction *inst) { - /* - Both immediate: - One immediate: - Neither immediate: - */ - 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; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op1)); - if (op1CG == NULL) { - printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op1))); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#addition start\n", getAddress(op1CG)); - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\taddl\t%%edx, %%eax\n"); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#addition end\n", getAddress(cg)); - return 0; -} - -int generateSub(Instruction *instruction) { - /* - Both immediate: - One immediate: - Neither immediate: - */ - 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; - } - - if (cg == NULL) { - cg = addCG(getResult(instruction), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateSub failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#subtraction start\n", getAddress(op1CG)); - fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#subtraction end\n", getAddress(cg)); - return 0; -} - -int generateMult(Instruction *inst){ - /* - Both immediate: - One immediate: - Neither immediate: - */ - 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; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateMult failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateMult failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#multiplication start\n", getAddress(op1CG)); - fprintf(cg_flag, "\timull\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#multiplication end\n", getAddress(cg)); - return 0; -} - -int generateDiv(Instruction *inst) { - /* - Both immediate: - One immediate: - Neither immediate: - */ - 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; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateDiv failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateDiv failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - 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 - return 0; -} - -int generateMod(Instruction *inst) { - /* - Both immediate: - One immediate: - Neither immediate: - */ - 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; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - 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 - fprintf(cg_flag, "\tmovl\t%%edx, %d(%%rbp)\t#mod end\n", getAddress(cg)); //stores result from edx (remainder) - return 0; -} - -int generateOr(Instruction *inst) { - /* - Both immediate: - One immediate: - Neither immediate: - */ - 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; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateOr failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateOr failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - int label = label_gen(); - - 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, "\tje\t.L%dor3\n", label); - - fprintf(cg_flag, ".L%dor2:\n", label); - 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, ".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 - return 0; -} - -int generateAnd(Instruction *inst) { - /* - Both immediate: - One immediate: - Neither immediate: - */ - 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; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateAnd failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateAnd failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - int label = label_gen(); - - 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, "\tje\t.L%dor2\n", label); - - 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, ".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 - 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; - } - - 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, "\tnegl\t%%eax\n"); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#negation end\n", getAddress(cg)); - return 0; -} -int generateNot(Instruction *inst) { - TNodeOrConst *op1 = getOperand1(inst); - CGNode *cg = findCG(getResult(inst)); - - if (op1 == NULL) { - printdebug("generateNot failed, NULL operand"); - return -1; - } - - 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"); - return -1; - } - - fprintf(cg_flag, "\tmovzbl\t%d(%%rbp), %%eax\t#not start\n", getAddress(op1CG)); - fprintf(cg_flag, "\ttestl\t%%eax, %%eax\n"); - fprintf(cg_flag, "\tsetne\t%%al\n"); - fprintf(cg_flag, "\txorl\t$1, %%eax\n"); - fprintf(cg_flag, "\tmovzbl\t%%al, %%eax\n"); - fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); - fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#not end\n", getAddress(cg)); - return 0; -} - -int generateAssign(Instruction *inst) { - TNodeOrConst *op1 = getOperand1(inst); - CGNode *cg = findCG(getResult(inst)); - - - if (op1 == NULL) { - printdebug("generateAssign failed, NULL operand"); - return -1; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - - //add option for constant assignment (should be easy) - if (isConst(op1) == true) { - 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) { - printf("failed here\n"); - 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%%eax, %d(%%rbp)\t#assign end\n", getAddress(cg)); - return 0; -} - -int generateGoto(Instruction *instruction){ - return -1; -} - -int generateCondGoto(Instruction *instruction) { - return -1; -} - -int generateIfTrue(Instruction *instruction){ - return -1; - // might just be a goto for where to go if something is true, or returning if something is true, or checking if true and writing goto if thats the case -} - -int generateIfFalse(Instruction *instruction){ - return -1; -} - -int generateLessThan(Instruction *inst){ - /* - Both immediate: - One immediate: - Neither immediate: - */ - 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; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateLessThan failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - 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)); - return 0; -} - -int generateEqualTo(Instruction *inst){ - /* - Both immediate: - One immediate: - Neither immediate: - */ - 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; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateLessThan failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - 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)); - return 0; -} -int generateCall(Instruction *instruction){ - return -1; - //will want to store parameters and then update the offset by adding 8? for stack pointer stuff, can then print call subroutine name, followed by movl of the result into the result's cg -} -int generateReturn(Instruction *instruction){ - return -1; - //will movl the result into the appropriate register and move the stack pointer/offset stuff back to correct value -} -int generateCopyRight(Instruction *instruction){ - return -1; -} -int generateCopyLeft(Instruction *instruction){ - return -1; -} -int generateAddressOf(Instruction *instruction){ - return -1; -} -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; -} diff --git a/src/IR.c b/src/IR.c deleted file mode 100644 index ce141f5..0000000 --- a/src/IR.c +++ /dev/null @@ -1,395 +0,0 @@ - -// TODO: this is here to bring your attention to the comment bellow. -// check if start is NULL if it is assign it to the start globle variable -// otherwise make it next of current and set cur to your instruction. -TNodeOrConst * getOperand1(Instruction * i){ - return i->operand1; -} - -TNodeOrConst * getOperand2(Instruction * i){ - return i->operand2; -} - -TableNode * getResult(Instruction * i){ - return i->result; -} - -Op getOp(Instruction * i){ - return i->opcode; -} - -int getLabel(Instruction * i){ - return i->label; -} - -int get_index(Instruction * i){ - return i->index; -} - -void set_label(Instruction * i, int label){ - i->label = label; -} - -bool isConst(TNodeOrConst * tnc) { - return tnc->d != NODE; -} - -TNodeOrConst * tn_or_const(Discriminant d, void * tnc) { - TNodeOrConst * count = calloc(1, sizeof(*count)); - count->d = d; - count->tnc_union = calloc(1, sizeof(*count->tnc_union)); - switch (d) { - case NODE: - count->tnc_union->node = tnc; - break; - case ADDRESS: - count->tnc_union->address = tnc; - break; - case STRING: - count->tnc_union->string = tnc; - break; - case INTEGER: - count->tnc_union->integer = *(int*)tnc; - break; - case CHARACTER: - count->tnc_union->character = *(char*)tnc; - break; - case BOOLEAN: - count->tnc_union->Boolean = *( uint_least8_t*)tnc; - break; - } - return count; -} - -static void emit_helper(void){ - Instruction * inst = calloc(1, sizeof(*inst)); - if(begin == NULL){ - begin = current = inst; - current->index = 1; - } else { - current->next = inst; - inst->prev = current; - inst->index = current->index+1; - current = inst; - } -} - -void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2){ - emit_helper(); - current->opcode = op; - // TODO: create temp and remove result from param list - current->result = result; - current->operand1 = arg1; - current->operand2 = arg2; - } - -void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){ - emit_helper(); - current->opcode = op; - current->result = result; - current->operand1 = arg; - } - -void emit_assignment(TableNode * target, TNodeOrConst * source){ - emit_helper(); - current->opcode = E_ASSIGN; - current->result = target; - current->operand1 = source; - } - -char * get_string(TNodeOrConst * tc){ - - char * s; - switch (tc->d) { - case NODE: - return getName(tc->tnc_union->node); - case ADDRESS: - return strdup("null"); - case STRING: - return tc->tnc_union->string; - case INTEGER: - s = calloc(10, sizeof(char)); - sprintf(s, "%d", tc->tnc_union->integer); - return s; - case CHARACTER: - s = calloc(2, sizeof(char)); - sprintf(s, "%c", tc->tnc_union->character); - return s; - case BOOLEAN: - if(tc->tnc_union->Boolean){ - return strdup("true"); - } - return strdup("false"); - } -} - -void emit_as_file(FILE * out_file, Instruction * i){ - if(i == NULL){ - return; - } - switch(i->opcode){ - case E_LABEL: - break; - // this is a terrible one to start with - // fprintf(out_file, "%04.d: %d ", i->index, i->label); - case E_ADD: - fprintf(out_file, "%4.d: %s = %s + %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_SUB: - fprintf(out_file, "%4.d: %s = %s - %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_MUL: - fprintf(out_file, "%4.d: %s = %s * %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_DIV: - fprintf(out_file, "%4.d: %s = %s / %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_MOD: - fprintf(out_file, "%4.d: %s = %s %% %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_OR: - fprintf(out_file, "%4.d: %s = %s | %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_AND: - fprintf(out_file, "%4.d: %s = %s & %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_NEG: - fprintf(out_file, "%4.d: %s = -%s\n", - i->index, getName(i->result), - get_string(i->operand1)); - break; - case E_NOT: - fprintf(out_file, "%4.d: %s = !%s\n", - i->index, getName(i->result), - get_string(i->operand1)); - break; - case E_ASSIGN: - fprintf(out_file, "%4.d: %s = %s\n", - i->index, getName(i->result), - get_string(i->operand1)); - break; - case E_GOTO: - // are we ever going to use this? - // yes we do look at bounds checking - case E_IF_X_TRUE: - fprintf(out_file, "%4.d: if %s goto %d\n", - i->index, get_string(i->operand1), - i->label); - break; - case E_IF_X_FALSE: - fprintf(out_file, "%4.d: if %s false goto %d\n", - i->index, get_string(i->operand1), - i->label); - break; - case E_LESS_THAN: - fprintf(out_file, "%4.d: if %s < %s goto %d\n", - i->index, get_string(i->operand1), - get_string(i->operand2), i->label); - break; - case E_EQUAL_TO: - fprintf(out_file, "%4.d: if %s = %s goto %d\n", - i->index, get_string(i->operand1), - get_string(i->operand2), i->label); - break; - case E_CALL: - fprintf(out_file, "%4.d: call %s %s\n", - i->index, get_string(i->operand1), - get_string(i->operand2)); - break; - - case E_PARAM: - fprintf(out_file, "%4.d: param %s \n", - i->index, get_string(i->operand1)); - break; - case E_RETURN: - - case E_INDEX_COPY_RIGHT: - case E_INDEX_COPY_LEFT: - - case E_ADDRESS_OF: - - case E_DEREF_RIGHT: - case E_DEREF_LEFT: - } - - emit_as_file(out_file, i->next); -} - -void emit_label(int label){ - emit_helper(); - current->opcode = E_LABEL; - current->label = label; -} - -void emit_jump(int label){ - emit_helper(); - current->opcode = E_GOTO; - current->label = label; -} - -void emit_conditional_jump(Op condition, int label, ...){ - // when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *). - // when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *) - emit_helper(); - va_list argptr; - va_start(argptr, label); - current->opcode = condition; - current->label = label; - TNodeOrConst * n1; - TNodeOrConst * n2; - switch (condition) { - case E_IF_X_TRUE: case E_IF_X_FALSE: - n1 = va_arg(argptr, TNodeOrConst *); - current->operand1 = n1; - break; - case E_LESS_THAN: case E_EQUAL_TO: - n1 = va_arg(argptr, TNodeOrConst *); - n2 = va_arg(argptr, TNodeOrConst *); - current->operand1 = n1; - current->operand2 = n2; - break; - } - va_end(argptr); -} - -void emit_function_start(int name){ - emit_helper(); - current->opcode = E_LABEL; // I think this is right TODO: ask - current->label = name; - // this is probabaly a func decleration -} - -void emit_parameter(TNodeOrConst * param){ - emit_helper(); - current->opcode = E_PARAM; - current->operand1 = param; -} - -void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name){ - emit_helper(); - current->opcode = E_CALL; - current->operand1 = tn_or_const(INTEGER, ¶m_count); - current->operand2 = name; - current->result = result; -} - -void emit_return(TNodeOrConst * value){ - emit_helper(); - current->opcode = E_RETURN; - current->operand1 = value; -} - -void emit_reserve(TableNode * result, TNodeOrConst * size){ - emit_parameter(size); - emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); -} - -void emit_release(TableNode * pointer){ - emit_parameter(tn_or_const(NODE, pointer)); - emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release"))); -} - -void emit_deref_right(){ - return; -} - -void emit_deref_left(){ - return; -} - -void emit_field_access(char* result, char* record, char* field){ - emit_helper(); -} - -void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index){ - emit_helper(); - current->opcode; - current->result = result; - current->operand1 = array; - current->operand2 = index; - // TODO: Still don't know what to do with the dimentions -} - -void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr){ - /* - {[string: 5] - . - . - s:= reserve s(5); - s(0) := 'H'; - s(1) := 'e'; - . - . - s._0 num of dims Known at compile time - s._1 size Known at run time - s._1 int | 1 byte - +-------+---+---+---+---+---+ - | 5 | H | e | l | l | o | - +-------+---+---+---+---+---+ - size - ^ - | - p - s._0 ok - s._1 ok - s._2 not ok - t_0 is index - t_1 = *(int *)p = s._1 - if t_0 < 0 GOTO ERROR - if t_0 < s._1 GOTO access array - GOTO ERROR - */ - //emit_conditional_jump(E_LESS_THAN, ); - //emit_conditional_jump(E_LESS_THAN, ); - //emit_jump(); - /* We need a label ERROR to jump to - */ -} - -/*// * Implement temp variable generator function that produces unique names (t1, t2, etc.) -char * temp_var_gen(){ - char * ret = calloc(9, sizeof(*ret)); - sprintf(ret, "$t%d", temp_count); - temp_count++; - return ret; -} -*/ -int label_gen(){ - label_count++; - return label_count; -} - -TableNode* getTN(TNodeOrConst * tnc){ - if(tnc->d == NODE){ - return tnc->tnc_union->node; - } - return NULL; -} -//we must fix this -int getConst(TNodeOrConst * tnc){ - if(tnc->d == INTEGER){ - return tnc->tnc_union->integer; - } - return -1; -} diff --git a/src/stacks.h.gch b/src/stacks.h.gch deleted file mode 100644 index 7600f4d256ba6efcd8071b37b3b9f9802c834fed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1745332 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

AqJt@5>`7_{C`hvcELKyF9@BzJglk;El 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%0DBh4lJJ93PtRTuZE0 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 z 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 From e092ea392671be5c943f3340e320357cd42250ab Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 29 Apr 2025 23:14:35 -0400 Subject: [PATCH 012/109] some emission --- src/grammar.h | 4 +++- src/grammar.y | 37 ++++++++++++++++++------------------- src/runner.c | 1 + 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/grammar.h b/src/grammar.h index 2b7b03c..055d1b4 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -29,4 +29,6 @@ Instruction *current; int offset; int currentsp; -CGNode *cgList; \ No newline at end of file +CGNode *cgList; + +extern Stack* stack; \ No newline at end of file diff --git a/src/grammar.y b/src/grammar.y index eb73cc0..2ee09e4 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -18,7 +18,6 @@ %{ #include "../src/grammar.h" %} - %union { int integ; char* words; @@ -166,6 +165,7 @@ definition: } | ID { + emit_function_start(table_lookup(cur,$1)); //printf("ID: %s\n", $1); //printf("Type: %s\n", getType(table_lookup(getAncestor(cur), $1))); printdebug("see function def rule 1\n"); @@ -626,7 +626,9 @@ simple_statement: } - | RETURN expression {$$ = getTypeEntry((TableNode*)$2);} + | RETURN expression { + $$ = getTypeEntry((TableNode*)$2); + emit_return(tn_or_const(NODE,(TableNode*)$2));} |simple_statement error {yyerrok; printdebug("error in simple statement");} @@ -852,7 +854,20 @@ expression: $$=$2; } - | memOp assignable + | RESERVE assignable + { + int d = getAdInfoType((TableNode*)$2); + if(d == TYPE_ARRAY ||d == TYPE_RECORD) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + $$ = node; + } else { + throw_error(ERROR_TYPE, "Invalid memOp expression with object %s of type %s.", getName((TableNode*)$2), getType((TableNode*)$2)); + $$=undefined; + } + } + | RELEASE assignable { int d = getAdInfoType((TableNode*)$2); if(d == TYPE_ARRAY ||d == TYPE_RECORD) { @@ -1064,22 +1079,6 @@ assignable: ; - -memOp: - RESERVE - { - printdebug("reserve expression"); - } - - | RELEASE - { - printdebug("release expression"); - } - - - ; - - constant: C_STRING { diff --git a/src/runner.c b/src/runner.c index 8d5feac..c134dc4 100644 --- a/src/runner.c +++ b/src/runner.c @@ -102,6 +102,7 @@ void print_tok(int tok) { int run(FILE *alpha) { int token; top = cur = init(CreateScope(NULL, 1, 1)); + Stack *s = S_Init(); // If file is not found if (alpha == NULL) { From 4cc1ece6ab4e8d17917a51848d618baaebcf3eee Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Tue, 29 Apr 2025 23:18:01 -0400 Subject: [PATCH 013/109] I added detach --- src/intermediate_code.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/intermediate_code.c b/src/intermediate_code.c index a0bfa9d..aee5862 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -64,6 +64,10 @@ char * temp = NULL; otherwise make it next of current and set cur to your instruction. */ +void emit_detach(){ + current = current->prev; + current->next = NULL; +} TNodeOrConst * getOperand1(Instruction * i){ return i->operand1; From 69b8019a8b11a9103d8689963738c3f81e443ec1 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 29 Apr 2025 23:27:46 -0400 Subject: [PATCH 014/109] added some emissions --- src/grammar.y | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 2ee09e4..e4e2162 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -657,18 +657,27 @@ ablock: argument_list: //NEED TO EMIT PARAMETERS HERE. MAYBE USE STACK STRUCTURE - expression COMMA argument_list + expression{ + 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(); + //printdebug("[ARGUMENT_LIST] argument list is %d", $$); + } + COMMA argument_list + {$$ = $4 + 1;} + + | expression + { - CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); - $$ = $3 + 1; + 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(); + $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } - | expression - { - CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), getName((TableNode*)$1), NULL); - $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); - } ; From 6d26ba25b073610539c469b432838f67bbdf982d Mon Sep 17 00:00:00 2001 From: Partho Date: Wed, 30 Apr 2025 01:25:11 -0400 Subject: [PATCH 015/109] finished type checking issues --- src/grammar.y | 47 ++++++++++++++++++++++++++++------------------ src/symbol_table.c | 1 + 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index e4e2162..89ee8f5 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -619,6 +619,10 @@ simple_statement: else { + printf("%d\n",getAdInfoType((TableNode*)$1)); + printf("%d\n",getAdInfoType((TableNode*)$3)); + //printf("%d\n",getAdInfoType((TableNode*)$1)); + //printf("%d\n",getAdInfoType((TableNode*)$3)); 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)); } @@ -831,7 +835,12 @@ expression: 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 { + } else if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==boo){ + 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; throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } @@ -866,28 +875,30 @@ expression: | RESERVE assignable { int d = getAdInfoType((TableNode*)$2); - if(d == TYPE_ARRAY ||d == TYPE_RECORD) { + //commenting out type checks for now since assignable is being resolved to something before reserve is being applied which is tricky + //if(d == TYPE_ARRAY ||d == TYPE_RECORD) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) $$ = node; - } else { - throw_error(ERROR_TYPE, "Invalid memOp expression with object %s of type %s.", getName((TableNode*)$2), getType((TableNode*)$2)); - $$=undefined; - } + // } else { + // throw_error(ERROR_TYPE, "Invalid memOp expression with object %s of type %s.", getName((TableNode*)$2), getType((TableNode*)$2)); + // $$=undefined; + // } } | RELEASE assignable { int d = getAdInfoType((TableNode*)$2); - if(d == TYPE_ARRAY ||d == TYPE_RECORD) { + //commenting out type checks for now since assignable is being resolved to something before reserve is being applied which is tricky + //if(d == TYPE_ARRAY ||d == TYPE_RECORD) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) $$ = node; - } else { - throw_error(ERROR_TYPE, "Invalid memOp expression with object %s of type %s.", getName((TableNode*)$2), getType((TableNode*)$2)); - $$=undefined; - } + // } else { + // throw_error(ERROR_TYPE, "Invalid memOp expression with object %s of type %s.", getName((TableNode*)$2), getType((TableNode*)$2)); + // $$=undefined; + // } } ; @@ -942,16 +953,16 @@ assignable: arg_given = getNextEntry(arg_given); } if(getTypeEntry(arg_given) != getTypeEntry(param_arg_type)){ - throw_error(ERROR_TYPE, "expected %s expression as first argument in function call but got %s", getType(param_arg_type), getType(arg_given)); + throw_error(ERROR_TYPE, "expected %s expression as first argument of a record in function call but got %s", getType(param_arg_type), getType(arg_given)); } param_arg_type = getNextEntry(param_arg_type); arg_given = getNextEntry(arg_given); while(arg_given != NULL && param_arg_type != NULL){ - while(arg_given != NULL && getName(arg_given)[0]=='&'){ + while(arg_given != NULL && getName(arg_given)[0]!='&'){ arg_given = getNextEntry(arg_given); } if(getTypeEntry(arg_given) != getTypeEntry(param_arg_type)){ - throw_error(ERROR_TYPE, "expected %s expression as argument in function call but got %s", getType(param_arg_type), getType(arg_given)); + throw_error(ERROR_TYPE, "expected type %s expression as argument of a record in function call but got type %s", getType(param_arg_type), getType(arg_given)); } arg_given = getNextEntry(arg_given); param_arg_type = getNextEntry(param_arg_type); @@ -959,7 +970,7 @@ assignable: } }else{ TableNode*actual_instance = getFirstEntry(cur); - while(actual_instance != NULL && getName(actual_instance)[0] =='&'){ + while(actual_instance != NULL && getName(actual_instance)[0] !='&'){ actual_instance = getNextEntry(actual_instance); } if(actual_instance == NULL){ @@ -968,14 +979,14 @@ assignable: } TableNode *actual = getTypeEntry(actual_instance); if (expected != actual) { - throw_error(ERROR_TYPE, "expected %s expression in function call but got %s", getType(expected), getName(actual)); + throw_error(ERROR_TYPE, "expected %s expression in single argument function call but got %s", getType(expected), getName(actual)); } if ($3 != 1) { throw_error(ERROR_SYNTAX, "expected 1 argument but got %d", $3); } printTableNode(getReturn(getTypeEntry((TableNode*)$1))); } char* temp = temp_var_gen(); - TableNode* typeNode2 = getReturn(getTypeEntry($1)); + TableNode* typeNode2 = getReturn(getTypeEntry((TableNode*)$1)); int t = -1; if(getAdInfoType(typeNode2) == TYPE_PRIMITIVE_TYPE){ t = TYPE_PRIMITIVE; @@ -1092,7 +1103,7 @@ constant: C_STRING { char* temp = temp_var_gen(); - TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, stri, temp, NULL); + TableNode* node = CreateEntry(cur,TYPE_ARRAY, stri, temp, NULL); emit_assignment(node, tn_or_const(STRING,$1)); printdebug("string of C_STRING in constant is %s", $1); $$ = node; diff --git a/src/symbol_table.c b/src/symbol_table.c index 26faf11..fa7b1ed 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -630,6 +630,7 @@ TableNode *getReturn(TableNode *definition) { "node has NULL additionalinfo. Invalid."); return undefined; } + printdebug("function:%s with return type %s\n",getName(definition),getName(definition->additionalinfo->FunTypeAdInfo->returntype)); return definition->additionalinfo->FunTypeAdInfo->returntype; } From f2affd8a550ed022ecc6e3b864ed61b630685e73 Mon Sep 17 00:00:00 2001 From: Partho Date: Wed, 30 Apr 2025 02:27:52 -0400 Subject: [PATCH 016/109] finished more type check stuff and some loops --- src/grammar.y | 18 ++++++++++-------- src/symbol_table.c | 5 ++++- src/symbol_table.h | 2 ++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 89ee8f5..8a287d2 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -619,8 +619,8 @@ simple_statement: else { - printf("%d\n",getAdInfoType((TableNode*)$1)); - printf("%d\n",getAdInfoType((TableNode*)$3)); + //printf("%d\n",getAdInfoType((TableNode*)$1)); + //printf("%d\n",getAdInfoType((TableNode*)$3)); //printf("%d\n",getAdInfoType((TableNode*)$1)); //printf("%d\n",getAdInfoType((TableNode*)$3)); 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)); @@ -662,7 +662,8 @@ 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); + char* name = arg_var_gen(); + TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), name, NULL); emit_parameter(tn_or_const(NODE,arg)); //S_Push(stack,current); //emit_detach(); @@ -673,8 +674,9 @@ argument_list: | expression - { - TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); + { + char* name = arg_var_gen(); + TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), name, NULL); emit_parameter(tn_or_const(NODE,arg)); //S_Push(stack,current); //emit_detach(); @@ -949,7 +951,7 @@ assignable: }else{ TableNode* param_arg_type = getFirstEntry(getRecList(expected)); TableNode* arg_given = getFirstEntry(cur); - while(arg_given != NULL && getName(arg_given)[0]!='&'){ + while(arg_given != NULL && arg_given != undefined && getName(arg_given)[0]!='&'){ arg_given = getNextEntry(arg_given); } if(getTypeEntry(arg_given) != getTypeEntry(param_arg_type)){ @@ -957,7 +959,7 @@ assignable: } param_arg_type = getNextEntry(param_arg_type); arg_given = getNextEntry(arg_given); - while(arg_given != NULL && param_arg_type != NULL){ + while(arg_given != NULL && arg_given != undefined && param_arg_type != NULL){ while(arg_given != NULL && getName(arg_given)[0]!='&'){ arg_given = getNextEntry(arg_given); } @@ -970,7 +972,7 @@ assignable: } }else{ TableNode*actual_instance = getFirstEntry(cur); - while(actual_instance != NULL && getName(actual_instance)[0] !='&'){ + while(actual_instance != NULL && actual_instance != undefined && getName(actual_instance)[0] !='&'){ actual_instance = getNextEntry(actual_instance); } if(actual_instance == NULL){ diff --git a/src/symbol_table.c b/src/symbol_table.c index fa7b1ed..ab2cd88 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -27,7 +27,7 @@ char *temp_var_gen() { } char *arg_var_gen() { char *ret = calloc(9, sizeof(*ret)); - sprintf(ret, "&t%d", temp3_count); + sprintf(ret, "&%d", temp3_count); temp3_count++; return ret; } @@ -1216,6 +1216,9 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } for (; entry != NULL; entry = getNextEntry(entry)) { + if((getName(entry)[0] == '$' || getName(entry)[0] == '&') && ir_flag == NULL){ + continue; + } if (getAdInfoType(entry) == TYPE_ARRAY_TYPE) { char *arrayType = (char *)malloc(100); sprintf(arrayType, " %d -> %s", getNumArrDim(entry), diff --git a/src/symbol_table.h b/src/symbol_table.h index c64f036..e730595 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -15,6 +15,8 @@ #define SIZE_CHAR 1 #define SIZE_BOOL 1 +extern FILE *ir_flag; + struct TableNode; typedef struct TFList TFList; typedef struct CGNode CGNode; From cd4393d0526cecc70d39267be7b76838049f4a01 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Wed, 30 Apr 2025 08:20:11 -0400 Subject: [PATCH 017/109] 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 018/109] 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 019/109] 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 020/109] 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 021/109] 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 022/109] 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 023/109] 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 024/109] 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 025/109] 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 026/109] 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 027/109] 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 028/109] 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 * ); From e598fad62aaf4d7f23a375c8dd85c250018d5081 Mon Sep 17 00:00:00 2001 From: Annie Date: Fri, 2 May 2025 16:12:35 -0400 Subject: [PATCH 029/109] idk what i did anymore --- a.out | Bin 0 -> 464 bytes integer | 0 src/codegen.c | 106 +++++++++++++++++++++----- src/codegen.h | 3 +- src/codegen.h~ | 2 + src/intermediate_code.h | 55 ++++++------- tests/sprint4/test/sp4_cg_demo.alpha | 8 ++ tests/sprint4/test/sp4_cg_demo.alpha~ | 8 ++ tests/sprint4/test/sp4_cg_demo.cg | 9 +++ 9 files changed, 146 insertions(+), 45 deletions(-) create mode 100644 a.out create mode 100644 integer create mode 100644 src/codegen.h~ create mode 100644 tests/sprint4/test/sp4_cg_demo.alpha create mode 100644 tests/sprint4/test/sp4_cg_demo.alpha~ create mode 100644 tests/sprint4/test/sp4_cg_demo.cg diff --git a/a.out b/a.out new file mode 100644 index 0000000000000000000000000000000000000000..8540d49290617f7498e8df1dc190587a92561a76 GIT binary patch literal 464 zcmb<-^>JfjWMqH=Mg}_u1P><4z%T*9WN-kp9T->{SQw7G{$U1kkGuY00#jc&fK<2Z z5B~M8Upiesbi4lPcKyJ3q0{wEx9giu*B1lX*gfr5Zs{n+dVSqHOU L2E;)E==K8uL2Dw) literal 0 HcmV?d00001 diff --git a/integer b/integer new file mode 100644 index 0000000..e69de29 diff --git a/src/codegen.c b/src/codegen.c index 250d2a4..a9d8759 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -5,6 +5,7 @@ int generate(){ offset = 0; + currentsp = 0; Instruction *i = begin; while (i != NULL) { switch(getOp(i)) { @@ -74,6 +75,9 @@ int generate(){ case E_ADDRESS_OF: generateAddressOf(i); break; + case E_FUNC_START: + generateFunctionStart(i); + break; default: ; } @@ -118,7 +122,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; @@ -127,7 +131,12 @@ CGNode *addCG(TableNode *tn, int sp) { int generateLabel(Instruction *inst) { + if (inst == NULL) { + return -1; + } + fprintf(cg_flag, ".L%d:\n", getLabel(inst)); + return 0; } int generateAdd(Instruction *inst) { @@ -151,7 +160,7 @@ int generateAdd(Instruction *inst) { CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op1))); return -1; @@ -503,20 +512,20 @@ int generateAssign(Instruction *inst) { return 0; } -int generateGoto(Instruction *instruction){ +int generateGoto(Instruction *inst){ return -1; } -int generateCondGoto(Instruction *instruction) { +int generateCondGoto(Instruction *inst) { return -1; } -int generateIfTrue(Instruction *instruction){ +int generateIfTrue(Instruction *inst){ return -1; // might just be a goto for where to go if something is true, or returning if something is true, or checking if true and writing goto if thats the case } -int generateIfFalse(Instruction *instruction){ +int generateIfFalse(Instruction *inst){ return -1; } @@ -595,24 +604,87 @@ int generateEqualTo(Instruction *inst){ fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#equal to end\n", getAddress(cg)); return 0; } -int generateCall(Instruction *instruction){ - return -1; - //will want to store parameters and then update the offset by adding 8? for stack pointer stuff, can then print call subroutine name, followed by movl of the result into the result's cg +int generateCall(Instruction *inst){ + + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + if (op1 == NULL) { + printdebug("%sgenerateFunctionStart failed, NULL operand", COLOR_RED); + return -1; + } + + if (op1 == NULL) { + printdebug("%sgenerateFunctionStart failed, NULL operand", COLOR_RED); + return -1; + } + + if (getTN(op1) == NULL) { + printdebug("generateFunctionCall failed, NULL tablenode"); + return -1; + } + + if (getTN(op2) == NULL) { + printdebug("generateFunctionCall failed, NULL tablenode"); + return -1; + } + + + fprintf(cg_flag, "\tcall %s\n", getName(getTN(op1))); + fprintf(cg_flag, "\taddq\t$%d, %%rsp\n", 8 + getConst(op1)); + + return 0; + } -int generateReturn(Instruction *instruction){ +int generateReturn(Instruction *inst){ return -1; //will movl the result into the appropriate register and move the stack pointer/offset stuff back to correct value } -int generateCopyRight(Instruction *instruction){ +int generateCopyRight(Instruction *inst){ return -1; } -int generateCopyLeft(Instruction *instruction){ +int generateCopyLeft(Instruction *inst){ return -1; } -int generateAddressOf(Instruction *instruction){ +int generateAddressOf(Instruction *inst){ return -1; } -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 +int generateParam(Instruction *inst){ + TNodeOrConst *op1 = getOperand1(inst); + + if (op1 == NULL) { + printdebug("generateParam failed, NULL operand"); + return -1; + } + + CGNode *op1CG = findCG(getTN(op1)); + if (op1CG == NULL) { + printdebug("generateParam failed, op1 is not in CGlist"); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#adding param start\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#adding param end\n", offset += 8); + return 0; +} + +int generateFunctionStart(Instruction *inst) { + + TNodeOrConst *op1 = getOperand1(inst); + + if (op1 == NULL) { + printdebug("%sgenerateFunctionStart failed, NULL operand", COLOR_RED); + return -1; + } + + if (getTN(op1) == NULL) { + printdebug("generateFunctionStart failed, NULL tablenode"); + return -1; + } + + fprintf(cg_flag, "%s:\n", getName(getTN(op1))); + fprintf(cg_flag, "\tpushq\t%%rbp\n"); + fprintf(cg_flag, "\tmovq\t%%rsp, %%rbp\n"); + + return 0; + +} diff --git a/src/codegen.h b/src/codegen.h index 3203a52..2d67a6e 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -50,6 +50,7 @@ int generateCopyRight(Instruction *instruction); int generateCopyLeft(Instruction *instruction); int generateAddressOf(Instruction *instruction); int generateParam(Instruction *instruction); +int generateFunctionStart(Instruction *instruction); extern int label_count; extern Instruction *begin; @@ -57,4 +58,4 @@ extern Instruction *current; extern int offset; extern int currentsp; -extern CGNode *cgList; \ No newline at end of file +extern CGNode *cgList; diff --git a/src/codegen.h~ b/src/codegen.h~ new file mode 100644 index 0000000..2d4c660 --- /dev/null +++ b/src/codegen.h~ @@ -0,0 +1,2 @@ +/* Code Generation File - Contains functions to generate assembly code */ + diff --git a/src/intermediate_code.h b/src/intermediate_code.h index c1efb76..bce2b17 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -13,32 +13,33 @@ #include "symbol_table.h" // these are from page 364 -typedef enum { - E_LABEL = 10000, // this is not in the book - E_ADD, // 1 from the list - E_SUB, // 1 - E_MUL, // 1 - E_DIV, // 1 - E_MOD, // 1 - E_OR, // 1 - E_AND, // 1 - E_NEG, // 2 - E_NOT, // 2 - E_ASSIGN, // 3 - E_GOTO, // 4 - E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got - E_IF_X_TRUE, // 5 - E_IF_X_FALSE, // 5 - E_LESS_THAN, // 6 rule 1 + 5 - E_EQUAL_TO, // 6 rule 1 + 5 - E_CALL, // 7 - E_PARAM, // 7 - E_RETURN, // 7 - E_INDEX_COPY_RIGHT, // 8 this is x = y[i] - E_INDEX_COPY_LEFT, // 8 x[i] = y - E_ADDRESS_OF, // 9 x = &y - E_DEREF_RIGHT, // 9 x = *y - E_DEREF_LEFT // 9 x* = y +typedef enum { // these are from page 364 + E_LABEL = 10000, // this is not in the book + E_FUNC_START, + E_ADD, // 1 from the list + E_SUB, // 1 + E_MUL, // 1 + E_DIV, // 1 + E_MOD, // 1 TODO: Please change to REM + E_OR, // 1 + E_AND, // 1 + E_NEG, // 2 + E_NOT, // 2 + E_ASSIGN, // 3 + E_GOTO, // 4 + E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got + E_IF_X_TRUE, // 5 + E_IF_X_FALSE, // 5 + E_LESS_THAN, // 6 rule 1 + 5 + E_EQUAL_TO, // 6 rule 1 + 5 + E_CALL, // 7 + E_PARAM, // 7 + E_RETURN, // 7 + E_INDEX_COPY_RIGHT, // 8 this is x = y[i] + E_INDEX_COPY_LEFT, // 8 x[i] = y + E_ADDRESS_OF, // 9 x = &y + E_DEREF_RIGHT, // 9 x = *y + E_DEREF_LEFT // 9 x* = y } Op; typedef enum { @@ -121,4 +122,4 @@ extern Instruction* current; extern int offset; extern int currentsp; -extern CGNode* cgList; \ No newline at end of file +extern CGNode* cgList; diff --git a/tests/sprint4/test/sp4_cg_demo.alpha b/tests/sprint4/test/sp4_cg_demo.alpha new file mode 100644 index 0000000..e74c5ad --- /dev/null +++ b/tests/sprint4/test/sp4_cg_demo.alpha @@ -0,0 +1,8 @@ +type main: string -> integer +function entry: main + +entry(arg) := { + [integer:x] + x := 3 + 2 * 8; + return x; + } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_demo.alpha~ b/tests/sprint4/test/sp4_cg_demo.alpha~ new file mode 100644 index 0000000..6f69389 --- /dev/null +++ b/tests/sprint4/test/sp4_cg_demo.alpha~ @@ -0,0 +1,8 @@ +type main: string -> integer +function entry: main + +entry(arg) := { + [integer:x] + x := 3 + 2 * 8; + return 0; + } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_demo.cg b/tests/sprint4/test/sp4_cg_demo.cg new file mode 100644 index 0000000..32d366c --- /dev/null +++ b/tests/sprint4/test/sp4_cg_demo.cg @@ -0,0 +1,9 @@ +type main: string -> integer +function entry: main + +entry(arg) := { + [integer:x; Boolean b] + x := 3 + 2 * 8; + b := x < 1; + return 0; + } \ No newline at end of file From c32e85c24b7c7cf7ad53177305668eeb8297d796 Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 2 May 2025 17:22:45 -0400 Subject: [PATCH 030/109] updated symbol table entry add order --- src/grammar.y | 45 ++++++++++++++++++++----- src/symbol_table.c | 16 +++++++-- tests/carl/NoErrors/functionValue.alpha | 1 + 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 8a287d2..204898b 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1,3 +1,4 @@ + /* Syntax Analyzer with Bison (3.8.2) */ /* The Translators - Spring 2025 */ @@ -203,17 +204,24 @@ definition: } if(type_of_param_type == TYPE_UNDEFINED){ CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); + // throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); } else { if(type_of_param_type == TYPE_FUNCTION_TYPE){ CreateEntry(cur, TYPE_FUNCTION_DECLARATION, parameter,NULL, getAdInfo(parameter)); + // throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); + } if(type_of_param_type == TYPE_ARRAY_TYPE){ CreateEntry(cur, TYPE_ARRAY, parameter,NULL, getAdInfo(parameter)); - } - if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ - CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter)); - } + //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); + } + if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ + CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter))==undefined; + // throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition.");} + + } + } } else { printdebug("record found"); for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ @@ -234,18 +242,29 @@ definition: if(type_of_param_type == TYPE_UNDEFINED){ printdebug("undefined type of parameter inside record"); CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); + //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); + } else { if(type_of_param_type == TYPE_FUNCTION_DECLARATION){ printdebug("function declaration of parameter inside record"); CreateEntry(cur, TYPE_FUNCTION_DECLARATION, getTypeEntry(entry),NULL, getAdInfo(entry)); + //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); + } if(type_of_param_type == TYPE_ARRAY){ printdebug("array type of parameter inside record"); CreateEntry(cur, TYPE_ARRAY, getTypeEntry(entry),NULL, getAdInfo(entry)); - } + //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); + } if(type_of_param_type == TYPE_PRIMITIVE){ printdebug("primitive type of parameter inside record"); CreateEntry(cur, TYPE_PRIMITIVE, getTypeEntry(entry),NULL, getAdInfo(entry)); + //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition.");} + } + if(type_of_param_type == TYPE_RECORD){ + printdebug("record type of parameter inside record"); + CreateEntry(cur, TYPE_RECORD, getTypeEntry(entry),NULL, getAdInfo(entry)); + //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition.");} } /*printdebug("creating entry of type %s for function", getType(entry)); CreateEntry(cur, getTypeEntry(entry), "undefined", NULL);*/ @@ -455,22 +474,30 @@ declaration: 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)); + if(CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)) == undefined){ + throw_error(ERROR_TYPE, "Duplicate defination of function in declaration list"); + } } 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)); + if(CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)) == undefined){ + throw_error(ERROR_TYPE, "Duplicate defination of array in declaration list"); + } } 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)); + if(CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1))== undefined){ + throw_error(ERROR_TYPE, "Duplicate defination of record in declaration list"); + } } 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)); + if(CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)) == undefined){ + throw_error(ERROR_TYPE, "Duplicate defination of primitive in declaration list"); + } }else { throw_error(ERROR_TYPE, "%s is being defined with an undefined type", $3); CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); diff --git a/src/symbol_table.c b/src/symbol_table.c index ab2cd88..a7c05be 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -956,6 +956,11 @@ TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, return NULL; } */ + if((id != NULL) && table_lookup(cur,id)!=undefined){ + printdebug("This name is already defined in the current scope"); + //throw_error(ERROR_TYPE, "Already defined."); + return undefined; + } if (typeOf == NULL) { printdebug("Passing an NULL Type Node to Create Entry"); return undefined; @@ -982,9 +987,14 @@ TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, printdebug("[CreateEntry] Adding %s to the symbol table", id); return newEntry; } else { - TableNode *oldEntry = table->entries; - table->entries = newEntry; - newEntry->next = oldEntry; + TableNode*oldEntry = table->entries; + while (oldEntry->next != NULL) { + oldEntry = oldEntry->next; + } + oldEntry->next = newEntry; + newEntry->next = NULL; + //table->entries = newEntry; + //newEntry->next = oldEntry; printdebug("[CreateEntry] Adding %s to the symbol table", id); return newEntry; } diff --git a/tests/carl/NoErrors/functionValue.alpha b/tests/carl/NoErrors/functionValue.alpha index 8ad0e6c..c1134ce 100644 --- a/tests/carl/NoErrors/functionValue.alpha +++ b/tests/carl/NoErrors/functionValue.alpha @@ -28,6 +28,7 @@ function c: string2int_2_integer function d: iic2b d(x,y,z) := { + [string: s;integer: s] return (x < y & z < 'm'); } From 2ed537276102f947a881381db01a99705feda3f8 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Sat, 3 May 2025 12:52:23 -0400 Subject: [PATCH 031/109] I fixed the way we are doing the evaluation of == and < Getting to &&, || next. Not sure if ! is correct --- src/grammar.y | 53 ++++++++++++++++++++++++++++++++++------- src/intermediate_code.c | 21 +++++++++------- 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 6a93c45..7de731e 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -550,6 +550,21 @@ compound_statement: emit_label(*l); S_Push(stack, l, 2); } expression R_PAREN { + emit_backpatch(S_Pop(TrueList), getLabel(current)); + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $4)); + 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); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); } sblock { @@ -563,8 +578,23 @@ compound_statement: S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); }expression R_PAREN THEN { + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $4)); + 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); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); + } sblock ELSE { // NOTE we are not going back to int l = label_gen(); @@ -752,8 +782,10 @@ expression: if(getTypeEntry((TableNode*)$2) == boo) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - emit_unary_op(E_NOT,node,tn_or_const(NODE,$2)); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + Stack * t = S_Pop(TrueList); + Stack * f = S_Pop(FalseList); + S_Push(TrueList, f, 0); + S_Push(FalseList, t, 0); //result of unary operation $$ = node; } else { @@ -864,7 +896,12 @@ expression: | expression LESS_THAN expression { - emit_conditional_jump(E_LESS_THAN, 0, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); +// ---------------------------------------------------------------------------- + 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)); + /* + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); if(t==NULL){ t = S_Init(); @@ -878,15 +915,12 @@ expression: 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(); - TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); $$ = node; } else if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==boo){ - 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; @@ -900,6 +934,8 @@ 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)); Stack * t = S_Peek(TrueList); if(t==NULL){ @@ -914,6 +950,7 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); + */ $$ = node; } else { diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 44c6016..c807096 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -58,6 +58,11 @@ int S_Size(Stack *s){ return s->size; } +void S_Merge(Stack *s1, Stack *s2){ + for (Instruction * i = S_Pop(s1); i; i = S_Pop(s1)){ + S_Push(s2, i, 1); + } +} void emit_backpatch(Stack * s, int l){ for (Instruction * i = S_Pop(s); i; i = S_Pop(s)){ i->label = l; @@ -501,7 +506,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 True GOTO %d\n", i->index, get_string(i->operand1), i->label @@ -509,7 +514,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 @@ -518,21 +523,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: if ( %s < %s ) GOTO %d\n", + "%4.d: %s = %s < %s\n", i->index, + getName(i->result), get_string(i->operand1), - get_string(i->operand2), - i->label + get_string(i->operand2) ); break; case E_EQUAL_TO: // this feels wrong I need to TODO: this fprintf(out_file, - "%4.d: if ( %s = %s ) GOTO %d\n", + "%4.d: %s = %s == %s\n", i->index, + getName(i->result), get_string(i->operand1), - get_string(i->operand2), - i->label + get_string(i->operand2) ); break; case E_CALL: From 4380d214bbe6c933662e9061719470c39c921d77 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Sat, 3 May 2025 12:53:13 -0400 Subject: [PATCH 032/109] I added some test files Looks good so far Need someone to spot check --- .../sprint3/test/sp3_if_else_nested_exp.alpha | 25 ++++++++++++++++ .../sprint3/test/sp3_while_nested_bools.alpha | 29 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 tests/sprint3/test/sp3_if_else_nested_exp.alpha create mode 100644 tests/sprint3/test/sp3_while_nested_bools.alpha diff --git a/tests/sprint3/test/sp3_if_else_nested_exp.alpha b/tests/sprint3/test/sp3_if_else_nested_exp.alpha new file mode 100644 index 0000000..08161f2 --- /dev/null +++ b/tests/sprint3/test/sp3_if_else_nested_exp.alpha @@ -0,0 +1,25 @@ +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: x ; integer: y; integer: z;integer: t] + + if ( (x = y) < ( z = t ) ) then { + if ( (x < y) = ( z < t ) ) then { + x := x; + } else { + x := 1; (* bar('c', 7); *) + } + } else { + return 0; + } +} diff --git a/tests/sprint3/test/sp3_while_nested_bools.alpha b/tests/sprint3/test/sp3_while_nested_bools.alpha new file mode 100644 index 0000000..5a6920e --- /dev/null +++ b/tests/sprint3/test/sp3_while_nested_bools.alpha @@ -0,0 +1,29 @@ +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: x ; integer: y; integer: z;integer: t] + while ( (!(x = y)) < ( z = t ) ) { + x := x; + while ( (x < y) = ( z < t ) ) { + y := y; + } + (* + if ( (x = y) = ( z < t ) ) then { + x := 1; + } else { + x := 1; + } + *) + } + return 0; +} From 1546ea178534745e54df5ed81e5fa55f5e36ed13 Mon Sep 17 00:00:00 2001 From: Annie Date: Sat, 3 May 2025 13:13:22 -0400 Subject: [PATCH 033/109] just comments --- a.out | Bin 464 -> 0 bytes src/codegen.c | 6 ++++-- 2 files changed, 4 insertions(+), 2 deletions(-) delete mode 100644 a.out diff --git a/a.out b/a.out deleted file mode 100644 index 8540d49290617f7498e8df1dc190587a92561a76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 464 zcmb<-^>JfjWMqH=Mg}_u1P><4z%T*9WN-kp9T->{SQw7G{$U1kkGuY00#jc&fK<2Z z5B~M8Upiesbi4lPcKyJ3q0{wEx9giu*B1lX*gfr5Zs{n+dVSqHOU L2E;)E==K8uL2Dw) diff --git a/src/codegen.c b/src/codegen.c index cbeadc0..806972e 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -680,10 +680,12 @@ int generateFunctionStart(Instruction *inst) { printdebug("generateFunctionStart failed, NULL tablenode"); return -1; } - + + //this is independent of parameters: fprintf(cg_flag, "%s:\n", getName(getTN(op1))); fprintf(cg_flag, "\tpushq\t%%rbp\n"); fprintf(cg_flag, "\tmovq\t%%rsp, %%rbp\n"); - + + //now we need to add the CGs of nodes to the CG list by doing assign from the return 0; } From 6b239b0724d2651faf75419e82577ed12a21a990 Mon Sep 17 00:00:00 2001 From: Partho Date: Sat, 3 May 2025 14:16:31 -0400 Subject: [PATCH 034/109] added reference to function scopes --- src/grammar.y | 11 ++++--- src/symbol_table.c | 81 ++++++++++++++++++++++++++++++++++++++++++---- src/symbol_table.h | 6 +++- 3 files changed, 86 insertions(+), 12 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 1b3b04a..9d5d5a3 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -171,6 +171,7 @@ definition: setAsKeyword(node, true); } cur = CreateScope(cur, 0, 0); + setFunScope(node, cur); printdebug("Created a new scope"); } L_PAREN { TableNode * parameter = getParameter(getTypeEntry(table_lookup(getAncestor(cur), $1))); @@ -290,11 +291,11 @@ function_declaration: if(getAdInfoType(table_lookup(cur, $4))==TYPE_FUNCTION_TYPE){ //printf("%s\n",$2); //printf("%s\n",getName(table_lookup(cur, $4))); - CreateEntry(cur,TYPE_FUNCTION_DECLARATION, table_lookup(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, table_lookup(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false,NULL)); } else{ throw_error(ERROR_TYPE, "Function declatation (%s) is not a valid function type", $2); - CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false,NULL)); } } @@ -302,11 +303,11 @@ 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)); + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false,NULL)); } else{ throw_error(ERROR_TYPE, "Function declatation (%s) is not a valid function type", $3); - CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false)); + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false,NULL)); } } @@ -467,7 +468,7 @@ declaration: printdebug("invalid (function) type passed in declaration list in dblock", @2.first_line, @2.first_column); d = TYPE_FUNCTION_DECLARATION; - if(CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)) == undefined){ + if(CreateEntry(cur,d,(TableNode*)$1,$3,NULL) == undefined){ throw_error(ERROR_TYPE, "Duplicate defination of function in declaration list"); } diff --git a/src/symbol_table.c b/src/symbol_table.c index a7c05be..f4fa1ea 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -456,12 +456,13 @@ int getRecSize(SymbolTable *tn) { // using "as" the input record can be decomposed to give the illusion of // multiple inputs Below function also has the line number where the function is // first defined -AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { - AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); +AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular, SymbolTable *scope) { + AdInfo *info = (AdInfo *)calloc(1,sizeof(AdInfo)); info->FunDecAdInfo = (function_declaration_info *)malloc( sizeof(function_declaration_info)); info->FunDecAdInfo->startlinenumber = line; info->FunDecAdInfo->regularoras = asorregular; + info->FunDecAdInfo->scope = scope; return info; } // gets the line at which the function was first defined. (Can be used to print @@ -530,6 +531,68 @@ bool getAsKeyword(TableNode *definition) { return definition->additionalinfo->FunDecAdInfo->regularoras; } +SymbolTable *getFunScope(TableNode *definition) { + if (definition == NULL) { + printdebug( + "passed a NULL entry to getScope " + "function. Invalid."); + return NULL; + } + if (getAdInfoType(definition) != TYPE_FUNCTION_DECLARATION) { + printdebug( + "passed in invalid entry type to getScope " + "function. Invalid."); + return NULL; + } + if (definition->additionalinfo == NULL) { + printdebug( + "node has NULL additionalinfo. Invalid."); + return NULL; + } + if(definition->additionalinfo->FunDecAdInfo == NULL) { + printdebug( + "node has NULL additionalinfo. Invalid."); + return NULL; + } + if(definition->additionalinfo->FunDecAdInfo->scope == NULL) { + printdebug( + "node has no scope initialized."); + return NULL; + } + + return definition->additionalinfo->FunDecAdInfo->scope; +} +TableNode *setFunScope(TableNode *tn, SymbolTable *scope) { + if (tn == NULL) { + printdebug( + "passing in a NULL entry to setFunScope. " + "invalid"); + return undefined; + } + if (getAdInfoType(tn) != TYPE_FUNCTION_DECLARATION) { + printdebug( + "passing in an invalid entry to setFunScope. " + "invalid"); + return undefined; + } + if(tn->additionalinfo == NULL) { + printdebug( + "node has NULL additionalinfo. Invalid."); + return undefined; + } + if(tn->additionalinfo->FunDecAdInfo == NULL) { + printdebug( + "node has NULL additionalinfo. Invalid."); + return undefined; + } + if(scope == NULL) { + printdebug( + "passed in an empty scope."); + return undefined; + } + tn->additionalinfo->FunDecAdInfo->scope = scope; + return tn; +} TableNode *setAsKeyword(TableNode *tn, bool as) { if (tn == NULL) { printdebug( @@ -787,10 +850,10 @@ SymbolTable *init(SymbolTable *start) { chara->additionalinfo = CreatePrimitiveInfo(SIZE_CHAR); stri->additionalinfo = CreateArrayInfo(1, chara); boo->additionalinfo = CreatePrimitiveInfo(SIZE_BOOL); - reserve->additionalinfo = CreateFunctionDeclarationInfo(0, false); + reserve->additionalinfo = CreateFunctionDeclarationInfo(0, false,NULL); reservetype->additionalinfo = CreateFunctionTypeInfo(integ, addr); releasetype->additionalinfo = CreateFunctionTypeInfo(addr, integ); - release->additionalinfo = CreateFunctionDeclarationInfo(0, false); + release->additionalinfo = CreateFunctionDeclarationInfo(0, false,NULL); integ->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for integ addr->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for addr @@ -1308,10 +1371,16 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (getAdInfoType(entry) == TYPE_FUNCTION_DECLARATION) { char *functiontype = (char *)malloc(100); sprintf(functiontype, " %s", getName(getTypeEntry(entry))); + char* functionScope = (char *)malloc(100); + if(getLine(getFunScope(entry)) < 1){ + sprintf(functionScope, " Function not defined before runtime"); + }else{ + sprintf(functionScope, " Function Definition that starts at line %d",getLine(getFunScope(entry))); + } if (parentScopeNum == 0) { - st_fprint(file_ptr, getName(entry), currentScopeNum, -100, functiontype, " Function Definition"); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, functiontype, functionScope); } else { - st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, functiontype, " Function Definition"); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, functiontype, functionScope); } } diff --git a/src/symbol_table.h b/src/symbol_table.h index e730595..f838314 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -20,6 +20,7 @@ extern FILE *ir_flag; struct TableNode; typedef struct TFList TFList; typedef struct CGNode CGNode; +typedef struct SymbolTable SymbolTable; typedef struct Constant_Stack { struct TableNode *theType; @@ -47,6 +48,7 @@ typedef struct { typedef struct { int startlinenumber; bool regularoras; + SymbolTable* scope; } function_declaration_info; typedef struct { @@ -120,7 +122,9 @@ int getRecLength(TableNode *definition); SymbolTable *getRecList(TableNode *definition); TableNode *setRecSize(TableNode *tn, int n); int getRecSize(SymbolTable *tn); -AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular); +AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular,SymbolTable *scope); +TableNode *setFunScope(TableNode *tn, SymbolTable *scope); +SymbolTable *getFunScope(TableNode *definition); int getStartLine(TableNode *definition); TableNode *setStartLine(TableNode *tn, int start); bool getAsKeyword(TableNode *definition); From ea7c2846657e0b5823a040f72e12bb62f8f5a5ef Mon Sep 17 00:00:00 2001 From: Scarlett Date: Sat, 3 May 2025 19:25:55 -0400 Subject: [PATCH 035/109] woah --- test.sh | 221 ++++++++---------- tests/carl/Errors/entry.undeclaredType.alpha | 10 - .../Errors/entry.undeclaredType.alpha.asc | 16 -- tests/carl/Errors/entry.undeclaredVar.alpha | 7 - .../carl/Errors/entry.undeclaredVar.alpha.asc | 12 - tests/carl/Errors/error.operator.alpha | 14 -- tests/carl/Errors/error.operator.alpha.asc | 19 -- .../carl/NoErrors/entry.definition.alpha.asc | 10 - .../entry.duplicateDifferent.alpha.asc | 13 -- .../NoErrors/entry.duplicateSame.alpha.asc | 11 - tests/carl/NoErrors/entry.local.alpha.asc | 13 -- tests/carl/NoErrors/error.none.alpha.asc | 16 -- .../NoErrors/function.declaration.alpha.asc | 5 - .../NoErrors/function.definition.alpha.asc | 9 - tests/carl/NoErrors/functionValue.alpha.asc | 75 ------ tests/carl/NoErrors/sample.good.alpha.asc | 31 --- tests/carl/NoErrors/selectionSort.alpha.asc | 70 ------ tests/carl/NoErrors/type.array.alpha.asc | 3 - tests/carl/NoErrors/type.mapping.alpha.asc | 4 - tests/carl/NoErrors/type.record.alpha.asc | 3 - tests/carl/NoErrors/types.alpha.asc | 77 ------ .../test}/entry.definition.alpha | 1 + .../test}/entry.duplicateDifferent.alpha | 1 + .../test}/entry.duplicateSame.alpha | 1 + .../NoErrors => given/test}/entry.local.alpha | 1 + .../NoErrors => given/test}/error.none.alpha | 1 + .../test}/function.declaration.alpha | 1 + .../test}/function.definition.alpha | 1 + .../test}/functionValue.alpha | 1 + .../NoErrors => given/test}/sample.good.alpha | 2 +- .../test}/selectionSort.alpha | 1 + .../NoErrors => given/test}/type.array.alpha | 1 + .../test}/type.mapping.alpha | 1 + .../NoErrors => given/test}/type.record.alpha | 1 + .../{carl/NoErrors => given/test}/types.alpha | 1 + ...fix1.expected => sp1_comment_fix1.tok.exp} | 0 ...fix2.expected => sp1_comment_fix2.tok.exp} | 0 ...es.expected => sp1_comment_issues.tok.exp} | 0 ...comments.expected => sp1_comments.tok.exp} | 0 ...ken.expected => sp1_general_token.tok.exp} | 0 tests/sprint1/expected/sp1_keywords.expected | 29 --- tests/sprint1/expected/sp1_operators.expected | 22 -- .../sprint1/expected/sp1_other_punc.expected | 7 - .../expected/sp1_punc_grouping.expected | 59 ----- .../expected/sp1_real_alpha_file1.expected | 145 ------------ .../expected/sp1_real_alpha_file2.expected | 100 -------- .../sprint1/expected/sp1_simple_int.expected | 8 - .../expected/sp1_simple_literals.expected | 64 ----- tests/sprint1/expected/sp1_variables.expected | 13 -- tests/sprint1/test/sp1_comment_fix1.alpha | 1 + tests/sprint1/test/sp1_comment_fix2.alpha | 1 + tests/sprint1/test/sp1_comment_issues.alpha | 1 + tests/sprint1/test/sp1_comments.alpha | 1 + tests/sprint1/test/sp1_general_token.alpha | 1 + tests/sprint1/test/sp1_keywords.alpha | 1 + tests/sprint1/test/sp1_operators.alpha | 1 + tests/sprint1/test/sp1_other_punc.alpha | 1 + tests/sprint1/test/sp1_punc_grouping.alpha | 1 + tests/sprint1/test/sp1_real_alpha_file1.alpha | 1 + tests/sprint1/test/sp1_real_alpha_file2.alpha | 1 + tests/sprint1/test/sp1_simple_alpha.alpha | 1 + tests/sprint1/test/sp1_simple_int.alpha | 1 + tests/sprint1/test/sp1_simple_literals.alpha | 1 + tests/sprint1/test/sp1_variables.alpha | 1 + 64 files changed, 121 insertions(+), 995 deletions(-) delete mode 100644 tests/carl/Errors/entry.undeclaredType.alpha delete mode 100644 tests/carl/Errors/entry.undeclaredType.alpha.asc delete mode 100644 tests/carl/Errors/entry.undeclaredVar.alpha delete mode 100644 tests/carl/Errors/entry.undeclaredVar.alpha.asc delete mode 100644 tests/carl/Errors/error.operator.alpha delete mode 100644 tests/carl/Errors/error.operator.alpha.asc delete mode 100644 tests/carl/NoErrors/entry.definition.alpha.asc delete mode 100644 tests/carl/NoErrors/entry.duplicateDifferent.alpha.asc delete mode 100644 tests/carl/NoErrors/entry.duplicateSame.alpha.asc delete mode 100644 tests/carl/NoErrors/entry.local.alpha.asc delete mode 100644 tests/carl/NoErrors/error.none.alpha.asc delete mode 100644 tests/carl/NoErrors/function.declaration.alpha.asc delete mode 100644 tests/carl/NoErrors/function.definition.alpha.asc delete mode 100644 tests/carl/NoErrors/functionValue.alpha.asc delete mode 100644 tests/carl/NoErrors/sample.good.alpha.asc delete mode 100644 tests/carl/NoErrors/selectionSort.alpha.asc delete mode 100644 tests/carl/NoErrors/type.array.alpha.asc delete mode 100644 tests/carl/NoErrors/type.mapping.alpha.asc delete mode 100644 tests/carl/NoErrors/type.record.alpha.asc delete mode 100644 tests/carl/NoErrors/types.alpha.asc rename tests/{carl/NoErrors => given/test}/entry.definition.alpha (84%) rename tests/{carl/NoErrors => given/test}/entry.duplicateDifferent.alpha (86%) rename tests/{carl/NoErrors => given/test}/entry.duplicateSame.alpha (85%) rename tests/{carl/NoErrors => given/test}/entry.local.alpha (85%) rename tests/{carl/NoErrors => given/test}/error.none.alpha (92%) rename tests/{carl/NoErrors => given/test}/function.declaration.alpha (68%) rename tests/{carl/NoErrors => given/test}/function.definition.alpha (78%) rename tests/{carl/NoErrors => given/test}/functionValue.alpha (98%) rename tests/{carl/NoErrors => given/test}/sample.good.alpha (96%) rename tests/{carl/NoErrors => given/test}/selectionSort.alpha (98%) rename tests/{carl/NoErrors => given/test}/type.array.alpha (52%) rename tests/{carl/NoErrors => given/test}/type.mapping.alpha (60%) rename tests/{carl/NoErrors => given/test}/type.record.alpha (67%) rename tests/{carl/NoErrors => given/test}/types.alpha (99%) rename tests/sprint1/expected/{sp1_comment_fix1.expected => sp1_comment_fix1.tok.exp} (100%) rename tests/sprint1/expected/{sp1_comment_fix2.expected => sp1_comment_fix2.tok.exp} (100%) rename tests/sprint1/expected/{sp1_comment_issues.expected => sp1_comment_issues.tok.exp} (100%) rename tests/sprint1/expected/{sp1_comments.expected => sp1_comments.tok.exp} (100%) rename tests/sprint1/expected/{sp1_general_token.expected => sp1_general_token.tok.exp} (100%) delete mode 100644 tests/sprint1/expected/sp1_keywords.expected delete mode 100644 tests/sprint1/expected/sp1_operators.expected delete mode 100644 tests/sprint1/expected/sp1_other_punc.expected delete mode 100644 tests/sprint1/expected/sp1_punc_grouping.expected delete mode 100644 tests/sprint1/expected/sp1_real_alpha_file1.expected delete mode 100644 tests/sprint1/expected/sp1_real_alpha_file2.expected delete mode 100644 tests/sprint1/expected/sp1_simple_int.expected delete mode 100644 tests/sprint1/expected/sp1_simple_literals.expected delete mode 100644 tests/sprint1/expected/sp1_variables.expected diff --git a/test.sh b/test.sh index 3f6f5a9..9c3652e 100755 --- a/test.sh +++ b/test.sh @@ -20,147 +20,110 @@ LIGHTCYAN='\033[1;36m' WHITE='\033[1;37m' if [ ! -f "./alpha" ]; then - echo -e "${RED}[ERROR] ${YELLOW}File ./alpha not found!${WHITE}" - exit 1 + echo -e "${RED}[ALERT] ${YELLOW}File ./alpha not found! Generating with 'make'.${WHITE}" + make fi if [ ! -d "./out" ]; then mkdir -p out fi -SWITCH=${YELLOW} -count=0 +if [ $# -eq 0 ]; then + help +fi -switchfunc() { - if [ $count -eq 0 ]; then - count=1 - SWITCH=${YELLOW} - else - count=0 - SWITCH='\033[0;35m' - fi +help() { + echo -e "${GREEN}[HELP] ${YELLOW}Usage: ./test.sh [-exp] ${WHITE}" + echo -e "${GREEN}[HELP] ${YELLOW}To all tests in a folder: ./test/sh

/* [-exp]${WHITE}" + exit 1 } -if [ $# -eq 0 ]; then - echo -e "${YELLOW}[INFO] ${WHITE}Running all tests...${WHITE}" - echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-1 ---------------------------\n${WHITE}" - for file in ./tests/sprint1/test/*; do - if [ -f "$file" ]; then - filename=$(basename -- "$file") - echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st -debug "$file" - echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" - switchfunc - fi - done - echo -e "" +run() { + filename=$(basename -- "$1") + first_line=$(head -n 1 "$1") + if [[ "$first_line" == "\$\$ TEST: ["*"]"* ]]; then + if [ -n "$2" ]; then + if [[ "$2" == "-exp" ]]; then + bracket_content=$(echo "$first_line" | sed -n 's/.*\[\(.*\)\].*/\1/p') + sed -i '1d' "$1" + ./alpha ${bracket_content} "$1" + sed -i "1s/^/$first_line\n/" "$1" + path=$(dirname "$1") + filename_noext=${filename:0:${#filename}-6} - echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-2 ---------------------------\n${WHITE}" - for file in ./tests/sprint2/test/*; do - if [ -f "$file" ]; then - filename=$(basename -- "$file") - echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st -debug "$file" - echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" - switchfunc - fi - done - echo -e "" + for file in out/${filename_noext}.*; do + if [[ "$file" == *".asc" || "$file" == *".s" || "$file" == *".st" || "$file" == *".tok" || "$file" == *".ir" ]]; then + for_filename=$(basename -- "$file") + for_filename="${for_filename}.exp" + if [ -f "${path}/../expected/${for_filename}" ]; then + echo -e "${RED}[ALERT] ${YELLOW}File ${path}/../expected/${for_filename} already exists! Overwriting...${WHITE}" + fi + cp "$file" "${path}/../expected/${for_filename}" + else + echo -e "${RED}[ALERT] ${YELLOW}Unexpected file found: $file ${WHITE}" + fi + done + else + echo -e "${BLUE}[ERROR] ${YELLOW}Invalid argument $2!${WHITE}" + help + fi + fi - echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-3 ---------------------------\n${WHITE}" - for file in ./tests/sprint3/test/*; do - if [ -f "$file" ]; then - filename=$(basename -- "$file") - echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st -debug "$file" - echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" - switchfunc - fi - done - echo -e "" + bracket_content=$(echo "$first_line" | sed -n 's/.*\[\(.*\)\].*/\1/p') + sed -i '1d' "$1" + ./alpha ${bracket_content} "$1" + sed -i "1s/^/$first_line\n/" "$1" + else + echo -e "${RED}[ERROR] ${YELLOW}File $1 is not a valid .alpha test file!${WHITE}" + help + fi +} - echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-4 ---------------------------\n${WHITE}" - for file in ./tests/sprint4/test/*; do - if [ -f "$file" ]; then - filename=$(basename -- "$file") - echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -cg "$file" - echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n${WHITE}" - switchfunc - fi - done -else - if [ "$1" == "--help" ]; then - echo -e "${YELLOW}[INFO] ${WHITE}Usage: ./test.sh [prefix]" - echo -e "${YELLOW}[INFO] ${WHITE}--help: show this help message" - echo -e "${YELLOW}[INFO] ${WHITE}--file : run test with file" - exit 0 - fi - if [[ "$1" == "--file" ]]; then - shift - if [ $# -eq 0 ]; then - echo -e "${RED}[ERROR] ${YELLOW}No file specified!${WHITE}" - exit 1 - fi - if [ -f "$1" ]; then - filename=$(basename -- "$1") - echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st -debug "$1" - echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}" - exit 1 - else - echo -e "${RED}[ERROR] ${YELLOW}File $1 not found!${WHITE}" - exit 1 - fi - fi - if [[ "$1" == "sp1" ]]; then - echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..." - for file in ./tests/sprint1/test/*; do - if [[ "$file" == *"$1"* ]]; then - filename=$(basename -- "$file") - echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st -debug "$file" - echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" - switchfunc - fi - done - elif [[ "$1" == "sp2" ]]; then - echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..." - for file in ./tests/sprint2/test/*; do - if [[ "$file" == *"$1"* ]]; then - filename=$(basename -- "$file") - echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st -debug "$file" - echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" - switchfunc - fi - done - elif [[ "$1" == "sp3" ]]; then - echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..." - for file in ./tests/sprint3/test/*; do - if [[ "$file" == *"$1"* ]]; then - filename=$(basename -- "$file") - echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st -debug "$file" - echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" - switchfunc - fi - done - elif [[ "$1" == "sp4" ]]; then - echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..." - for file in ./tests/sprint4/test/*; do - if [[ "$file" == *"$1"* ]]; then - filename=$(basename -- "$file") - echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -cg -debug "$file" - echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" - switchfunc - fi - done - else - echo -e "${RED}[ERROR] ${YELLOW}Invalid prefix $1!${WHITE}" - exit 1 - fi +if [[ "$1" == *"/" ]]; then + if [ -n $2 ]; then + for file in "$1"/*; do + if [[ "$file" == *.alpha ]]; then + if [[ "$2" == "-exp" ]]; then + run "$file" "$2" + else + echo -e "${RED}[ERROR] ${YELLOW}Invalid argument $2!${WHITE}" + help + fi + else + echo -e "${RED}[ERROR] ${YELLOW}File $file is not a .alpha file!${WHITE}" + help + fi + done + else + for file in "$1"/*; do + if [[ "$file" == *.alpha ]]; then + run "$file" + else + echo -e "${RED}[ERROR] ${YELLOW}File $file is not a .alpha file!${WHITE}" + help + fi + done + + fi + exit 0 +fi + +if [ -f "$1" ]; then + if [[ "$1" == *.alpha ]]; then + if [ -n "$2" ]; then + if [[ "$2" == "-exp" ]]; then + run "$1" "$2" + else + echo -e "${RED}[ERROR] ${YELLOW}Invalid argument $2!${WHITE}" + help + fi + else + run "$1" + fi + else + echo -e "${RED}[ERROR] ${YELLOW}File $1 is not a .alpha file!${WHITE}" + help + fi fi diff --git a/tests/carl/Errors/entry.undeclaredType.alpha b/tests/carl/Errors/entry.undeclaredType.alpha deleted file mode 100644 index 6b9531f..0000000 --- a/tests/carl/Errors/entry.undeclaredType.alpha +++ /dev/null @@ -1,10 +0,0 @@ -type M : string -> integer - -function foo : M - -foo (s) := { - [ - int: x - ] - return 0; -} diff --git a/tests/carl/Errors/entry.undeclaredType.alpha.asc b/tests/carl/Errors/entry.undeclaredType.alpha.asc deleted file mode 100644 index cd1d37c..0000000 --- a/tests/carl/Errors/entry.undeclaredType.alpha.asc +++ /dev/null @@ -1,16 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.undeclaredType.alpha -001: type M : string -> integer -002: -003: function foo : M -004: -005: foo (s) := { -006: [ -007: int: x - ^0 ^1 - LINE 7:9 ** ERROR #0: the name 'int', used here as a type, has not been declared at this point in the program. - LINE 7:14 ** ERROR #1: the name 'x' is being declared with an unknown type. - -008: ] -009: return 0; -010: } -011: diff --git a/tests/carl/Errors/entry.undeclaredVar.alpha b/tests/carl/Errors/entry.undeclaredVar.alpha deleted file mode 100644 index 6cd5fa7..0000000 --- a/tests/carl/Errors/entry.undeclaredVar.alpha +++ /dev/null @@ -1,7 +0,0 @@ -type M : string -> integer - -function entry : M - -entry(s) := { - return x; -} diff --git a/tests/carl/Errors/entry.undeclaredVar.alpha.asc b/tests/carl/Errors/entry.undeclaredVar.alpha.asc deleted file mode 100644 index 7c4e6c2..0000000 --- a/tests/carl/Errors/entry.undeclaredVar.alpha.asc +++ /dev/null @@ -1,12 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.undeclaredVar.alpha -001: type M : string -> integer -002: -003: function entry : M -004: -005: entry(s) := { -006: return x; - ^0 - LINE 6:12 ** ERROR #0: the name 'x', used here as a variable name, has not been declared at this point in the program. - -007: } -008: diff --git a/tests/carl/Errors/error.operator.alpha b/tests/carl/Errors/error.operator.alpha deleted file mode 100644 index a7b0691..0000000 --- a/tests/carl/Errors/error.operator.alpha +++ /dev/null @@ -1,14 +0,0 @@ -type string2int: string -> integer - -function entry : string2int - -entry(arg) := { - [ integer: i; integer: sum ] - sum := 0; - i := 0; - while (i < 10) { - sum = sum + i; - i := i + 1; - } - return 0; -} diff --git a/tests/carl/Errors/error.operator.alpha.asc b/tests/carl/Errors/error.operator.alpha.asc deleted file mode 100644 index 82f5614..0000000 --- a/tests/carl/Errors/error.operator.alpha.asc +++ /dev/null @@ -1,19 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file error.operator.alpha -001: type string2int: string -> integer -002: -003: function entry : string2int -004: -005: entry(arg) := { -006: [ integer: i; integer: sum ] -007: sum := 0; -008: i := 0; -009: while (i < 10) { -010: sum = sum + i; - ^0 - LINE 10:13 ** ERROR #0: assignment operator (:=) expected but equality operator (=) found. - -011: i := i + 1; -012: } -013: return 0; -014: } -015: diff --git a/tests/carl/NoErrors/entry.definition.alpha.asc b/tests/carl/NoErrors/entry.definition.alpha.asc deleted file mode 100644 index 07dbd42..0000000 --- a/tests/carl/NoErrors/entry.definition.alpha.asc +++ /dev/null @@ -1,10 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.definition.alpha -001: (* type string : 1 -> character *) -002: type M : string -> integer -003: -004: function entry : M -005: -006: entry(s) := { -007: return 0; -008: } -009: diff --git a/tests/carl/NoErrors/entry.duplicateDifferent.alpha.asc b/tests/carl/NoErrors/entry.duplicateDifferent.alpha.asc deleted file mode 100644 index 65ae8d8..0000000 --- a/tests/carl/NoErrors/entry.duplicateDifferent.alpha.asc +++ /dev/null @@ -1,13 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.duplicateDifferent.alpha -001: type M : string -> integer -002: -003: function entry : M -004: -005: entry(s) := { -006: [ -007: integer: x; -008: character: x -009: ] -010: return x; -011: } -012: diff --git a/tests/carl/NoErrors/entry.duplicateSame.alpha.asc b/tests/carl/NoErrors/entry.duplicateSame.alpha.asc deleted file mode 100644 index 7861cc6..0000000 --- a/tests/carl/NoErrors/entry.duplicateSame.alpha.asc +++ /dev/null @@ -1,11 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.duplicateSame.alpha -001: type M : string -> integer -002: function entry : M -003: -004: entry(s) := { -005: [ -006: integer: x; integer: x -007: ] -008: return x; -009: } -010: diff --git a/tests/carl/NoErrors/entry.local.alpha.asc b/tests/carl/NoErrors/entry.local.alpha.asc deleted file mode 100644 index e9882d4..0000000 --- a/tests/carl/NoErrors/entry.local.alpha.asc +++ /dev/null @@ -1,13 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.local.alpha -001: type M : string -> integer -002: -003: function entry : M -004: -005: entry(s) := { -006: [ -007: integer: x -008: ] -009: x := 0; -010: return x; -011: } -012: diff --git a/tests/carl/NoErrors/error.none.alpha.asc b/tests/carl/NoErrors/error.none.alpha.asc deleted file mode 100644 index 9fdcadb..0000000 --- a/tests/carl/NoErrors/error.none.alpha.asc +++ /dev/null @@ -1,16 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file error.none.alpha -001: type string2int: string -> integer -002: -003: function entry : string2int -004: -005: entry(arg) := { -006: [ integer: i ; integer: sum ] -007: sum := 0; -008: i := 0 ; -009: while (i < 10) { -010: sum := sum + i; -011: i := i + 1; -012: } -013: return 0; -014: } -015: diff --git a/tests/carl/NoErrors/function.declaration.alpha.asc b/tests/carl/NoErrors/function.declaration.alpha.asc deleted file mode 100644 index fca046a..0000000 --- a/tests/carl/NoErrors/function.declaration.alpha.asc +++ /dev/null @@ -1,5 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file function.declaration.alpha -001: type M : integer -> integer -002: -003: function f : M -004: diff --git a/tests/carl/NoErrors/function.definition.alpha.asc b/tests/carl/NoErrors/function.definition.alpha.asc deleted file mode 100644 index e476758..0000000 --- a/tests/carl/NoErrors/function.definition.alpha.asc +++ /dev/null @@ -1,9 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file function.definition.alpha -001: type M : integer -> integer -002: -003: function f : M -004: -005: f(x) := { -006: return x; -007: } -008: diff --git a/tests/carl/NoErrors/functionValue.alpha.asc b/tests/carl/NoErrors/functionValue.alpha.asc deleted file mode 100644 index 882d558..0000000 --- a/tests/carl/NoErrors/functionValue.alpha.asc +++ /dev/null @@ -1,75 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file functionValue.alpha -001: (* Type definitions *) -002: -003: (* mapping type *) -004: type string2int: string -> integer -005: -006: (* array of functions *) -007: type funArray: 1 -> string2int -008: -009: (* record of functions *) -010: type funRec: [ string2int: f; string2int: g ] -011: -012: (* function returning function *) -013: type integer_2_string2int: integer -> string2int -014: -015: (* function returning function *) -016: type string2int_2_integer: string2int -> integer -017: -018: -019: type iXiXc: [integer: a; integer: b; character: c] -020: -021: type iic2b: iXiXc -> Boolean -022: -023: (* Function declarations using the above type definitions *) -024: function a: string2int -025: function b: integer_2_string2int -026: function c: string2int_2_integer -027: -028: function d: iic2b -029: -030: d(x,y,z) := { -031: return (x < y & z < 'm'); -032: } -033: -034: function entry: string2int -035: -036: a(x) := { -037: [string : s] -038: s := x; -039: return 0; -040: } -041: -042: b(x) := { -043: [integer: i] -044: i := x; -045: return a; -046: } -047: -048: c(x) := { -049: [string: s] -050: s := "Hi!"; -051: return x(s); -052: } -053: -054: -055: (* Function definition -056: entry is the first function called -057: *) -058: entry(arg) := { -059: [integer: result; string2int: f; integer: temp] -060: temp := a("Hello"); -061: f := b(temp); -062: result := c(f); -063: if (d(1,2,'c')) -064: then { -065: result := 0; -066: } -067: else { -068: [ Boolean : b] -069: result := entry("hello"); -070: } -071: result := c(f); -072: return result; -073: } -074: diff --git a/tests/carl/NoErrors/sample.good.alpha.asc b/tests/carl/NoErrors/sample.good.alpha.asc deleted file mode 100644 index a4bfa3a..0000000 --- a/tests/carl/NoErrors/sample.good.alpha.asc +++ /dev/null @@ -1,31 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file sample.good.alpha -001: -001: (* Type definitions *) -003: type int2int: integer -> integer -004: type string2int: string -> integer -005: -006: (* Function declarations -007: They use the above type definitions -008: *) -009: function square : int2int -010: function entry : string2int -011: -012: (* Function definition -013: Functions must be declared before they are defined -014: *) -015: square(x) := { -016: return x * x; -017: } -018: -019: (* Function definition -020: entry is the first function called -021: *) -022: entry(arg) := { -023: [ integer: input ; integer: expected ; integer: actual ; Boolean: result ] -024: input := 7; -025: expected := 49; -026: actual := square(input); -027: result := expected = actual; -028: return 0; -029: } -030: diff --git a/tests/carl/NoErrors/selectionSort.alpha.asc b/tests/carl/NoErrors/selectionSort.alpha.asc deleted file mode 100644 index 2a12877..0000000 --- a/tests/carl/NoErrors/selectionSort.alpha.asc +++ /dev/null @@ -1,70 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file selectionSort.alpha -001: (* Type definitions *) -002: -003: type string2int: string -> integer -004: type intArray: 1 -> integer -005: type intArrayXinteger: [ intArray: data; integer: index ] -006: type intArrayXinteger2integer: intArrayXinteger -> integer -007: type intArray2Boolean: intArray -> Boolean -008: -009: -010: (* Function declarations -011: They use the above type definitions -012: *) -013: function indexOfSmallest: intArrayXinteger2integer -014: function selectionSort: intArray2Boolean -015: function entry : string2int -016: -017: (* indexOfSmallest *) -018: indexOfSmallest (* as *) (data, startingIndex) := { -019: [ integer: indexOfSmallestSoFar; integer: i ] -020: indexOfSmallestSoFar := startingIndex; -021: i := 0 ; -022: while (i < data._1 ) { -023: if ( data(i) < data(indexOfSmallestSoFar) ) -024: then { -025: indexOfSmallestSoFar := i; -026: } -027: else { -028: i := i; -029: } -030: i := i + 1; -031: } -032: return indexOfSmallestSoFar; -033: } -034: -035: -036: (* selectionSort *) -037: selectionSort(data) := { -038: [ integer: i ] -039: i := 0 ; -040: while (i < data._1 ) { -041: [ integer: index; integer: temp ] -042: index := indexOfSmallest(data,i); -043: temp := data(index); -044: data(index) := data(i); -045: data(i) := temp; -046: i := i + 1; -047: } -048: return true; -049: } -050: -051: -052: (* Function definition -053: entry is the first function called -054: *) -055: entry(arg) := { -056: [ intArray: data; Boolean: _ ] -057: data := reserve data(8); -058: data(0) := 60; -059: data(1) := 80; -060: data(2) := 10; -061: data(3) := 50; -062: data(4) := 30; -063: data(5) := 40; -064: data(6) := 20; -065: data(7) := 70; -066: _ := selectionSort(data); -067: return 0; -068: } -069: diff --git a/tests/carl/NoErrors/type.array.alpha.asc b/tests/carl/NoErrors/type.array.alpha.asc deleted file mode 100644 index 8e6154d..0000000 --- a/tests/carl/NoErrors/type.array.alpha.asc +++ /dev/null @@ -1,3 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file type.array.alpha -001: type A : 1 -> integer -002: diff --git a/tests/carl/NoErrors/type.mapping.alpha.asc b/tests/carl/NoErrors/type.mapping.alpha.asc deleted file mode 100644 index 2ce8f0c..0000000 --- a/tests/carl/NoErrors/type.mapping.alpha.asc +++ /dev/null @@ -1,4 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file type.mapping.alpha -001: type M : integer -> character -002: -003: diff --git a/tests/carl/NoErrors/type.record.alpha.asc b/tests/carl/NoErrors/type.record.alpha.asc deleted file mode 100644 index 848948b..0000000 --- a/tests/carl/NoErrors/type.record.alpha.asc +++ /dev/null @@ -1,3 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file type.record.alpha -001: type R : [ integer : i ; character : c ] -002: diff --git a/tests/carl/NoErrors/types.alpha.asc b/tests/carl/NoErrors/types.alpha.asc deleted file mode 100644 index 8844865..0000000 --- a/tests/carl/NoErrors/types.alpha.asc +++ /dev/null @@ -1,77 +0,0 @@ -alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file types.alpha -001: (* -001: -002: At compiler start-up your program should -003: create symbol table entries for the following -004: built-in types: -005: -006: Boolean (1 byte) -007: character (1 byte) -008: integer (4 bytes) -009: address (8 bytes) -010: -011: and the following privileged type (it has literals): -012: -013: type string: 1 -> character -014: -015: Your compiler can define other types during -016: its start-up routine as well, if it is helpful -017: to do so. -018: -019: *) -021: -022: -023: -024: type BooleanXBoolean: [Boolean: x; Boolean: y] -025: type characterXcharacter: [character: x; character: y] -026: type integerXinteger: [integer: x; integer: y] -027: -028: type Boolean2Boolean: Boolean -> Boolean -029: type integer2integer: integer -> integer -030: -031: type character2integer: character -> integer -032: type Boolean2integer: Boolean -> integer -033: type string2integer: string -> integer -034: -035: type integerXinteger2integer: integerXinteger -> integer -036: -037: type integerXinteger2Boolean: integerXinteger -> Boolean -038: type characterXcharacter2Boolean: characterXcharacter -> Boolean -039: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean -040: -041: -042: type integer2address: integer -> address -043: type address2integer: address -> integer -044: -045: -046: (* The alpha library functions -047: You will be provided with x86-64 assembly -048: code implementations of these. -049: *) -050: -051: external function printInteger: integer2integer -052: external function printCharacter: character2integer -053: external function printBoolean: Boolean2integer -054: -055: (* -056: A declaration of the entry point function for your program -057: -058: You may assume that when starting this function will behave as if -059: it had been called from the C language main function like this: -060: -061: int main(int argc, char * argv[]) { -062: if (argc == 1) { -063: return entry(NULL); -064: } -065: else { -066: return entry(makeAlphaString(argv[1])); -067: } -068: } -069: -070: for some suitable definition of makeAlphaString which creates -071: an alpha string representation of its argument C string in memory -072: and returns a pointer to that alpha string. -073: *) -074: -075: function entry: string2integer -076: diff --git a/tests/carl/NoErrors/entry.definition.alpha b/tests/given/test/entry.definition.alpha similarity index 84% rename from tests/carl/NoErrors/entry.definition.alpha rename to tests/given/test/entry.definition.alpha index 0003cd5..c9538b4 100644 --- a/tests/carl/NoErrors/entry.definition.alpha +++ b/tests/given/test/entry.definition.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-asc -tc] (* type string : 1 -> character *) type M : string -> integer diff --git a/tests/carl/NoErrors/entry.duplicateDifferent.alpha b/tests/given/test/entry.duplicateDifferent.alpha similarity index 86% rename from tests/carl/NoErrors/entry.duplicateDifferent.alpha rename to tests/given/test/entry.duplicateDifferent.alpha index 5cbd668..41168f2 100644 --- a/tests/carl/NoErrors/entry.duplicateDifferent.alpha +++ b/tests/given/test/entry.duplicateDifferent.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-asc -tc] type M : string -> integer function entry : M diff --git a/tests/carl/NoErrors/entry.duplicateSame.alpha b/tests/given/test/entry.duplicateSame.alpha similarity index 85% rename from tests/carl/NoErrors/entry.duplicateSame.alpha rename to tests/given/test/entry.duplicateSame.alpha index 554b9d8..e6b295d 100644 --- a/tests/carl/NoErrors/entry.duplicateSame.alpha +++ b/tests/given/test/entry.duplicateSame.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-asc -tc] type M : string -> integer function entry : M diff --git a/tests/carl/NoErrors/entry.local.alpha b/tests/given/test/entry.local.alpha similarity index 85% rename from tests/carl/NoErrors/entry.local.alpha rename to tests/given/test/entry.local.alpha index cff2062..e9905c4 100644 --- a/tests/carl/NoErrors/entry.local.alpha +++ b/tests/given/test/entry.local.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-asc -tc] type M : string -> integer function entry : M diff --git a/tests/carl/NoErrors/error.none.alpha b/tests/given/test/error.none.alpha similarity index 92% rename from tests/carl/NoErrors/error.none.alpha rename to tests/given/test/error.none.alpha index 85aa4f2..50fc401 100644 --- a/tests/carl/NoErrors/error.none.alpha +++ b/tests/given/test/error.none.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-asc -tc] type string2int: string -> integer function entry : string2int diff --git a/tests/carl/NoErrors/function.declaration.alpha b/tests/given/test/function.declaration.alpha similarity index 68% rename from tests/carl/NoErrors/function.declaration.alpha rename to tests/given/test/function.declaration.alpha index 69f210f..9653a68 100644 --- a/tests/carl/NoErrors/function.declaration.alpha +++ b/tests/given/test/function.declaration.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-asc -tc] type M : integer -> integer function f : M diff --git a/tests/carl/NoErrors/function.definition.alpha b/tests/given/test/function.definition.alpha similarity index 78% rename from tests/carl/NoErrors/function.definition.alpha rename to tests/given/test/function.definition.alpha index b729610..72f1f68 100644 --- a/tests/carl/NoErrors/function.definition.alpha +++ b/tests/given/test/function.definition.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-asc -tc] type M : integer -> integer function f : M diff --git a/tests/carl/NoErrors/functionValue.alpha b/tests/given/test/functionValue.alpha similarity index 98% rename from tests/carl/NoErrors/functionValue.alpha rename to tests/given/test/functionValue.alpha index c1134ce..85158c7 100644 --- a/tests/carl/NoErrors/functionValue.alpha +++ b/tests/given/test/functionValue.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-asc -tc] (* Type definitions *) (* mapping type *) diff --git a/tests/carl/NoErrors/sample.good.alpha b/tests/given/test/sample.good.alpha similarity index 96% rename from tests/carl/NoErrors/sample.good.alpha rename to tests/given/test/sample.good.alpha index 8a8b727..54c4ae6 100644 --- a/tests/carl/NoErrors/sample.good.alpha +++ b/tests/given/test/sample.good.alpha @@ -1,4 +1,4 @@ - +$$ TEST: [-asc -tc] (* Type definitions *) type int2int: integer -> integer type string2int: string -> integer diff --git a/tests/carl/NoErrors/selectionSort.alpha b/tests/given/test/selectionSort.alpha similarity index 98% rename from tests/carl/NoErrors/selectionSort.alpha rename to tests/given/test/selectionSort.alpha index 24fb000..d785542 100644 --- a/tests/carl/NoErrors/selectionSort.alpha +++ b/tests/given/test/selectionSort.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-asc -tc] (* Type definitions *) type string2int: string -> integer diff --git a/tests/carl/NoErrors/type.array.alpha b/tests/given/test/type.array.alpha similarity index 52% rename from tests/carl/NoErrors/type.array.alpha rename to tests/given/test/type.array.alpha index 2b04ba0..ef76679 100644 --- a/tests/carl/NoErrors/type.array.alpha +++ b/tests/given/test/type.array.alpha @@ -1 +1,2 @@ +$$ TEST: [-asc -tc] type A : 1 -> integer diff --git a/tests/carl/NoErrors/type.mapping.alpha b/tests/given/test/type.mapping.alpha similarity index 60% rename from tests/carl/NoErrors/type.mapping.alpha rename to tests/given/test/type.mapping.alpha index 8b6bc50..37c1037 100644 --- a/tests/carl/NoErrors/type.mapping.alpha +++ b/tests/given/test/type.mapping.alpha @@ -1,2 +1,3 @@ +$$ TEST: [-asc -tc] type M : integer -> character diff --git a/tests/carl/NoErrors/type.record.alpha b/tests/given/test/type.record.alpha similarity index 67% rename from tests/carl/NoErrors/type.record.alpha rename to tests/given/test/type.record.alpha index 2c5e9c9..4a08b73 100644 --- a/tests/carl/NoErrors/type.record.alpha +++ b/tests/given/test/type.record.alpha @@ -1 +1,2 @@ +$$ TEST: [-asc -tc] type R : [ integer : i ; character : c ] diff --git a/tests/carl/NoErrors/types.alpha b/tests/given/test/types.alpha similarity index 99% rename from tests/carl/NoErrors/types.alpha rename to tests/given/test/types.alpha index 0402f95..d4947d7 100644 --- a/tests/carl/NoErrors/types.alpha +++ b/tests/given/test/types.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-asc -tc] (* At compiler start-up your program should diff --git a/tests/sprint1/expected/sp1_comment_fix1.expected b/tests/sprint1/expected/sp1_comment_fix1.tok.exp similarity index 100% rename from tests/sprint1/expected/sp1_comment_fix1.expected rename to tests/sprint1/expected/sp1_comment_fix1.tok.exp diff --git a/tests/sprint1/expected/sp1_comment_fix2.expected b/tests/sprint1/expected/sp1_comment_fix2.tok.exp similarity index 100% rename from tests/sprint1/expected/sp1_comment_fix2.expected rename to tests/sprint1/expected/sp1_comment_fix2.tok.exp diff --git a/tests/sprint1/expected/sp1_comment_issues.expected b/tests/sprint1/expected/sp1_comment_issues.tok.exp similarity index 100% rename from tests/sprint1/expected/sp1_comment_issues.expected rename to tests/sprint1/expected/sp1_comment_issues.tok.exp diff --git a/tests/sprint1/expected/sp1_comments.expected b/tests/sprint1/expected/sp1_comments.tok.exp similarity index 100% rename from tests/sprint1/expected/sp1_comments.expected rename to tests/sprint1/expected/sp1_comments.tok.exp diff --git a/tests/sprint1/expected/sp1_general_token.expected b/tests/sprint1/expected/sp1_general_token.tok.exp similarity index 100% rename from tests/sprint1/expected/sp1_general_token.expected rename to tests/sprint1/expected/sp1_general_token.tok.exp diff --git a/tests/sprint1/expected/sp1_keywords.expected b/tests/sprint1/expected/sp1_keywords.expected deleted file mode 100644 index 9e70321..0000000 --- a/tests/sprint1/expected/sp1_keywords.expected +++ /dev/null @@ -1,29 +0,0 @@ -1 1 401 "while" -2 1 101 "While" -3 1 101 "whiLe" -4 1 402 "if" -5 1 101 "IF" -6 1 101 "If" -7 1 101 "iF" -8 1 403 "then" -9 1 101 "Then" -10 1 101 "theN" -11 1 404 "else" -12 1 101 "eLse" -13 1 101 "elSe" -14 1 101 "Else" -15 1 405 "type" -16 1 101 "Type" -17 1 101 "tyPe" -18 1 406 "function" -19 1 101 "Function" -20 1 101 "functioN" -21 1 407 "return" -22 1 101 "Return" -23 1 101 "returN" -24 1 408 "external" -25 1 101 "External" -26 1 101 "exteRnal" -27 1 409 "as" -28 1 101 "As" -29 1 101 "aS" diff --git a/tests/sprint1/expected/sp1_operators.expected b/tests/sprint1/expected/sp1_operators.expected deleted file mode 100644 index dd3eaab..0000000 --- a/tests/sprint1/expected/sp1_operators.expected +++ /dev/null @@ -1,22 +0,0 @@ -1 1 601 "+" -2 1 602 "-" -3 1 603 "*" -4 1 604 "/" -6 1 605 "%" -7 1 606 "<" -9 1 607 "=" -10 1 608 ":=" -11 1 607 "=" -11 2 508 ":" -12 1 508 ":" -13 1 607 "=" -14 1 609 "!" -15 1 610 "&" -16 1 611 "|" -17 1 612 "." -18 1 101 "relEASE" -19 1 614 "release" -20 1 101 "RELEASE" -21 1 613 "reserve" -22 1 101 "RESERVE" -23 1 101 "reSERVe" diff --git a/tests/sprint1/expected/sp1_other_punc.expected b/tests/sprint1/expected/sp1_other_punc.expected deleted file mode 100644 index 7500378..0000000 --- a/tests/sprint1/expected/sp1_other_punc.expected +++ /dev/null @@ -1,7 +0,0 @@ -1 1 507 ";" -2 1 508 ":" -3 1 509 "," -4 1 510 "->" -5 1 510 "->" -6 1 602 "-" -6 2 510 "->" diff --git a/tests/sprint1/expected/sp1_punc_grouping.expected b/tests/sprint1/expected/sp1_punc_grouping.expected deleted file mode 100644 index c58a316..0000000 --- a/tests/sprint1/expected/sp1_punc_grouping.expected +++ /dev/null @@ -1,59 +0,0 @@ -1 1 502 ")" -2 1 101 "a" -2 2 502 ")" -3 1 502 ")" -3 2 101 "a" -4 1 502 ")" -4 2 603 "*" -5 1 603 "*" -5 2 502 ")" -7 1 700 "(* jellsls - well this seems to work - - - *)" -13 1 501 "(" -14 1 101 "a" -14 2 501 "(" -15 1 501 "(" -15 2 101 "a" -16 1 501 "(" -16 2 603 "*" -17 1 603 "*" -17 2 501 "(" -20 1 505 "{" -21 1 101 "a" -21 2 505 "{" -22 1 505 "{" -22 2 101 "a" -23 1 505 "{" -23 2 603 "*" -24 1 603 "*" -24 2 505 "{" -25 1 506 "}" -26 1 101 "a" -26 2 506 "}" -27 1 506 "}" -27 2 101 "a" -28 1 506 "}" -28 2 603 "*" -29 1 603 "*" -29 2 506 "}" -33 1 503 "[" -34 1 101 "a" -34 2 503 "[" -35 1 503 "[" -35 2 101 "a" -36 1 503 "[" -36 2 603 "*" -37 1 603 "*" -37 2 503 "[" -38 1 504 "]" -39 1 101 "a" -39 2 504 "]" -40 1 504 "]" -40 2 101 "a" -41 1 504 "]" -41 2 603 "*" -42 1 603 "*" -42 2 504 "]" diff --git a/tests/sprint1/expected/sp1_real_alpha_file1.expected b/tests/sprint1/expected/sp1_real_alpha_file1.expected deleted file mode 100644 index cc3f2c9..0000000 --- a/tests/sprint1/expected/sp1_real_alpha_file1.expected +++ /dev/null @@ -1,145 +0,0 @@ -1 1 405 "type" -1 6 101 "rec" -1 9 508 ":" -1 11 503 "[" -1 12 201 "integer" -1 19 508 ":" -1 21 101 "x" -1 22 507 ";" -1 24 201 "integer" -1 31 508 ":" -1 33 101 "y" -1 34 504 "]" -2 1 405 "type" -2 6 101 "T1" -2 8 508 ":" -2 10 201 "integer" -2 18 510 "->" -2 21 201 "integer" -3 1 405 "type" -3 6 101 "T2" -3 8 508 ":" -3 10 101 "rec" -3 14 510 "->" -3 17 201 "integer" -4 1 406 "function" -4 10 101 "foo" -4 14 508 ":" -4 16 101 "T1" -5 1 406 "function" -5 10 101 "bar1" -5 15 508 ":" -5 17 101 "T2" -6 1 406 "function" -6 10 101 "bar2" -6 15 508 ":" -6 17 101 "T2" -7 1 101 "foo" -7 4 501 "(" -7 5 101 "x" -7 6 502 ")" -7 8 608 ":=" -7 11 505 "{" -8 2 407 "return" -8 9 101 "x" -8 11 603 "*" -8 13 101 "x" -8 14 507 ";" -9 9 506 "}" -10 1 101 "bar1" -10 5 501 "(" -10 6 101 "a" -10 7 502 ")" -10 9 608 ":=" -10 12 505 "{" -11 9 407 "return" -11 16 101 "a" -11 17 612 "." -11 18 101 "x" -11 20 603 "*" -11 22 101 "a" -11 23 612 "." -11 24 101 "y" -11 25 507 ";" -12 9 506 "}" -13 1 101 "bar2" -13 6 409 "as" -13 9 501 "(" -13 10 101 "r" -13 11 509 "," -13 12 101 "s" -13 13 502 ")" -13 15 608 ":=" -13 18 505 "{" -14 9 407 "return" -14 16 101 "r" -14 18 603 "*" -14 20 101 "s" -14 21 507 ";" -15 9 506 "}" -16 1 101 "entry" -16 6 501 "(" -16 7 101 "arg" -16 10 502 ")" -16 12 608 ":=" -16 15 505 "{" -17 9 503 "[" -17 11 201 "integer" -17 18 508 ":" -17 20 101 "result" -17 27 507 ";" -17 29 101 "rec" -17 32 508 ":" -17 34 101 "w" -17 35 504 "]" -18 9 101 "result" -18 16 608 ":=" -18 19 101 "foo" -18 22 501 "(" -18 23 301 "5" -18 24 502 ")" -18 25 507 ";" -19 9 101 "w" -19 11 608 ":=" -19 14 613 "reserve" -19 21 501 "(" -19 22 101 "w" -19 23 502 ")" -19 24 507 ";" -19 26 700 "(* see types.alpha – reserve returns a value of type address, - which can be assigned to array and record variables - *)" -22 9 101 "w" -22 10 612 "." -22 11 101 "x" -22 13 608 ":=" -22 16 301 "5" -22 17 507 ";" -23 9 101 "w" -23 10 612 "." -23 11 101 "y" -23 13 608 ":=" -23 16 301 "7" -23 17 507 ";" -24 9 101 "result" -24 16 608 ":=" -24 19 101 "bar1" -24 23 501 "(" -24 24 101 "w" -24 25 502 ")" -24 26 507 ";" -24 28 700 "(* pass w (a rec type value) to bar1 *)" -25 9 101 "result" -25 16 608 ":=" -25 19 101 "bar2" -25 23 501 "(" -25 24 301 "5" -25 25 509 "," -25 26 301 "7" -25 27 502 ")" -25 28 507 ";" -25 30 700 "(* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *)" -27 9 407 "return" -27 16 301 "0" -27 17 507 ";" -28 1 506 "}" diff --git a/tests/sprint1/expected/sp1_real_alpha_file2.expected b/tests/sprint1/expected/sp1_real_alpha_file2.expected deleted file mode 100644 index 90c34a2..0000000 --- a/tests/sprint1/expected/sp1_real_alpha_file2.expected +++ /dev/null @@ -1,100 +0,0 @@ -1 1 700 "(* Type definitions *)" -2 1 405 "type" -2 6 101 "string" -2 12 508 ":" -2 14 301 "1" -2 16 510 "->" -2 19 204 "character" -3 1 405 "type" -3 6 101 "int2int" -3 13 508 ":" -3 15 201 "integer" -3 23 510 "->" -3 26 201 "integer" -4 1 405 "type" -4 6 101 "string2int" -4 16 508 ":" -4 18 101 "string" -4 25 510 "->" -4 28 201 "integer" -5 1 700 "(* Function prototypes -They use the above type definitions -*)" -8 1 406 "function" -8 10 101 "square" -8 17 508 ":" -8 19 101 "int2int" -9 1 406 "function" -9 10 101 "entry" -9 16 508 ":" -9 18 101 "string2int" -10 1 700 "(* Function definition -Functions must be declared before they are defined -*)" -13 1 101 "square" -13 7 501 "(" -13 8 101 "x" -13 9 502 ")" -13 11 608 ":=" -13 14 505 "{" -14 1 407 "return" -14 8 101 "x" -14 10 603 "*" -14 12 101 "x" -14 13 507 ";" -15 1 506 "}" -16 1 700 "(* Function definition -entry is the first function called -*)" -19 1 101 "entry" -19 6 501 "(" -19 7 101 "arg" -19 10 502 ")" -19 12 608 ":=" -19 15 505 "{" -20 1 101 "input" -20 7 607 "=" -20 9 301 "7" -20 10 507 ";" -21 1 101 "expected" -21 10 607 "=" -21 12 301 "49" -21 14 507 ";" -22 1 101 "actual" -22 8 608 ":=" -22 11 101 "square" -22 17 501 "(" -22 18 101 "input" -22 23 502 ")" -22 24 507 ";" -23 1 101 "rseult" -23 8 608 ":=" -23 11 101 "expected" -23 20 607 "=" -23 22 101 "actual" -23 28 507 ";" -24 1 407 "return" -24 8 301 "0" -24 9 507 ";" -25 1 503 "[" -25 3 201 "integer" -25 10 508 ":" -25 12 101 "input" -25 17 507 ";" -25 19 201 "integer" -25 26 508 ":" -25 28 101 "expected" -25 36 507 ";" -25 38 201 "integer" -25 45 508 ":" -25 47 101 "actual" -25 53 507 ";" -25 55 101 "boolean" -25 62 508 ":" -25 64 101 "result" -25 70 507 ";" -25 72 101 "string" -25 78 508 ":" -25 80 101 "input" -25 86 504 "]" -26 1 506 "}" diff --git a/tests/sprint1/expected/sp1_simple_int.expected b/tests/sprint1/expected/sp1_simple_int.expected deleted file mode 100644 index 0bcbefb..0000000 --- a/tests/sprint1/expected/sp1_simple_int.expected +++ /dev/null @@ -1,8 +0,0 @@ -1 1 301 "45" -2 1 301 "123" -3 1 301 "8392" -4 1 301 "40" -4 4 301 "40" -5 2 301 "200" -5 6 301 "50" -5 9 301 "21783" diff --git a/tests/sprint1/expected/sp1_simple_literals.expected b/tests/sprint1/expected/sp1_simple_literals.expected deleted file mode 100644 index 788adc2..0000000 --- a/tests/sprint1/expected/sp1_simple_literals.expected +++ /dev/null @@ -1,64 +0,0 @@ -1 1 304 ""this is a string"" -1 20 301 "721398" -1 27 303 "'g'" -1 32 604 "/" -1 33 101 "n" -1 36 700 "(* should print 3 tokens before this *)" -4 1 301 "12893" -4 8 101 "this" -4 13 101 "is" -4 16 101 "not" -4 20 101 "a" -4 22 101 "string" -4 29 700 "(*one valid token before this*)" -5 1 700 "(* spacey comment here -over multiple lines -will it work? *)" -7 18 306 "false" -11 1 306 "false" -12 1 700 "(**)" -14 1 101 "nullfalse" -15 2 101 "nulltrue" -16 1 302 "null" -17 1 303 "'7'" -18 1 305 "true" -19 2 301 "189" -20 1 303 "'\t'" -21 1 303 "'"'" -22 1 303 "'/'" -23 1 303 "'\n'" -24 1 303 "'\''" -25 1 303 "'\t'" -26 1 303 "'\\'" -27 1 303 "'n'" -29 2 101 "fdsf" -30 1 700 "(*/jnewjno2893u86^ Lots of random characters /n /t '") *)" -35 1 304 ""STRINGwithnotSPaces"" -36 1 303 "' '" -38 1 304 ""J"" -39 1 304 """" -40 1 304 "" "" -42 1 304 ""{SCHAR}"" -43 1 304 ""SCHAR"" -44 1 304 ""[SCHAR]"" -45 1 304 ""FINAL: I'd think this is a legal \"string\" that contains \n \t several escaped characters, isn't it?"" -46 2 101 "I" -46 4 101 "d" -46 6 101 "think" -46 12 101 "this" -46 17 101 "is" -46 20 101 "a" -46 22 101 "legal" -46 30 101 "string" -46 39 101 "that" -46 44 101 "contains" -46 53 101 "several" -46 63 101 "n" -46 66 101 "t" -46 68 101 "escaped" -46 76 101 "characters" -46 86 509 "," -46 88 101 "isn" -46 92 101 "t" -46 94 101 "it" -47 1 101 "nullLike" diff --git a/tests/sprint1/expected/sp1_variables.expected b/tests/sprint1/expected/sp1_variables.expected deleted file mode 100644 index 223288a..0000000 --- a/tests/sprint1/expected/sp1_variables.expected +++ /dev/null @@ -1,13 +0,0 @@ -1 1 101 "valid1" -2 1 101 "Valid2" -3 1 101 "_valid3" -4 1 101 "_valid_name_4" -5 1 101 "VALID" -6 1 301 "0" -6 2 101 "Invalid" -7 1 301 "1" -7 2 101 "invalid" -8 2 101 "invalid" -9 1 101 "invalid" -9 8 607 "=" -10 1 101 "String" diff --git a/tests/sprint1/test/sp1_comment_fix1.alpha b/tests/sprint1/test/sp1_comment_fix1.alpha index 910a538..0f2ec67 100644 --- a/tests/sprint1/test/sp1_comment_fix1.alpha +++ b/tests/sprint1/test/sp1_comment_fix1.alpha @@ -1 +1,2 @@ +$$ TEST: [-tok] (***) \ No newline at end of file diff --git a/tests/sprint1/test/sp1_comment_fix2.alpha b/tests/sprint1/test/sp1_comment_fix2.alpha index bd710e9..72e5ffe 100644 --- a/tests/sprint1/test/sp1_comment_fix2.alpha +++ b/tests/sprint1/test/sp1_comment_fix2.alpha @@ -1 +1,2 @@ +$$ TEST: [-tok] (*(**)*) \ No newline at end of file diff --git a/tests/sprint1/test/sp1_comment_issues.alpha b/tests/sprint1/test/sp1_comment_issues.alpha index e968d93..45b244d 100644 --- a/tests/sprint1/test/sp1_comment_issues.alpha +++ b/tests/sprint1/test/sp1_comment_issues.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-tok] (*(**)*) (***) (******)(*\kpp*********) diff --git a/tests/sprint1/test/sp1_comments.alpha b/tests/sprint1/test/sp1_comments.alpha index 1111428..63f216b 100644 --- a/tests/sprint1/test/sp1_comments.alpha +++ b/tests/sprint1/test/sp1_comments.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-tok] (* hello *) (* hello *) (* I'd think this is a legal "string" that contains several \n \t diff --git a/tests/sprint1/test/sp1_general_token.alpha b/tests/sprint1/test/sp1_general_token.alpha index defc56b..dcb581f 100644 --- a/tests/sprint1/test/sp1_general_token.alpha +++ b/tests/sprint1/test/sp1_general_token.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-tok] This is a test 9combined 7okens 12345 diff --git a/tests/sprint1/test/sp1_keywords.alpha b/tests/sprint1/test/sp1_keywords.alpha index ff18168..8b76ac7 100644 --- a/tests/sprint1/test/sp1_keywords.alpha +++ b/tests/sprint1/test/sp1_keywords.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-tok] while While whiLe diff --git a/tests/sprint1/test/sp1_operators.alpha b/tests/sprint1/test/sp1_operators.alpha index b985387..eacaec4 100644 --- a/tests/sprint1/test/sp1_operators.alpha +++ b/tests/sprint1/test/sp1_operators.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-tok] + - * diff --git a/tests/sprint1/test/sp1_other_punc.alpha b/tests/sprint1/test/sp1_other_punc.alpha index bd1f2de..87bdb10 100644 --- a/tests/sprint1/test/sp1_other_punc.alpha +++ b/tests/sprint1/test/sp1_other_punc.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-tok] ; : , diff --git a/tests/sprint1/test/sp1_punc_grouping.alpha b/tests/sprint1/test/sp1_punc_grouping.alpha index 45dfb99..57df795 100644 --- a/tests/sprint1/test/sp1_punc_grouping.alpha +++ b/tests/sprint1/test/sp1_punc_grouping.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-tok] ) a) )a diff --git a/tests/sprint1/test/sp1_real_alpha_file1.alpha b/tests/sprint1/test/sp1_real_alpha_file1.alpha index 51d5d08..c7713be 100644 --- a/tests/sprint1/test/sp1_real_alpha_file1.alpha +++ b/tests/sprint1/test/sp1_real_alpha_file1.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-tok] type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer diff --git a/tests/sprint1/test/sp1_real_alpha_file2.alpha b/tests/sprint1/test/sp1_real_alpha_file2.alpha index 0beb2af..7fe7705 100644 --- a/tests/sprint1/test/sp1_real_alpha_file2.alpha +++ b/tests/sprint1/test/sp1_real_alpha_file2.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-tok] (* Type definitions *) type string: 1 -> character type int2int: integer -> integer diff --git a/tests/sprint1/test/sp1_simple_alpha.alpha b/tests/sprint1/test/sp1_simple_alpha.alpha index 719384b..2d8b2ce 100644 --- a/tests/sprint1/test/sp1_simple_alpha.alpha +++ b/tests/sprint1/test/sp1_simple_alpha.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-tok] type main: string -> integer function entry: main diff --git a/tests/sprint1/test/sp1_simple_int.alpha b/tests/sprint1/test/sp1_simple_int.alpha index 127f0a6..f712914 100644 --- a/tests/sprint1/test/sp1_simple_int.alpha +++ b/tests/sprint1/test/sp1_simple_int.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-tok] 45 123 8392 diff --git a/tests/sprint1/test/sp1_simple_literals.alpha b/tests/sprint1/test/sp1_simple_literals.alpha index 4c5b0b2..ce5b0bd 100644 --- a/tests/sprint1/test/sp1_simple_literals.alpha +++ b/tests/sprint1/test/sp1_simple_literals.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-tok] "this is a string" 721398 'g' '/n' (* should print 3 tokens before this *) ' ' diff --git a/tests/sprint1/test/sp1_variables.alpha b/tests/sprint1/test/sp1_variables.alpha index 26db6c0..ec787c6 100644 --- a/tests/sprint1/test/sp1_variables.alpha +++ b/tests/sprint1/test/sp1_variables.alpha @@ -1,3 +1,4 @@ +$$ TEST: [-tok] valid1 Valid2 _valid3 From 31bc69d52be7e2748155bf68e3357cefd80718a7 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Sat, 3 May 2025 19:29:38 -0400 Subject: [PATCH 036/109] It seems to be working but I need to ckeck again --- src/grammar.y | 114 +++++++++++++++++----- src/intermediate_code.c | 11 ++- src/intermediate_code.h | 1 + tests/sprint3/test/sp3_if_else_sse.alpha | 26 +++++ tests/sprint3/test/sp3_if_else_sse2.alpha | 29 ++++++ tests/sprint3/test/sp3_while_sse.alpha | 27 +++++ 6 files changed, 181 insertions(+), 27 deletions(-) create mode 100644 tests/sprint3/test/sp3_if_else_sse.alpha create mode 100644 tests/sprint3/test/sp3_if_else_sse2.alpha create mode 100644 tests/sprint3/test/sp3_while_sse.alpha diff --git a/src/grammar.y b/src/grammar.y index 7de731e..b2cc77b 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -578,23 +578,8 @@ compound_statement: S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); }expression R_PAREN THEN { - emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $4)); - 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); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); - } sblock ELSE { // NOTE we are not going back to int l = label_gen(); @@ -868,11 +853,47 @@ expression: | expression AND expression { +// ---------------------------------------------------------------------------- + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $1)); + Stack * t1 = S_Peek(TrueList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(TrueList, t1, 1); + } + S_Push(t1, current, 1); + emit_goto(0); + t1 = S_Peek(FalseList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(FalseList, t1, 1); + } + S_Push(t1, current, 1); + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); + + emit_conditional_jump(E_IF_X_TRUE, 0, 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); + S_Merge(FalseList); + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); +// ---------------------------------------------------------------------------- printdebug("AND"); + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { - char* temp = temp_var_gen(); - TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - emit_binary_op(E_AND,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); + //emit_binary_op(E_AND,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -882,11 +903,47 @@ expression: | expression OR expression { +// ---------------------------------------------------------------------------- + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $1)); + Stack * t1 = S_Peek(TrueList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(TrueList, t1, 1); + } + S_Push(t1, current, 1); + emit_goto(0); + t1 = S_Peek(FalseList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(FalseList, t1, 1); + } + S_Push(t1, current, 1); + emit_label(label_gen()); + emit_backpatch(S_Pop(FalseList), getLabel(current)); + + emit_conditional_jump(E_IF_X_TRUE, 0, 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); + S_Merge(TrueList); + // This is very inportant. + // With OR W DO NOT BP THE TRUELIST Only with AND +// ---------------------------------------------------------------------------- printdebug("OR"); if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - emit_binary_op(E_OR,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); + // emit_binary_op(E_OR,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -896,11 +953,10 @@ expression: | expression LESS_THAN expression { -// ---------------------------------------------------------------------------- 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)); - /* emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); if(t==NULL){ @@ -915,6 +971,9 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); + // emit_label(label_gen()); + // emit_backpatch(S_Pop(TrueList), getLabel(current)); + /* */ // ---------------------------------------------------------------------------- printdebug("less than expression"); @@ -930,13 +989,11 @@ expression: | expression EQUAL_TO expression { - printdebug("equals check 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)); + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); if(t==NULL){ t = S_Init(); @@ -950,7 +1007,12 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); - */ + // emit_label(label_gen()); + // emit_backpatch(S_Pop(TrueList), getLabel(current)); +// ---------------------------------------------------------------------------- + printdebug("equals check expression"); + if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1) != undefined) { + // emit_binary_op(E_EQUAL_TO, node, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); $$ = node; } else { diff --git a/src/intermediate_code.c b/src/intermediate_code.c index c807096..62fb563 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -58,7 +58,16 @@ int S_Size(Stack *s){ return s->size; } -void S_Merge(Stack *s1, Stack *s2){ +void S_Merge(Stack *list){ + Stack* s1 = S_Pop(list); + Stack* s2 = S_Peek(list); + if(s1 == NULL){ + return; + } + if(s2 == NULL){ + S_Push(list, s1, 0); + return; + } for (Instruction * i = S_Pop(s1); i; i = S_Pop(s1)){ S_Push(s2, i, 1); } diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 0906cb1..4e241fe 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -32,6 +32,7 @@ void * S_Pop(Stack *s); void * S_Peek(Stack *s); bool S_IsEmpty(Stack *s); int S_Size(Stack *s); +void S_Merge(Stack *list); //______________________________________________________________________________________________ typedef union TNConstUnion TNConstUnion; diff --git a/tests/sprint3/test/sp3_if_else_sse.alpha b/tests/sprint3/test/sp3_if_else_sse.alpha new file mode 100644 index 0000000..24ec9ee --- /dev/null +++ b/tests/sprint3/test/sp3_if_else_sse.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) := { + [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] + if ( !( x < y ) & ( z & t ) ) then { + (* if ( result < w.y ) then { + result := 8; + } else { + result := 9; + } *) + z := t; + } else { + y := true; (* bar('c', 7); *) + } + return 0; +} diff --git a/tests/sprint3/test/sp3_if_else_sse2.alpha b/tests/sprint3/test/sp3_if_else_sse2.alpha new file mode 100644 index 0000000..c26ce11 --- /dev/null +++ b/tests/sprint3/test/sp3_if_else_sse2.alpha @@ -0,0 +1,29 @@ +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) := { + [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] + if ( y & z | t ) then { + (* if ( ( x < y ) & ( z = t ) ) then { + y := z < t; + t:= 0; + } else { + t := z = t; + z := 1; + } *) + t := true; + } else { + y := true; (* bar('c', 7); *) + } + (* x := x & y; *) + return 0; +} diff --git a/tests/sprint3/test/sp3_while_sse.alpha b/tests/sprint3/test/sp3_while_sse.alpha new file mode 100644 index 0000000..89fa23f --- /dev/null +++ b/tests/sprint3/test/sp3_while_sse.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) := { + [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] + while ( !( x & y ) (* | ( z | t ) *) ) { + (* + if ( ( x < y ) & ( z = t ) ) then { + y := z < t; + } else { + t := z = t; + } + *) + y := true; (* bar('c', 7); *) + } + (* x := x & y; *) + return 0; +} From 5d520645fd5bfd1a1a8abad1969a7b400ef1a6aa Mon Sep 17 00:00:00 2001 From: Annie Date: Sat, 3 May 2025 20:38:12 -0400 Subject: [PATCH 037/109] may have function calls, need to merge other stuff to check --- src/codegen.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 806972e..79a489c 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -663,19 +663,20 @@ int generateParam(Instruction *inst){ } fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#adding param start\n", getAddress(op1CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#adding param end\n", offset += 8); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#adding param end\n", getPrimSize(getTypeEntry(tn))); return 0; } int generateFunctionStart(Instruction *inst) { - TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op1 = getResult(inst); if (op1 == NULL) { printdebug("%sgenerateFunctionStart failed, NULL operand", COLOR_RED); return -1; } - + + TableNode *funDecTN = getTN(op1); if (getTN(op1) == NULL) { printdebug("generateFunctionStart failed, NULL tablenode"); return -1; @@ -686,6 +687,30 @@ int generateFunctionStart(Instruction *inst) { fprintf(cg_flag, "\tpushq\t%%rbp\n"); fprintf(cg_flag, "\tmovq\t%%rsp, %%rbp\n"); - //now we need to add the CGs of nodes to the CG list by doing assign from the + //now we need to add the CGs of nodes to the CG list by doing assign from the + // have function declararation node + //declaration ->getType: if record, go through each element and load param from stack and store to correct tn cg + // if not, go get one element of type of param + //declaration ->getType->getDefinitionScope?: go through first n entries to get table nodes for params + + TableNode *paramTN = getParameter(funDecTN); + SymbolTable *st = getFunScope(funDecTN); + int paramOffset = -16; + if (getAdInfoType(paramTN) != TYPE_RECORD) { + CGNode *paramCG = addCG(tn, currentsp); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getPrimSize(getTypeEntry(paramTN))); + } else { + int numParams = getRecLength(paramTN); + TableNode *tnToAdd = getFirstEntry(st); + for (int i = 0; i < numParams; i++) { + CGNode *paramCG = addCG(tnTooAdd, currentsp); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getPrimSize(getTypeEntry(paramTN))); + paramoffset -= getPrimSize(getTypeEntry(tnToAdd)); + tnToAdd = getNextEntry(tnToAdd); + } + } + return 0; } From 3e1c510c68c068ca3137cd3b1240dba245ff390e Mon Sep 17 00:00:00 2001 From: Annie Date: Sat, 3 May 2025 21:14:24 -0400 Subject: [PATCH 038/109] seems to work for records, but the offsets are wrong (1) --- src/codegen.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 79a489c..a3c4dff 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -663,27 +663,21 @@ int generateParam(Instruction *inst){ } fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#adding param start\n", getAddress(op1CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#adding param end\n", getPrimSize(getTypeEntry(tn))); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#adding param end\n", getPrimSize(getTypeEntry(getTN(op1)))); return 0; } int generateFunctionStart(Instruction *inst) { - TNodeOrConst *op1 = getResult(inst); + TableNode *funDecTN = getResult(inst); - if (op1 == NULL) { - printdebug("%sgenerateFunctionStart failed, NULL operand", COLOR_RED); - return -1; - } - - TableNode *funDecTN = getTN(op1); - if (getTN(op1) == NULL) { + if (funDecTN == NULL) { printdebug("generateFunctionStart failed, NULL tablenode"); return -1; } //this is independent of parameters: - fprintf(cg_flag, "%s:\n", getName(getTN(op1))); + fprintf(cg_flag, "%s:\n", getName(funDecTN)); fprintf(cg_flag, "\tpushq\t%%rbp\n"); fprintf(cg_flag, "\tmovq\t%%rsp, %%rbp\n"); @@ -693,21 +687,23 @@ int generateFunctionStart(Instruction *inst) { // if not, go get one element of type of param //declaration ->getType->getDefinitionScope?: go through first n entries to get table nodes for params - TableNode *paramTN = getParameter(funDecTN); + TableNode *paramTN = getParameter(getTypeEntry(funDecTN)); SymbolTable *st = getFunScope(funDecTN); - int paramOffset = -16; - if (getAdInfoType(paramTN) != TYPE_RECORD) { - CGNode *paramCG = addCG(tn, currentsp); + int paramOffset = 16; + if (getAdInfoType(paramTN) != TYPE_RECORD_TYPE) { + fprintf(stderr, "%d\n", getAdInfoType(funDecTN)); + CGNode *paramCG = addCG(paramTN, currentsp); fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getPrimSize(getTypeEntry(paramTN))); } else { + fprintf(stderr, "record type\n"); int numParams = getRecLength(paramTN); TableNode *tnToAdd = getFirstEntry(st); for (int i = 0; i < numParams; i++) { - CGNode *paramCG = addCG(tnTooAdd, currentsp); + CGNode *paramCG = addCG(tnToAdd, currentsp); fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getPrimSize(getTypeEntry(paramTN))); - paramoffset -= getPrimSize(getTypeEntry(tnToAdd)); + paramOffset += getPrimSize(getTypeEntry(tnToAdd)); tnToAdd = getNextEntry(tnToAdd); } } From 9d98b75bc0fd041a4e123be3612228c4e953beee Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Sun, 4 May 2025 14:30:04 -0400 Subject: [PATCH 039/109] I think it was broken so I fixed it --- src/grammar.y | 73 +++++++------------ tests/sprint3/test/sp3_if_else_sse.alpha | 17 +++-- tests/sprint3/test/sp3_if_else_sse2.alpha | 23 +++--- .../sprint3/test/sp3_while_nested_bools.alpha | 10 +-- 4 files changed, 57 insertions(+), 66 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index b2cc77b..c190783 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -550,21 +550,6 @@ compound_statement: emit_label(*l); S_Push(stack, l, 2); } expression R_PAREN { - emit_backpatch(S_Pop(TrueList), getLabel(current)); - emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $4)); - 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); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); } sblock { @@ -854,40 +839,40 @@ expression: | expression AND expression { // ---------------------------------------------------------------------------- - emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $1)); - Stack * t1 = S_Peek(TrueList); - if(t1==NULL){ - t1 = S_Init(); - S_Push(TrueList, t1, 1); - } - S_Push(t1, current, 1); - emit_goto(0); - t1 = S_Peek(FalseList); + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); + emit_conditional_jump(E_IF_X_FALSE, 0, tn_or_const(NODE, $1)); + Stack * t1 = S_Peek(FalseList); if(t1==NULL){ t1 = S_Init(); S_Push(FalseList, t1, 1); } S_Push(t1, current, 1); + emit_goto(0); + t1 = S_Peek(TrueList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(TrueList, t1, 1); + } + S_Push(t1, current, 1); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); - - emit_conditional_jump(E_IF_X_TRUE, 0, 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); + emit_conditional_jump(E_IF_X_FALSE, 0, tn_or_const(NODE, $3)); + Stack * t = S_Peek(FalseList); if(t==NULL){ t = S_Init(); S_Push(FalseList, t, 1); } S_Push(t, current, 1); + + emit_goto(0); + t = S_Peek(TrueList); + if(t==NULL){ + t = S_Init(); + S_Push(TrueList, t, 1); + } + S_Push(t, current, 1); S_Merge(FalseList); - emit_label(label_gen()); - emit_backpatch(S_Pop(TrueList), getLabel(current)); // ---------------------------------------------------------------------------- printdebug("AND"); char* temp = temp_var_gen(); @@ -904,6 +889,8 @@ expression: | expression OR expression { // ---------------------------------------------------------------------------- + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $1)); Stack * t1 = S_Peek(TrueList); if(t1==NULL){ @@ -920,7 +907,6 @@ expression: S_Push(t1, current, 1); emit_label(label_gen()); emit_backpatch(S_Pop(FalseList), getLabel(current)); - emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $3)); Stack * t = S_Peek(TrueList); if(t==NULL){ @@ -936,14 +922,11 @@ expression: } S_Push(t, current, 1); S_Merge(TrueList); - // This is very inportant. - // With OR W DO NOT BP THE TRUELIST Only with AND // ---------------------------------------------------------------------------- printdebug("OR"); if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - // emit_binary_op(E_OR,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -956,6 +939,8 @@ expression: char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); // ---------------------------------------------------------------------------- + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_binary_op(E_LESS_THAN, node, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); @@ -971,10 +956,6 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); - // emit_label(label_gen()); - // emit_backpatch(S_Pop(TrueList), getLabel(current)); - /* - */ // ---------------------------------------------------------------------------- printdebug("less than expression"); if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==integ) { @@ -992,6 +973,8 @@ expression: char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); // ---------------------------------------------------------------------------- + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_binary_op(E_EQUAL_TO, node, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); @@ -1007,8 +990,6 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); - // emit_label(label_gen()); - // emit_backpatch(S_Pop(TrueList), getLabel(current)); // ---------------------------------------------------------------------------- printdebug("equals check expression"); if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1) != undefined) { diff --git a/tests/sprint3/test/sp3_if_else_sse.alpha b/tests/sprint3/test/sp3_if_else_sse.alpha index 24ec9ee..f5d7d79 100644 --- a/tests/sprint3/test/sp3_if_else_sse.alpha +++ b/tests/sprint3/test/sp3_if_else_sse.alpha @@ -6,19 +6,24 @@ type main: string -> integer function entry: main function bar: T2 + (* bar (r,s) := { return 0; } + *) entry (arg) := { [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] - if ( !( x < y ) & ( z & t ) ) then { - (* if ( result < w.y ) then { - result := 8; + if ( ( x < y ) (* < ( z & t )*)) then { + + (* + if ( x Date: Sun, 4 May 2025 15:13:48 -0400 Subject: [PATCH 040/109] added extra case for get prim size --- src/symbol_table.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/symbol_table.c b/src/symbol_table.c index f4fa1ea..e1a63aa 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -116,6 +116,10 @@ int getPrimSize(TableNode *definition) { "Invalid."); return -1; } + if(getAdInfoType(definition) == TYPE_ARRAY_TYPE){ + //special case to return size for reference to an array + return 8; + } if (definition->additionalinfo == NULL) { printdebug("node has NULL additionalinfo. Invalid."); return -1; From 6d6beda20efb21528da8771aa8862d1a39a3e54a Mon Sep 17 00:00:00 2001 From: Partho Date: Sun, 4 May 2025 15:17:40 -0400 Subject: [PATCH 041/109] added more extra cases for get prim size --- src/symbol_table.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/symbol_table.c b/src/symbol_table.c index e1a63aa..139785a 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -120,6 +120,14 @@ int getPrimSize(TableNode *definition) { //special case to return size for reference to an array return 8; } + if(getAdInfoType(definition) == TYPE_FUNCTION_TYPE){ + //special case to return size for reference to a function + return 8; + } + if(getAdInfoType(definition) == TYPE_RECORD_TYPE){ + //special case to return size for reference to a record + return getRecTotal(definition); + } if (definition->additionalinfo == NULL) { printdebug("node has NULL additionalinfo. Invalid."); return -1; From a61d0a57e8b6d69453d11e7dcc8892edd5cc7ce9 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Sun, 4 May 2025 16:05:13 -0400 Subject: [PATCH 042/109] test updates woooo --- check.sh | 67 -------- src/symbol_table.c | 8 + test.sh | 74 +++++---- .../given/expected/entry.definition.alpha.asc | 10 ++ .../entry.duplicateDifferent.alpha.asc | 13 ++ .../expected/entry.duplicateSame.alpha.asc | 11 ++ tests/given/expected/entry.local.alpha.asc | 13 ++ .../error.entry.undeclaredType.alpha.asc | 16 ++ .../error.entry.undeclaredVar.alpha.asc | 12 ++ tests/given/expected/error.none.alpha.asc | 16 ++ tests/given/expected/error.operator.alpha.asc | 19 +++ .../expected/function.declaration.alpha.asc | 5 + .../expected/function.definition.alpha.asc | 9 ++ tests/given/expected/functionValue.alpha.asc | 75 +++++++++ tests/given/expected/sample.good.alpha.asc | 31 ++++ tests/given/expected/selectionSort.alpha.asc | 70 +++++++++ tests/given/expected/type.array.alpha.asc | 3 + tests/given/expected/type.mapping.alpha.asc | 4 + tests/given/expected/type.record.alpha.asc | 3 + tests/given/expected/types.alpha.asc | 77 ++++++++++ tests/given/test/entry.definition.alpha | 2 +- .../given/test/entry.duplicateDifferent.alpha | 2 +- tests/given/test/entry.duplicateSame.alpha | 2 +- tests/given/test/entry.local.alpha | 2 +- .../test/error.entry.undeclaredType.alpha | 11 ++ .../test/error.entry.undeclaredVar.alpha | 8 + tests/given/test/error.none.alpha | 2 +- tests/given/test/error.operator.alpha | 15 ++ tests/given/test/function.declaration.alpha | 2 +- tests/given/test/function.definition.alpha | 2 +- tests/given/test/functionValue.alpha | 7 +- tests/given/test/sample.good.alpha | 3 +- tests/given/test/selectionSort.alpha | 6 +- tests/given/test/type.array.alpha | 2 +- tests/given/test/type.mapping.alpha | 2 +- tests/given/test/type.record.alpha | 2 +- tests/given/test/types.alpha | 2 +- tests/sprint1/expected/sp1_keywords.tok.exp | 29 ++++ tests/sprint1/expected/sp1_operators.tok.exp | 22 +++ tests/sprint1/expected/sp1_other_punc.tok.exp | 7 + .../expected/sp1_punc_grouping.tok.exp | 59 +++++++ .../expected/sp1_real_alpha_file1.tok.exp | 145 ++++++++++++++++++ .../expected/sp1_real_alpha_file2.tok.exp | 100 ++++++++++++ .../sprint1/expected/sp1_simple_alpha.tok.exp | 20 +++ tests/sprint1/expected/sp1_simple_int.tok.exp | 8 + .../expected/sp1_simple_literals.tok.exp | 64 ++++++++ tests/sprint1/expected/sp1_variables.tok.exp | 13 ++ tests/sprint1/test/sp1_comment_fix1.alpha | 2 +- tests/sprint1/test/sp1_comment_fix2.alpha | 2 +- tests/sprint1/test/sp1_comment_issues.alpha | 2 +- tests/sprint1/test/sp1_comments.alpha | 2 +- tests/sprint1/test/sp1_general_token.alpha | 2 +- tests/sprint1/test/sp1_keywords.alpha | 2 +- tests/sprint1/test/sp1_operators.alpha | 2 +- tests/sprint1/test/sp1_other_punc.alpha | 2 +- tests/sprint1/test/sp1_punc_grouping.alpha | 2 +- tests/sprint1/test/sp1_real_alpha_file1.alpha | 2 +- tests/sprint1/test/sp1_real_alpha_file2.alpha | 2 +- tests/sprint1/test/sp1_simple_alpha.alpha | 2 +- tests/sprint1/test/sp1_simple_int.alpha | 2 +- tests/sprint1/test/sp1_simple_literals.alpha | 2 +- tests/sprint1/test/sp1_variables.alpha | 2 +- ...take.expected => sp2_carls_mistake.st.exp} | 30 ++-- ...pes.expected => sp2_function_types.st.exp} | 42 ++--- ....expected => sp2_integer_binary_op.st.exp} | 22 +-- ... sp2_invalid_multiple_params_no_as.st.exp} | 14 +- ...ecop.expected => sp2_invalid_recop.st.exp} | 16 +- ...se.expected => sp2_invalid_release.st.exp} | 10 +- ...p2_library.expected => sp2_library.st.exp} | 49 +++--- tests/sprint2/expected/sp2_llnode.st.exp | 58 +++++++ ..._llnode.expected => sp2_llnode_bad.st.exp} | 56 +++---- ..._one_line.expected => sp2_one_line.st.exp} | 24 +-- ...sidence.expected => sp2_presidence.st.exp} | 22 +-- ...{sp2_simple.expected => sp2_simple.st.exp} | 12 +- ...args.expected => sp2_sp2_arrayargs.st.exp} | 13 +- .../sp2_valid_assignable_and_mem.expected | 21 --- .../sp2_valid_assignable_and_mem.st.exp} | 14 +- tests/sprint2/test/sp2_carls_mistake.alpha | 1 + tests/sprint2/test/sp2_function_types.alpha | 1 + .../sprint2/test/sp2_integer_binary_op.alpha | 1 + .../sp2_invalid_multiple_params_no_as.alpha | 1 + tests/sprint2/test/sp2_invalid_recop.alpha | 1 + tests/sprint2/test/sp2_invalid_release.alpha | 1 + tests/sprint2/test/sp2_library.alpha | 1 + tests/sprint2/test/sp2_llnode.alpha | 1 + tests/sprint2/test/sp2_llnode_bad.alpha | 1 + tests/sprint2/test/sp2_one_line.alpha | 1 + tests/sprint2/test/sp2_presidence.alpha | 1 + tests/sprint2/test/sp2_simple.alpha | 1 + tests/sprint2/test/sp2_sp2_arrayargs.alpha | 1 + tests/sprint2/test/sp2_sp2_arrayargs.alpha~ | 16 -- .../test/sp2_valid_assignable_and_mem.alpha | 3 +- .../expected/sp3_and_or_type_check.asc.exp | 92 +++++++++++ .../expected/sp3_and_or_type_check.expected | 50 ------ .../sp3_boolean_binary_op_typecheck.asc.exp | 17 ++ .../sp3_boolean_binary_op_typecheck.expected | 16 -- ...=> sp3_boolean_unary_op_typecheck.asc.exp} | 4 +- .../expected/sp3_carls_second_mistake.asc.exp | 36 +++++ .../sp3_carls_second_mistake.expected | 20 --- tests/sprint3/expected/sp3_if_else.asc.exp | 25 +++ tests/sprint3/expected/sp3_if_while.asc.exp | 27 ++++ .../sp3_integer_binary_op_typecheck.asc.exp | 28 ++++ .../sp3_integer_binary_op_typecheck.expected | 25 --- ...=> sp3_integer_unary_op_typecheck.asc.exp} | 4 +- .../expected/sp3_multiple_args.asc.exp | 23 +++ .../expected/sp3_multiple_args.expected | 25 --- .../expected/sp3_primitive_type_check.asc.exp | 23 +++ .../expected/sp3_record_size_check.asc.exp | 3 + .../expected/sp3_record_size_check.expected | 29 ---- .../sprint3/test/sp3_and_or_type_check.alpha | 1 + .../sp3_boolean_binary_op_typecheck.alpha | 1 + .../test/sp3_boolean_unary_op_typecheck.alpha | 1 + .../test/sp3_carls_second_mistake.alpha | 1 + tests/sprint3/test/sp3_if_else.alpha | 1 + tests/sprint3/test/sp3_if_while.alpha | 1 + .../sp3_integer_binary_op_typecheck.alpha | 1 + .../test/sp3_integer_unary_op_typecheck.alpha | 1 + tests/sprint3/test/sp3_multiple_args.alpha | 1 + .../test/sp3_primitive_type_check.alpha | 1 + .../sprint3/test/sp3_record_size_check.alpha | 1 + tests/sprint4/expected/sp4_cg_add.asc.exp | 10 ++ tests/sprint4/expected/sp4_cg_add.ir.exp | 8 + .../{sp4_cg_add.expected => sp4_cg_add.s.exp} | 0 tests/sprint4/expected/sp4_cg_and.asc.exp | 10 ++ tests/sprint4/expected/sp4_cg_and.expected | 20 --- tests/sprint4/expected/sp4_cg_and.ir.exp | 9 ++ tests/sprint4/expected/sp4_cg_and.s.exp | 20 +++ tests/sprint4/expected/sp4_cg_div.asc.exp | 10 ++ tests/sprint4/expected/sp4_cg_div.ir.exp | 8 + .../{sp4_cg_div.expected => sp4_cg_div.s.exp} | 0 .../sprint4/expected/sp4_cg_equal_to.asc.exp | 10 ++ tests/sprint4/expected/sp4_cg_equal_to.ir.exp | 10 ++ ...qual_to.expected => sp4_cg_equal_to.s.exp} | 6 +- .../sprint4/expected/sp4_cg_less_than.asc.exp | 10 ++ .../sprint4/expected/sp4_cg_less_than.ir.exp | 10 ++ ...s_than.expected => sp4_cg_less_than.s.exp} | 6 +- tests/sprint4/expected/sp4_cg_mod.asc.exp | 10 ++ tests/sprint4/expected/sp4_cg_mod.ir.exp | 8 + .../{sp4_cg_mod.expected => sp4_cg_mod.s.exp} | 0 tests/sprint4/expected/sp4_cg_mult.asc.exp | 10 ++ tests/sprint4/expected/sp4_cg_mult.ir.exp | 8 + ...sp4_cg_mult.expected => sp4_cg_mult.s.exp} | 0 tests/sprint4/expected/sp4_cg_neg.asc.exp | 9 ++ tests/sprint4/expected/sp4_cg_neg.ir.exp | 6 + .../{sp4_cg_neg.expected => sp4_cg_neg.s.exp} | 0 tests/sprint4/expected/sp4_cg_not.asc.exp | 9 ++ tests/sprint4/expected/sp4_cg_not.expected | 13 -- tests/sprint4/expected/sp4_cg_not.ir.exp | 7 + tests/sprint4/expected/sp4_cg_not.s.exp | 13 ++ tests/sprint4/expected/sp4_cg_or.asc.exp | 10 ++ tests/sprint4/expected/sp4_cg_or.expected | 21 --- tests/sprint4/expected/sp4_cg_or.ir.exp | 9 ++ tests/sprint4/expected/sp4_cg_or.s.exp | 21 +++ tests/sprint4/expected/sp4_cg_sub.asc.exp | 10 ++ tests/sprint4/expected/sp4_cg_sub.ir.exp | 8 + .../{sp4_cg_sub.expected => sp4_cg_sub.s.exp} | 1 + tests/sprint4/test/sp4_cg_add.alpha | 1 + tests/sprint4/test/sp4_cg_and.alpha | 1 + tests/sprint4/test/sp4_cg_div.alpha | 1 + tests/sprint4/test/sp4_cg_equal_to.alpha | 1 + tests/sprint4/test/sp4_cg_less_than.alpha | 1 + tests/sprint4/test/sp4_cg_mod.alpha | 1 + tests/sprint4/test/sp4_cg_mult.alpha | 1 + tests/sprint4/test/sp4_cg_neg.alpha | 1 + tests/sprint4/test/sp4_cg_not.alpha | 1 + tests/sprint4/test/sp4_cg_or.alpha | 1 + tests/sprint4/test/sp4_cg_sub.alpha | 1 + 167 files changed, 1757 insertions(+), 572 deletions(-) delete mode 100755 check.sh create mode 100644 tests/given/expected/entry.definition.alpha.asc create mode 100644 tests/given/expected/entry.duplicateDifferent.alpha.asc create mode 100644 tests/given/expected/entry.duplicateSame.alpha.asc create mode 100644 tests/given/expected/entry.local.alpha.asc create mode 100644 tests/given/expected/error.entry.undeclaredType.alpha.asc create mode 100644 tests/given/expected/error.entry.undeclaredVar.alpha.asc create mode 100644 tests/given/expected/error.none.alpha.asc create mode 100644 tests/given/expected/error.operator.alpha.asc create mode 100644 tests/given/expected/function.declaration.alpha.asc create mode 100644 tests/given/expected/function.definition.alpha.asc create mode 100644 tests/given/expected/functionValue.alpha.asc create mode 100644 tests/given/expected/sample.good.alpha.asc create mode 100644 tests/given/expected/selectionSort.alpha.asc create mode 100644 tests/given/expected/type.array.alpha.asc create mode 100644 tests/given/expected/type.mapping.alpha.asc create mode 100644 tests/given/expected/type.record.alpha.asc create mode 100644 tests/given/expected/types.alpha.asc create mode 100644 tests/given/test/error.entry.undeclaredType.alpha create mode 100644 tests/given/test/error.entry.undeclaredVar.alpha create mode 100644 tests/given/test/error.operator.alpha create mode 100644 tests/sprint1/expected/sp1_keywords.tok.exp create mode 100644 tests/sprint1/expected/sp1_operators.tok.exp create mode 100644 tests/sprint1/expected/sp1_other_punc.tok.exp create mode 100644 tests/sprint1/expected/sp1_punc_grouping.tok.exp create mode 100644 tests/sprint1/expected/sp1_real_alpha_file1.tok.exp create mode 100644 tests/sprint1/expected/sp1_real_alpha_file2.tok.exp create mode 100644 tests/sprint1/expected/sp1_simple_alpha.tok.exp create mode 100644 tests/sprint1/expected/sp1_simple_int.tok.exp create mode 100644 tests/sprint1/expected/sp1_simple_literals.tok.exp create mode 100644 tests/sprint1/expected/sp1_variables.tok.exp rename tests/sprint2/expected/{sp2_carls_mistake.expected => sp2_carls_mistake.st.exp} (80%) rename tests/sprint2/expected/{sp2_function_types.expected => sp2_function_types.st.exp} (67%) rename tests/sprint2/expected/{sp2_integer_binary_op.expected => sp2_integer_binary_op.st.exp} (83%) rename tests/sprint2/expected/{sp2_invalid_multiple_params_no_as.expected => sp2_invalid_multiple_params_no_as.st.exp} (82%) rename tests/sprint2/expected/{sp2_invalid_recop.expected => sp2_invalid_recop.st.exp} (82%) rename tests/sprint2/expected/{sp2_invalid_release.expected => sp2_invalid_release.st.exp} (85%) rename tests/sprint2/expected/{sp2_library.expected => sp2_library.st.exp} (79%) create mode 100644 tests/sprint2/expected/sp2_llnode.st.exp rename tests/sprint2/expected/{sp2_llnode.expected => sp2_llnode_bad.st.exp} (72%) rename tests/sprint2/expected/{sp2_one_line.expected => sp2_one_line.st.exp} (77%) rename tests/sprint2/expected/{sp2_presidence.expected => sp2_presidence.st.exp} (84%) rename tests/sprint2/expected/{sp2_simple.expected => sp2_simple.st.exp} (77%) rename tests/sprint2/expected/{sp2_sp2_arrayargs.expected => sp2_sp2_arrayargs.st.exp} (79%) delete mode 100644 tests/sprint2/expected/sp2_valid_assignable_and_mem.expected rename tests/{sprint3/expected/sp3_primitive_type_check.expected => sprint2/expected/sp2_valid_assignable_and_mem.st.exp} (50%) delete mode 100644 tests/sprint2/test/sp2_sp2_arrayargs.alpha~ create mode 100644 tests/sprint3/expected/sp3_and_or_type_check.asc.exp delete mode 100644 tests/sprint3/expected/sp3_and_or_type_check.expected create mode 100644 tests/sprint3/expected/sp3_boolean_binary_op_typecheck.asc.exp delete mode 100644 tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected rename tests/sprint3/expected/{sp3_boolean_unary_op_typecheck.expected => sp3_boolean_unary_op_typecheck.asc.exp} (52%) create mode 100644 tests/sprint3/expected/sp3_carls_second_mistake.asc.exp delete mode 100644 tests/sprint3/expected/sp3_carls_second_mistake.expected create mode 100644 tests/sprint3/expected/sp3_if_else.asc.exp create mode 100644 tests/sprint3/expected/sp3_if_while.asc.exp create mode 100644 tests/sprint3/expected/sp3_integer_binary_op_typecheck.asc.exp delete mode 100644 tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected rename tests/sprint3/expected/{sp3_integer_unary_op_typecheck.expected => sp3_integer_unary_op_typecheck.asc.exp} (53%) create mode 100644 tests/sprint3/expected/sp3_multiple_args.asc.exp delete mode 100644 tests/sprint3/expected/sp3_multiple_args.expected create mode 100644 tests/sprint3/expected/sp3_primitive_type_check.asc.exp create mode 100644 tests/sprint3/expected/sp3_record_size_check.asc.exp delete mode 100644 tests/sprint3/expected/sp3_record_size_check.expected create mode 100644 tests/sprint4/expected/sp4_cg_add.asc.exp create mode 100644 tests/sprint4/expected/sp4_cg_add.ir.exp rename tests/sprint4/expected/{sp4_cg_add.expected => sp4_cg_add.s.exp} (100%) create mode 100644 tests/sprint4/expected/sp4_cg_and.asc.exp delete mode 100644 tests/sprint4/expected/sp4_cg_and.expected create mode 100644 tests/sprint4/expected/sp4_cg_and.ir.exp create mode 100644 tests/sprint4/expected/sp4_cg_and.s.exp create mode 100644 tests/sprint4/expected/sp4_cg_div.asc.exp create mode 100644 tests/sprint4/expected/sp4_cg_div.ir.exp rename tests/sprint4/expected/{sp4_cg_div.expected => sp4_cg_div.s.exp} (100%) create mode 100644 tests/sprint4/expected/sp4_cg_equal_to.asc.exp create mode 100644 tests/sprint4/expected/sp4_cg_equal_to.ir.exp rename tests/sprint4/expected/{sp4_cg_equal_to.expected => sp4_cg_equal_to.s.exp} (66%) create mode 100644 tests/sprint4/expected/sp4_cg_less_than.asc.exp create mode 100644 tests/sprint4/expected/sp4_cg_less_than.ir.exp rename tests/sprint4/expected/{sp4_cg_less_than.expected => sp4_cg_less_than.s.exp} (66%) create mode 100644 tests/sprint4/expected/sp4_cg_mod.asc.exp create mode 100644 tests/sprint4/expected/sp4_cg_mod.ir.exp rename tests/sprint4/expected/{sp4_cg_mod.expected => sp4_cg_mod.s.exp} (100%) create mode 100644 tests/sprint4/expected/sp4_cg_mult.asc.exp create mode 100644 tests/sprint4/expected/sp4_cg_mult.ir.exp rename tests/sprint4/expected/{sp4_cg_mult.expected => sp4_cg_mult.s.exp} (100%) create mode 100644 tests/sprint4/expected/sp4_cg_neg.asc.exp create mode 100644 tests/sprint4/expected/sp4_cg_neg.ir.exp rename tests/sprint4/expected/{sp4_cg_neg.expected => sp4_cg_neg.s.exp} (100%) create mode 100644 tests/sprint4/expected/sp4_cg_not.asc.exp delete mode 100644 tests/sprint4/expected/sp4_cg_not.expected create mode 100644 tests/sprint4/expected/sp4_cg_not.ir.exp create mode 100644 tests/sprint4/expected/sp4_cg_not.s.exp create mode 100644 tests/sprint4/expected/sp4_cg_or.asc.exp delete mode 100644 tests/sprint4/expected/sp4_cg_or.expected create mode 100644 tests/sprint4/expected/sp4_cg_or.ir.exp create mode 100644 tests/sprint4/expected/sp4_cg_or.s.exp create mode 100644 tests/sprint4/expected/sp4_cg_sub.asc.exp create mode 100644 tests/sprint4/expected/sp4_cg_sub.ir.exp rename tests/sprint4/expected/{sp4_cg_sub.expected => sp4_cg_sub.s.exp} (99%) diff --git a/check.sh b/check.sh deleted file mode 100755 index cf7c946..0000000 --- a/check.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/bash - -# Diff-Check Tool # -# Checks if outputed TOK = exp # -# The Translators - Spring 2025 # - -TOK_DIR="out" -NOCOLOR='\033[0m' -RED='\033[0;31m' -GREEN='\033[0;32m' -ORANGE='\033[0;33m' -BLUE='\033[0;34m' -PURPLE='\033[0;35m' -CYAN='\033[0;36m' -LIGHTGRAY='\033[0;37m' -DARKGRAY='\033[1;30m' -LIGHTRED='\033[1;31m' -LIGHTGREEN='\033[1;32m' -YELLOW='\033[1;33m' -LIGHTBLUE='\033[1;34m' -LIGHTPURPLE='\033[1;35m' -LIGHTCYAN='\033[1;36m' -WHITE='\033[1;37m' - -compare_files() { - local file="$1" - local filename=$(basename -- "$file") - filename="${filename%.*}" - local num=${filename:2:1} - local exp="./tests/sprint$num/expected/$filename.expected" - - if [[ -f "$exp" ]]; then - diff -q "$file" "$exp" > /dev/null - if [[ $? -eq 0 ]]; then - echo -e "${GREEN}[✔] ${PURPLE}$filename ${WHITE}passed.${NOCOLOR}" - elif [[ ! -s "$file" ]]; then - echo -e "${RED}[✘] ${PURPLE}$filename ${WHITE}failed with an empty file. (did it segfault?)${NOCOLOR}" - else - echo -e "\n${RED}[✘] ${PURPLE}$file ${WHITE}failed with an unexpected value...${NOCOLOR}" - diff --color=always "$file" "$exp" - echo -e "" - fi - else - echo -e "${ORANGE}[-] ${PURPLE}$filename ${WHITE}does not have an expected value.${NOCOLOR}" - fi -} - -if [[ ! -d "$TOK_DIR" ]]; then - echo -e "${RED}[ERROR] ${YELLOW}Directory $TOK_DIR does not exist.${NOCOLOR}" - exit 1 -fi - -if [[ $# -eq 0 ]]; then - for file in "$TOK_DIR"/*; do - compare_files "$file" - done -elif [[ $# -eq 1 ]]; then - prefix="$1" - for file in "$TOK_DIR"/"$prefix"*; do - if [[ -f "$file" ]]; then - compare_files "$file" - fi - done -else - echo -e "${LIGHTBLUE}Usage: $0 [sp#]${NOCOLOR}" - exit 1 -fi \ No newline at end of file diff --git a/src/symbol_table.c b/src/symbol_table.c index f4fa1ea..646b053 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1200,6 +1200,14 @@ TableNode *table_lookup(SymbolTable *table, char *x) { } TableNode *entrie = table->entries; for (; entrie != NULL; entrie = entrie->next) { + if (entrie->theName == NULL) { + printdebug("name of entry is currently NULL, undefined"); + return undefined; + } + if (entrie->theName == undefined->theName) { + printdebug("name of entry is currently undefined"); + return undefined; + } if (!strcmp(entrie->theName, x)) { return entrie; } diff --git a/test.sh b/test.sh index 9c3652e..3f3c266 100755 --- a/test.sh +++ b/test.sh @@ -34,23 +34,23 @@ fi help() { echo -e "${GREEN}[HELP] ${YELLOW}Usage: ./test.sh [-exp] ${WHITE}" - echo -e "${GREEN}[HELP] ${YELLOW}To all tests in a folder: ./test/sh /* [-exp]${WHITE}" + echo -e "${GREEN}[HELP] ${YELLOW}To all tests in a folder: ./test/sh / [-exp]${WHITE}" exit 1 } run() { filename=$(basename -- "$1") first_line=$(head -n 1 "$1") - if [[ "$first_line" == "\$\$ TEST: ["*"]"* ]]; then - if [ -n "$2" ]; then - if [[ "$2" == "-exp" ]]; then - bracket_content=$(echo "$first_line" | sed -n 's/.*\[\(.*\)\].*/\1/p') - sed -i '1d' "$1" - ./alpha ${bracket_content} "$1" - sed -i "1s/^/$first_line\n/" "$1" - path=$(dirname "$1") - filename_noext=${filename:0:${#filename}-6} + if [[ "$first_line" == "(* TEST: ["*"] *)"* ]]; then + bracket_content=$(echo "$first_line" | sed -n 's/.*\[\(.*\)\].*/\1/p') + sed -i '1d' "$1" + ./alpha ${bracket_content} "$1" + sed -i "1s/^/$first_line\n/" "$1" + if [ $# -ge 2 ]; then + path=$(dirname "$1") + filename_noext=${filename:0:${#filename}-6} + if [[ "$2" == "-exp" || "$3" == "-exp" ]]; then for file in out/${filename_noext}.*; do if [[ "$file" == *".asc" || "$file" == *".s" || "$file" == *".st" || "$file" == *".tok" || "$file" == *".ir" ]]; then for_filename=$(basename -- "$file") @@ -62,65 +62,75 @@ run() { else echo -e "${RED}[ALERT] ${YELLOW}Unexpected file found: $file ${WHITE}" fi + done + fi + + if [[ "$2" == "-diff" || "$3" == "-diff" ]]; then + for file in out/${filename_noext}.*; do + if [[ "$file" == *".asc" || "$file" == *".s" || "$file" == *".st" || "$file" == *".tok" || "$file" == *".ir" ]]; then + for_filename=$(basename -- "$file") + for_filename="${for_filename}.exp" + if [ -f "${path}/../expected/${for_filename}" ]; then + exp_basename=$(basename -- "$for_filename") + diff -q "${path}/../expected/${for_filename}" "$file" + if [ $? -eq 0 ]; then + echo -e "${GREEN}[SUCCESS] ${YELLOW}Test ${WHITE}$file ${YELLOW}passed ${WHITE}$exp_basename${WHITE}" + else + echo -e "${RED}[ERROR] ${YELLOW}Test ${WHITE}$file ${YELLOW}failed ${WHITE}$exp_basename${WHITE}" + fi + else + echo -e "${RED}[ALERT] ${YELLOW}File ${path}/../expected/${for_filename} not found!${WHITE}" + fi + else + echo -e "${RED}[ALERT] ${YELLOW}Unexpected file found: $file ${WHITE}" + fi done - else - echo -e "${BLUE}[ERROR] ${YELLOW}Invalid argument $2!${WHITE}" - help fi fi - - bracket_content=$(echo "$first_line" | sed -n 's/.*\[\(.*\)\].*/\1/p') - sed -i '1d' "$1" - ./alpha ${bracket_content} "$1" - sed -i "1s/^/$first_line\n/" "$1" else echo -e "${RED}[ERROR] ${YELLOW}File $1 is not a valid .alpha test file!${WHITE}" - help fi } if [[ "$1" == *"/" ]]; then - if [ -n $2 ]; then - for file in "$1"/*; do + if [ $# -ge 2 ]; then + for file in "$1"*; do if [[ "$file" == *.alpha ]]; then - if [[ "$2" == "-exp" ]]; then - run "$file" "$2" + if [[ "$2" == "-exp" || "$3" == "-exp" || "$2" == "-diff" || "$3" == "-diff" ]]; then + run "$file" "$2" "$3" else echo -e "${RED}[ERROR] ${YELLOW}Invalid argument $2!${WHITE}" help fi - else - echo -e "${RED}[ERROR] ${YELLOW}File $file is not a .alpha file!${WHITE}" - help fi done else - for file in "$1"/*; do + for file in "$1"*; do if [[ "$file" == *.alpha ]]; then run "$file" else echo -e "${RED}[ERROR] ${YELLOW}File $file is not a .alpha file!${WHITE}" - help fi done - fi + exit 0 fi if [ -f "$1" ]; then if [[ "$1" == *.alpha ]]; then - if [ -n "$2" ]; then - if [[ "$2" == "-exp" ]]; then - run "$1" "$2" + if [ $# -ge 2 ]; then + if [[ "$2" == "-exp" || "$3" == "-exp" || "$2" == "-diff" || "$3" == "-diff" ]]; then + run "$1" "$2" "$3" else echo -e "${RED}[ERROR] ${YELLOW}Invalid argument $2!${WHITE}" help fi else run "$1" + fi else echo -e "${RED}[ERROR] ${YELLOW}File $1 is not a .alpha file!${WHITE}" diff --git a/tests/given/expected/entry.definition.alpha.asc b/tests/given/expected/entry.definition.alpha.asc new file mode 100644 index 0000000..07dbd42 --- /dev/null +++ b/tests/given/expected/entry.definition.alpha.asc @@ -0,0 +1,10 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.definition.alpha +001: (* type string : 1 -> character *) +002: type M : string -> integer +003: +004: function entry : M +005: +006: entry(s) := { +007: return 0; +008: } +009: diff --git a/tests/given/expected/entry.duplicateDifferent.alpha.asc b/tests/given/expected/entry.duplicateDifferent.alpha.asc new file mode 100644 index 0000000..65ae8d8 --- /dev/null +++ b/tests/given/expected/entry.duplicateDifferent.alpha.asc @@ -0,0 +1,13 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.duplicateDifferent.alpha +001: type M : string -> integer +002: +003: function entry : M +004: +005: entry(s) := { +006: [ +007: integer: x; +008: character: x +009: ] +010: return x; +011: } +012: diff --git a/tests/given/expected/entry.duplicateSame.alpha.asc b/tests/given/expected/entry.duplicateSame.alpha.asc new file mode 100644 index 0000000..7861cc6 --- /dev/null +++ b/tests/given/expected/entry.duplicateSame.alpha.asc @@ -0,0 +1,11 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.duplicateSame.alpha +001: type M : string -> integer +002: function entry : M +003: +004: entry(s) := { +005: [ +006: integer: x; integer: x +007: ] +008: return x; +009: } +010: diff --git a/tests/given/expected/entry.local.alpha.asc b/tests/given/expected/entry.local.alpha.asc new file mode 100644 index 0000000..e9882d4 --- /dev/null +++ b/tests/given/expected/entry.local.alpha.asc @@ -0,0 +1,13 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.local.alpha +001: type M : string -> integer +002: +003: function entry : M +004: +005: entry(s) := { +006: [ +007: integer: x +008: ] +009: x := 0; +010: return x; +011: } +012: diff --git a/tests/given/expected/error.entry.undeclaredType.alpha.asc b/tests/given/expected/error.entry.undeclaredType.alpha.asc new file mode 100644 index 0000000..cd1d37c --- /dev/null +++ b/tests/given/expected/error.entry.undeclaredType.alpha.asc @@ -0,0 +1,16 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.undeclaredType.alpha +001: type M : string -> integer +002: +003: function foo : M +004: +005: foo (s) := { +006: [ +007: int: x + ^0 ^1 + LINE 7:9 ** ERROR #0: the name 'int', used here as a type, has not been declared at this point in the program. + LINE 7:14 ** ERROR #1: the name 'x' is being declared with an unknown type. + +008: ] +009: return 0; +010: } +011: diff --git a/tests/given/expected/error.entry.undeclaredVar.alpha.asc b/tests/given/expected/error.entry.undeclaredVar.alpha.asc new file mode 100644 index 0000000..7c4e6c2 --- /dev/null +++ b/tests/given/expected/error.entry.undeclaredVar.alpha.asc @@ -0,0 +1,12 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.undeclaredVar.alpha +001: type M : string -> integer +002: +003: function entry : M +004: +005: entry(s) := { +006: return x; + ^0 + LINE 6:12 ** ERROR #0: the name 'x', used here as a variable name, has not been declared at this point in the program. + +007: } +008: diff --git a/tests/given/expected/error.none.alpha.asc b/tests/given/expected/error.none.alpha.asc new file mode 100644 index 0000000..9fdcadb --- /dev/null +++ b/tests/given/expected/error.none.alpha.asc @@ -0,0 +1,16 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file error.none.alpha +001: type string2int: string -> integer +002: +003: function entry : string2int +004: +005: entry(arg) := { +006: [ integer: i ; integer: sum ] +007: sum := 0; +008: i := 0 ; +009: while (i < 10) { +010: sum := sum + i; +011: i := i + 1; +012: } +013: return 0; +014: } +015: diff --git a/tests/given/expected/error.operator.alpha.asc b/tests/given/expected/error.operator.alpha.asc new file mode 100644 index 0000000..82f5614 --- /dev/null +++ b/tests/given/expected/error.operator.alpha.asc @@ -0,0 +1,19 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file error.operator.alpha +001: type string2int: string -> integer +002: +003: function entry : string2int +004: +005: entry(arg) := { +006: [ integer: i; integer: sum ] +007: sum := 0; +008: i := 0; +009: while (i < 10) { +010: sum = sum + i; + ^0 + LINE 10:13 ** ERROR #0: assignment operator (:=) expected but equality operator (=) found. + +011: i := i + 1; +012: } +013: return 0; +014: } +015: diff --git a/tests/given/expected/function.declaration.alpha.asc b/tests/given/expected/function.declaration.alpha.asc new file mode 100644 index 0000000..fca046a --- /dev/null +++ b/tests/given/expected/function.declaration.alpha.asc @@ -0,0 +1,5 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file function.declaration.alpha +001: type M : integer -> integer +002: +003: function f : M +004: diff --git a/tests/given/expected/function.definition.alpha.asc b/tests/given/expected/function.definition.alpha.asc new file mode 100644 index 0000000..e476758 --- /dev/null +++ b/tests/given/expected/function.definition.alpha.asc @@ -0,0 +1,9 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file function.definition.alpha +001: type M : integer -> integer +002: +003: function f : M +004: +005: f(x) := { +006: return x; +007: } +008: diff --git a/tests/given/expected/functionValue.alpha.asc b/tests/given/expected/functionValue.alpha.asc new file mode 100644 index 0000000..882d558 --- /dev/null +++ b/tests/given/expected/functionValue.alpha.asc @@ -0,0 +1,75 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file functionValue.alpha +001: (* Type definitions *) +002: +003: (* mapping type *) +004: type string2int: string -> integer +005: +006: (* array of functions *) +007: type funArray: 1 -> string2int +008: +009: (* record of functions *) +010: type funRec: [ string2int: f; string2int: g ] +011: +012: (* function returning function *) +013: type integer_2_string2int: integer -> string2int +014: +015: (* function returning function *) +016: type string2int_2_integer: string2int -> integer +017: +018: +019: type iXiXc: [integer: a; integer: b; character: c] +020: +021: type iic2b: iXiXc -> Boolean +022: +023: (* Function declarations using the above type definitions *) +024: function a: string2int +025: function b: integer_2_string2int +026: function c: string2int_2_integer +027: +028: function d: iic2b +029: +030: d(x,y,z) := { +031: return (x < y & z < 'm'); +032: } +033: +034: function entry: string2int +035: +036: a(x) := { +037: [string : s] +038: s := x; +039: return 0; +040: } +041: +042: b(x) := { +043: [integer: i] +044: i := x; +045: return a; +046: } +047: +048: c(x) := { +049: [string: s] +050: s := "Hi!"; +051: return x(s); +052: } +053: +054: +055: (* Function definition +056: entry is the first function called +057: *) +058: entry(arg) := { +059: [integer: result; string2int: f; integer: temp] +060: temp := a("Hello"); +061: f := b(temp); +062: result := c(f); +063: if (d(1,2,'c')) +064: then { +065: result := 0; +066: } +067: else { +068: [ Boolean : b] +069: result := entry("hello"); +070: } +071: result := c(f); +072: return result; +073: } +074: diff --git a/tests/given/expected/sample.good.alpha.asc b/tests/given/expected/sample.good.alpha.asc new file mode 100644 index 0000000..a4bfa3a --- /dev/null +++ b/tests/given/expected/sample.good.alpha.asc @@ -0,0 +1,31 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file sample.good.alpha +001: +001: (* Type definitions *) +003: type int2int: integer -> integer +004: type string2int: string -> integer +005: +006: (* Function declarations +007: They use the above type definitions +008: *) +009: function square : int2int +010: function entry : string2int +011: +012: (* Function definition +013: Functions must be declared before they are defined +014: *) +015: square(x) := { +016: return x * x; +017: } +018: +019: (* Function definition +020: entry is the first function called +021: *) +022: entry(arg) := { +023: [ integer: input ; integer: expected ; integer: actual ; Boolean: result ] +024: input := 7; +025: expected := 49; +026: actual := square(input); +027: result := expected = actual; +028: return 0; +029: } +030: diff --git a/tests/given/expected/selectionSort.alpha.asc b/tests/given/expected/selectionSort.alpha.asc new file mode 100644 index 0000000..2a12877 --- /dev/null +++ b/tests/given/expected/selectionSort.alpha.asc @@ -0,0 +1,70 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file selectionSort.alpha +001: (* Type definitions *) +002: +003: type string2int: string -> integer +004: type intArray: 1 -> integer +005: type intArrayXinteger: [ intArray: data; integer: index ] +006: type intArrayXinteger2integer: intArrayXinteger -> integer +007: type intArray2Boolean: intArray -> Boolean +008: +009: +010: (* Function declarations +011: They use the above type definitions +012: *) +013: function indexOfSmallest: intArrayXinteger2integer +014: function selectionSort: intArray2Boolean +015: function entry : string2int +016: +017: (* indexOfSmallest *) +018: indexOfSmallest (* as *) (data, startingIndex) := { +019: [ integer: indexOfSmallestSoFar; integer: i ] +020: indexOfSmallestSoFar := startingIndex; +021: i := 0 ; +022: while (i < data._1 ) { +023: if ( data(i) < data(indexOfSmallestSoFar) ) +024: then { +025: indexOfSmallestSoFar := i; +026: } +027: else { +028: i := i; +029: } +030: i := i + 1; +031: } +032: return indexOfSmallestSoFar; +033: } +034: +035: +036: (* selectionSort *) +037: selectionSort(data) := { +038: [ integer: i ] +039: i := 0 ; +040: while (i < data._1 ) { +041: [ integer: index; integer: temp ] +042: index := indexOfSmallest(data,i); +043: temp := data(index); +044: data(index) := data(i); +045: data(i) := temp; +046: i := i + 1; +047: } +048: return true; +049: } +050: +051: +052: (* Function definition +053: entry is the first function called +054: *) +055: entry(arg) := { +056: [ intArray: data; Boolean: _ ] +057: data := reserve data(8); +058: data(0) := 60; +059: data(1) := 80; +060: data(2) := 10; +061: data(3) := 50; +062: data(4) := 30; +063: data(5) := 40; +064: data(6) := 20; +065: data(7) := 70; +066: _ := selectionSort(data); +067: return 0; +068: } +069: diff --git a/tests/given/expected/type.array.alpha.asc b/tests/given/expected/type.array.alpha.asc new file mode 100644 index 0000000..8e6154d --- /dev/null +++ b/tests/given/expected/type.array.alpha.asc @@ -0,0 +1,3 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file type.array.alpha +001: type A : 1 -> integer +002: diff --git a/tests/given/expected/type.mapping.alpha.asc b/tests/given/expected/type.mapping.alpha.asc new file mode 100644 index 0000000..2ce8f0c --- /dev/null +++ b/tests/given/expected/type.mapping.alpha.asc @@ -0,0 +1,4 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file type.mapping.alpha +001: type M : integer -> character +002: +003: diff --git a/tests/given/expected/type.record.alpha.asc b/tests/given/expected/type.record.alpha.asc new file mode 100644 index 0000000..848948b --- /dev/null +++ b/tests/given/expected/type.record.alpha.asc @@ -0,0 +1,3 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file type.record.alpha +001: type R : [ integer : i ; character : c ] +002: diff --git a/tests/given/expected/types.alpha.asc b/tests/given/expected/types.alpha.asc new file mode 100644 index 0000000..8844865 --- /dev/null +++ b/tests/given/expected/types.alpha.asc @@ -0,0 +1,77 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file types.alpha +001: (* +001: +002: At compiler start-up your program should +003: create symbol table entries for the following +004: built-in types: +005: +006: Boolean (1 byte) +007: character (1 byte) +008: integer (4 bytes) +009: address (8 bytes) +010: +011: and the following privileged type (it has literals): +012: +013: type string: 1 -> character +014: +015: Your compiler can define other types during +016: its start-up routine as well, if it is helpful +017: to do so. +018: +019: *) +021: +022: +023: +024: type BooleanXBoolean: [Boolean: x; Boolean: y] +025: type characterXcharacter: [character: x; character: y] +026: type integerXinteger: [integer: x; integer: y] +027: +028: type Boolean2Boolean: Boolean -> Boolean +029: type integer2integer: integer -> integer +030: +031: type character2integer: character -> integer +032: type Boolean2integer: Boolean -> integer +033: type string2integer: string -> integer +034: +035: type integerXinteger2integer: integerXinteger -> integer +036: +037: type integerXinteger2Boolean: integerXinteger -> Boolean +038: type characterXcharacter2Boolean: characterXcharacter -> Boolean +039: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +040: +041: +042: type integer2address: integer -> address +043: type address2integer: address -> integer +044: +045: +046: (* The alpha library functions +047: You will be provided with x86-64 assembly +048: code implementations of these. +049: *) +050: +051: external function printInteger: integer2integer +052: external function printCharacter: character2integer +053: external function printBoolean: Boolean2integer +054: +055: (* +056: A declaration of the entry point function for your program +057: +058: You may assume that when starting this function will behave as if +059: it had been called from the C language main function like this: +060: +061: int main(int argc, char * argv[]) { +062: if (argc == 1) { +063: return entry(NULL); +064: } +065: else { +066: return entry(makeAlphaString(argv[1])); +067: } +068: } +069: +070: for some suitable definition of makeAlphaString which creates +071: an alpha string representation of its argument C string in memory +072: and returns a pointer to that alpha string. +073: *) +074: +075: function entry: string2integer +076: diff --git a/tests/given/test/entry.definition.alpha b/tests/given/test/entry.definition.alpha index c9538b4..75f6a38 100644 --- a/tests/given/test/entry.definition.alpha +++ b/tests/given/test/entry.definition.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) (* type string : 1 -> character *) type M : string -> integer diff --git a/tests/given/test/entry.duplicateDifferent.alpha b/tests/given/test/entry.duplicateDifferent.alpha index 41168f2..6a75b69 100644 --- a/tests/given/test/entry.duplicateDifferent.alpha +++ b/tests/given/test/entry.duplicateDifferent.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) type M : string -> integer function entry : M diff --git a/tests/given/test/entry.duplicateSame.alpha b/tests/given/test/entry.duplicateSame.alpha index e6b295d..435e170 100644 --- a/tests/given/test/entry.duplicateSame.alpha +++ b/tests/given/test/entry.duplicateSame.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) type M : string -> integer function entry : M diff --git a/tests/given/test/entry.local.alpha b/tests/given/test/entry.local.alpha index e9905c4..f2efa3a 100644 --- a/tests/given/test/entry.local.alpha +++ b/tests/given/test/entry.local.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) type M : string -> integer function entry : M diff --git a/tests/given/test/error.entry.undeclaredType.alpha b/tests/given/test/error.entry.undeclaredType.alpha new file mode 100644 index 0000000..9de0d02 --- /dev/null +++ b/tests/given/test/error.entry.undeclaredType.alpha @@ -0,0 +1,11 @@ +(* TEST: [-asc -tc] *) +type M : string -> integer + +function foo : M + +foo (s) := { + [ + int: x + ] + return 0; +} diff --git a/tests/given/test/error.entry.undeclaredVar.alpha b/tests/given/test/error.entry.undeclaredVar.alpha new file mode 100644 index 0000000..29a502c --- /dev/null +++ b/tests/given/test/error.entry.undeclaredVar.alpha @@ -0,0 +1,8 @@ +(* TEST: [-asc -tc] *) +type M : string -> integer + +function entry : M + +entry(s) := { + return x; +} diff --git a/tests/given/test/error.none.alpha b/tests/given/test/error.none.alpha index 50fc401..bd54c16 100644 --- a/tests/given/test/error.none.alpha +++ b/tests/given/test/error.none.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) type string2int: string -> integer function entry : string2int diff --git a/tests/given/test/error.operator.alpha b/tests/given/test/error.operator.alpha new file mode 100644 index 0000000..bb2e79c --- /dev/null +++ b/tests/given/test/error.operator.alpha @@ -0,0 +1,15 @@ +(* TEST: [-asc -tc] *) +type string2int: string -> integer + +function entry : string2int + +entry(arg) := { + [ integer: i; integer: sum ] + sum := 0; + i := 0; + while (i < 10) { + sum = sum + i; + i := i + 1; + } + return 0; +} diff --git a/tests/given/test/function.declaration.alpha b/tests/given/test/function.declaration.alpha index 9653a68..2396d45 100644 --- a/tests/given/test/function.declaration.alpha +++ b/tests/given/test/function.declaration.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) type M : integer -> integer function f : M diff --git a/tests/given/test/function.definition.alpha b/tests/given/test/function.definition.alpha index 72f1f68..ffafb72 100644 --- a/tests/given/test/function.definition.alpha +++ b/tests/given/test/function.definition.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) type M : integer -> integer function f : M diff --git a/tests/given/test/functionValue.alpha b/tests/given/test/functionValue.alpha index 85158c7..1ff9d50 100644 --- a/tests/given/test/functionValue.alpha +++ b/tests/given/test/functionValue.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) (* Type definitions *) (* mapping type *) @@ -29,7 +29,6 @@ function c: string2int_2_integer function d: iic2b d(x,y,z) := { - [string: s;integer: s] return (x < y & z < 'm'); } @@ -58,11 +57,11 @@ c(x) := { entry is the first function called *) entry(arg) := { - [integer: result; string2int: f; integer: temp; character: char] + [integer: result; string2int: f; integer: temp] temp := a("Hello"); f := b(temp); result := c(f); - if (d(1,2,char)) + if (d(1,2,'c')) then { result := 0; } diff --git a/tests/given/test/sample.good.alpha b/tests/given/test/sample.good.alpha index 54c4ae6..8153085 100644 --- a/tests/given/test/sample.good.alpha +++ b/tests/given/test/sample.good.alpha @@ -1,4 +1,5 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) + (* Type definitions *) type int2int: integer -> integer type string2int: string -> integer diff --git a/tests/given/test/selectionSort.alpha b/tests/given/test/selectionSort.alpha index d785542..489f355 100644 --- a/tests/given/test/selectionSort.alpha +++ b/tests/given/test/selectionSort.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) (* Type definitions *) type string2int: string -> integer @@ -46,9 +46,9 @@ selectionSort(data) := { data(i) := temp; i := i + 1; } - return true; + return true; } - + (* Function definition entry is the first function called diff --git a/tests/given/test/type.array.alpha b/tests/given/test/type.array.alpha index ef76679..3aec34c 100644 --- a/tests/given/test/type.array.alpha +++ b/tests/given/test/type.array.alpha @@ -1,2 +1,2 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) type A : 1 -> integer diff --git a/tests/given/test/type.mapping.alpha b/tests/given/test/type.mapping.alpha index 37c1037..dc4f63d 100644 --- a/tests/given/test/type.mapping.alpha +++ b/tests/given/test/type.mapping.alpha @@ -1,3 +1,3 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) type M : integer -> character diff --git a/tests/given/test/type.record.alpha b/tests/given/test/type.record.alpha index 4a08b73..9c2b1c6 100644 --- a/tests/given/test/type.record.alpha +++ b/tests/given/test/type.record.alpha @@ -1,2 +1,2 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) type R : [ integer : i ; character : c ] diff --git a/tests/given/test/types.alpha b/tests/given/test/types.alpha index d4947d7..47e92f5 100644 --- a/tests/given/test/types.alpha +++ b/tests/given/test/types.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-asc -tc] +(* TEST: [-asc -tc] *) (* At compiler start-up your program should diff --git a/tests/sprint1/expected/sp1_keywords.tok.exp b/tests/sprint1/expected/sp1_keywords.tok.exp new file mode 100644 index 0000000..9e70321 --- /dev/null +++ b/tests/sprint1/expected/sp1_keywords.tok.exp @@ -0,0 +1,29 @@ +1 1 401 "while" +2 1 101 "While" +3 1 101 "whiLe" +4 1 402 "if" +5 1 101 "IF" +6 1 101 "If" +7 1 101 "iF" +8 1 403 "then" +9 1 101 "Then" +10 1 101 "theN" +11 1 404 "else" +12 1 101 "eLse" +13 1 101 "elSe" +14 1 101 "Else" +15 1 405 "type" +16 1 101 "Type" +17 1 101 "tyPe" +18 1 406 "function" +19 1 101 "Function" +20 1 101 "functioN" +21 1 407 "return" +22 1 101 "Return" +23 1 101 "returN" +24 1 408 "external" +25 1 101 "External" +26 1 101 "exteRnal" +27 1 409 "as" +28 1 101 "As" +29 1 101 "aS" diff --git a/tests/sprint1/expected/sp1_operators.tok.exp b/tests/sprint1/expected/sp1_operators.tok.exp new file mode 100644 index 0000000..dd3eaab --- /dev/null +++ b/tests/sprint1/expected/sp1_operators.tok.exp @@ -0,0 +1,22 @@ +1 1 601 "+" +2 1 602 "-" +3 1 603 "*" +4 1 604 "/" +6 1 605 "%" +7 1 606 "<" +9 1 607 "=" +10 1 608 ":=" +11 1 607 "=" +11 2 508 ":" +12 1 508 ":" +13 1 607 "=" +14 1 609 "!" +15 1 610 "&" +16 1 611 "|" +17 1 612 "." +18 1 101 "relEASE" +19 1 614 "release" +20 1 101 "RELEASE" +21 1 613 "reserve" +22 1 101 "RESERVE" +23 1 101 "reSERVe" diff --git a/tests/sprint1/expected/sp1_other_punc.tok.exp b/tests/sprint1/expected/sp1_other_punc.tok.exp new file mode 100644 index 0000000..7500378 --- /dev/null +++ b/tests/sprint1/expected/sp1_other_punc.tok.exp @@ -0,0 +1,7 @@ +1 1 507 ";" +2 1 508 ":" +3 1 509 "," +4 1 510 "->" +5 1 510 "->" +6 1 602 "-" +6 2 510 "->" diff --git a/tests/sprint1/expected/sp1_punc_grouping.tok.exp b/tests/sprint1/expected/sp1_punc_grouping.tok.exp new file mode 100644 index 0000000..c58a316 --- /dev/null +++ b/tests/sprint1/expected/sp1_punc_grouping.tok.exp @@ -0,0 +1,59 @@ +1 1 502 ")" +2 1 101 "a" +2 2 502 ")" +3 1 502 ")" +3 2 101 "a" +4 1 502 ")" +4 2 603 "*" +5 1 603 "*" +5 2 502 ")" +7 1 700 "(* jellsls + well this seems to work + + + *)" +13 1 501 "(" +14 1 101 "a" +14 2 501 "(" +15 1 501 "(" +15 2 101 "a" +16 1 501 "(" +16 2 603 "*" +17 1 603 "*" +17 2 501 "(" +20 1 505 "{" +21 1 101 "a" +21 2 505 "{" +22 1 505 "{" +22 2 101 "a" +23 1 505 "{" +23 2 603 "*" +24 1 603 "*" +24 2 505 "{" +25 1 506 "}" +26 1 101 "a" +26 2 506 "}" +27 1 506 "}" +27 2 101 "a" +28 1 506 "}" +28 2 603 "*" +29 1 603 "*" +29 2 506 "}" +33 1 503 "[" +34 1 101 "a" +34 2 503 "[" +35 1 503 "[" +35 2 101 "a" +36 1 503 "[" +36 2 603 "*" +37 1 603 "*" +37 2 503 "[" +38 1 504 "]" +39 1 101 "a" +39 2 504 "]" +40 1 504 "]" +40 2 101 "a" +41 1 504 "]" +41 2 603 "*" +42 1 603 "*" +42 2 504 "]" diff --git a/tests/sprint1/expected/sp1_real_alpha_file1.tok.exp b/tests/sprint1/expected/sp1_real_alpha_file1.tok.exp new file mode 100644 index 0000000..cc3f2c9 --- /dev/null +++ b/tests/sprint1/expected/sp1_real_alpha_file1.tok.exp @@ -0,0 +1,145 @@ +1 1 405 "type" +1 6 101 "rec" +1 9 508 ":" +1 11 503 "[" +1 12 201 "integer" +1 19 508 ":" +1 21 101 "x" +1 22 507 ";" +1 24 201 "integer" +1 31 508 ":" +1 33 101 "y" +1 34 504 "]" +2 1 405 "type" +2 6 101 "T1" +2 8 508 ":" +2 10 201 "integer" +2 18 510 "->" +2 21 201 "integer" +3 1 405 "type" +3 6 101 "T2" +3 8 508 ":" +3 10 101 "rec" +3 14 510 "->" +3 17 201 "integer" +4 1 406 "function" +4 10 101 "foo" +4 14 508 ":" +4 16 101 "T1" +5 1 406 "function" +5 10 101 "bar1" +5 15 508 ":" +5 17 101 "T2" +6 1 406 "function" +6 10 101 "bar2" +6 15 508 ":" +6 17 101 "T2" +7 1 101 "foo" +7 4 501 "(" +7 5 101 "x" +7 6 502 ")" +7 8 608 ":=" +7 11 505 "{" +8 2 407 "return" +8 9 101 "x" +8 11 603 "*" +8 13 101 "x" +8 14 507 ";" +9 9 506 "}" +10 1 101 "bar1" +10 5 501 "(" +10 6 101 "a" +10 7 502 ")" +10 9 608 ":=" +10 12 505 "{" +11 9 407 "return" +11 16 101 "a" +11 17 612 "." +11 18 101 "x" +11 20 603 "*" +11 22 101 "a" +11 23 612 "." +11 24 101 "y" +11 25 507 ";" +12 9 506 "}" +13 1 101 "bar2" +13 6 409 "as" +13 9 501 "(" +13 10 101 "r" +13 11 509 "," +13 12 101 "s" +13 13 502 ")" +13 15 608 ":=" +13 18 505 "{" +14 9 407 "return" +14 16 101 "r" +14 18 603 "*" +14 20 101 "s" +14 21 507 ";" +15 9 506 "}" +16 1 101 "entry" +16 6 501 "(" +16 7 101 "arg" +16 10 502 ")" +16 12 608 ":=" +16 15 505 "{" +17 9 503 "[" +17 11 201 "integer" +17 18 508 ":" +17 20 101 "result" +17 27 507 ";" +17 29 101 "rec" +17 32 508 ":" +17 34 101 "w" +17 35 504 "]" +18 9 101 "result" +18 16 608 ":=" +18 19 101 "foo" +18 22 501 "(" +18 23 301 "5" +18 24 502 ")" +18 25 507 ";" +19 9 101 "w" +19 11 608 ":=" +19 14 613 "reserve" +19 21 501 "(" +19 22 101 "w" +19 23 502 ")" +19 24 507 ";" +19 26 700 "(* see types.alpha – reserve returns a value of type address, + which can be assigned to array and record variables + *)" +22 9 101 "w" +22 10 612 "." +22 11 101 "x" +22 13 608 ":=" +22 16 301 "5" +22 17 507 ";" +23 9 101 "w" +23 10 612 "." +23 11 101 "y" +23 13 608 ":=" +23 16 301 "7" +23 17 507 ";" +24 9 101 "result" +24 16 608 ":=" +24 19 101 "bar1" +24 23 501 "(" +24 24 101 "w" +24 25 502 ")" +24 26 507 ";" +24 28 700 "(* pass w (a rec type value) to bar1 *)" +25 9 101 "result" +25 16 608 ":=" +25 19 101 "bar2" +25 23 501 "(" +25 24 301 "5" +25 25 509 "," +25 26 301 "7" +25 27 502 ")" +25 28 507 ";" +25 30 700 "(* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *)" +27 9 407 "return" +27 16 301 "0" +27 17 507 ";" +28 1 506 "}" diff --git a/tests/sprint1/expected/sp1_real_alpha_file2.tok.exp b/tests/sprint1/expected/sp1_real_alpha_file2.tok.exp new file mode 100644 index 0000000..90c34a2 --- /dev/null +++ b/tests/sprint1/expected/sp1_real_alpha_file2.tok.exp @@ -0,0 +1,100 @@ +1 1 700 "(* Type definitions *)" +2 1 405 "type" +2 6 101 "string" +2 12 508 ":" +2 14 301 "1" +2 16 510 "->" +2 19 204 "character" +3 1 405 "type" +3 6 101 "int2int" +3 13 508 ":" +3 15 201 "integer" +3 23 510 "->" +3 26 201 "integer" +4 1 405 "type" +4 6 101 "string2int" +4 16 508 ":" +4 18 101 "string" +4 25 510 "->" +4 28 201 "integer" +5 1 700 "(* Function prototypes +They use the above type definitions +*)" +8 1 406 "function" +8 10 101 "square" +8 17 508 ":" +8 19 101 "int2int" +9 1 406 "function" +9 10 101 "entry" +9 16 508 ":" +9 18 101 "string2int" +10 1 700 "(* Function definition +Functions must be declared before they are defined +*)" +13 1 101 "square" +13 7 501 "(" +13 8 101 "x" +13 9 502 ")" +13 11 608 ":=" +13 14 505 "{" +14 1 407 "return" +14 8 101 "x" +14 10 603 "*" +14 12 101 "x" +14 13 507 ";" +15 1 506 "}" +16 1 700 "(* Function definition +entry is the first function called +*)" +19 1 101 "entry" +19 6 501 "(" +19 7 101 "arg" +19 10 502 ")" +19 12 608 ":=" +19 15 505 "{" +20 1 101 "input" +20 7 607 "=" +20 9 301 "7" +20 10 507 ";" +21 1 101 "expected" +21 10 607 "=" +21 12 301 "49" +21 14 507 ";" +22 1 101 "actual" +22 8 608 ":=" +22 11 101 "square" +22 17 501 "(" +22 18 101 "input" +22 23 502 ")" +22 24 507 ";" +23 1 101 "rseult" +23 8 608 ":=" +23 11 101 "expected" +23 20 607 "=" +23 22 101 "actual" +23 28 507 ";" +24 1 407 "return" +24 8 301 "0" +24 9 507 ";" +25 1 503 "[" +25 3 201 "integer" +25 10 508 ":" +25 12 101 "input" +25 17 507 ";" +25 19 201 "integer" +25 26 508 ":" +25 28 101 "expected" +25 36 507 ";" +25 38 201 "integer" +25 45 508 ":" +25 47 101 "actual" +25 53 507 ";" +25 55 101 "boolean" +25 62 508 ":" +25 64 101 "result" +25 70 507 ";" +25 72 101 "string" +25 78 508 ":" +25 80 101 "input" +25 86 504 "]" +26 1 506 "}" diff --git a/tests/sprint1/expected/sp1_simple_alpha.tok.exp b/tests/sprint1/expected/sp1_simple_alpha.tok.exp new file mode 100644 index 0000000..8672f7a --- /dev/null +++ b/tests/sprint1/expected/sp1_simple_alpha.tok.exp @@ -0,0 +1,20 @@ +1 1 405 "type" +1 6 101 "main" +1 10 508 ":" +1 12 101 "string" +1 19 510 "->" +1 22 201 "integer" +2 1 406 "function" +2 10 101 "entry" +2 15 508 ":" +2 17 101 "main" +4 1 101 "entry" +4 6 501 "(" +4 7 101 "arg" +4 10 502 ")" +4 12 608 ":=" +4 15 505 "{" +5 5 407 "return" +5 12 301 "0" +5 13 507 ";" +6 1 506 "}" diff --git a/tests/sprint1/expected/sp1_simple_int.tok.exp b/tests/sprint1/expected/sp1_simple_int.tok.exp new file mode 100644 index 0000000..0bcbefb --- /dev/null +++ b/tests/sprint1/expected/sp1_simple_int.tok.exp @@ -0,0 +1,8 @@ +1 1 301 "45" +2 1 301 "123" +3 1 301 "8392" +4 1 301 "40" +4 4 301 "40" +5 2 301 "200" +5 6 301 "50" +5 9 301 "21783" diff --git a/tests/sprint1/expected/sp1_simple_literals.tok.exp b/tests/sprint1/expected/sp1_simple_literals.tok.exp new file mode 100644 index 0000000..788adc2 --- /dev/null +++ b/tests/sprint1/expected/sp1_simple_literals.tok.exp @@ -0,0 +1,64 @@ +1 1 304 ""this is a string"" +1 20 301 "721398" +1 27 303 "'g'" +1 32 604 "/" +1 33 101 "n" +1 36 700 "(* should print 3 tokens before this *)" +4 1 301 "12893" +4 8 101 "this" +4 13 101 "is" +4 16 101 "not" +4 20 101 "a" +4 22 101 "string" +4 29 700 "(*one valid token before this*)" +5 1 700 "(* spacey comment here +over multiple lines +will it work? *)" +7 18 306 "false" +11 1 306 "false" +12 1 700 "(**)" +14 1 101 "nullfalse" +15 2 101 "nulltrue" +16 1 302 "null" +17 1 303 "'7'" +18 1 305 "true" +19 2 301 "189" +20 1 303 "'\t'" +21 1 303 "'"'" +22 1 303 "'/'" +23 1 303 "'\n'" +24 1 303 "'\''" +25 1 303 "'\t'" +26 1 303 "'\\'" +27 1 303 "'n'" +29 2 101 "fdsf" +30 1 700 "(*/jnewjno2893u86^ Lots of random characters /n /t '") *)" +35 1 304 ""STRINGwithnotSPaces"" +36 1 303 "' '" +38 1 304 ""J"" +39 1 304 """" +40 1 304 "" "" +42 1 304 ""{SCHAR}"" +43 1 304 ""SCHAR"" +44 1 304 ""[SCHAR]"" +45 1 304 ""FINAL: I'd think this is a legal \"string\" that contains \n \t several escaped characters, isn't it?"" +46 2 101 "I" +46 4 101 "d" +46 6 101 "think" +46 12 101 "this" +46 17 101 "is" +46 20 101 "a" +46 22 101 "legal" +46 30 101 "string" +46 39 101 "that" +46 44 101 "contains" +46 53 101 "several" +46 63 101 "n" +46 66 101 "t" +46 68 101 "escaped" +46 76 101 "characters" +46 86 509 "," +46 88 101 "isn" +46 92 101 "t" +46 94 101 "it" +47 1 101 "nullLike" diff --git a/tests/sprint1/expected/sp1_variables.tok.exp b/tests/sprint1/expected/sp1_variables.tok.exp new file mode 100644 index 0000000..223288a --- /dev/null +++ b/tests/sprint1/expected/sp1_variables.tok.exp @@ -0,0 +1,13 @@ +1 1 101 "valid1" +2 1 101 "Valid2" +3 1 101 "_valid3" +4 1 101 "_valid_name_4" +5 1 101 "VALID" +6 1 301 "0" +6 2 101 "Invalid" +7 1 301 "1" +7 2 101 "invalid" +8 2 101 "invalid" +9 1 101 "invalid" +9 8 607 "=" +10 1 101 "String" diff --git a/tests/sprint1/test/sp1_comment_fix1.alpha b/tests/sprint1/test/sp1_comment_fix1.alpha index 0f2ec67..25e4ba9 100644 --- a/tests/sprint1/test/sp1_comment_fix1.alpha +++ b/tests/sprint1/test/sp1_comment_fix1.alpha @@ -1,2 +1,2 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) (***) \ No newline at end of file diff --git a/tests/sprint1/test/sp1_comment_fix2.alpha b/tests/sprint1/test/sp1_comment_fix2.alpha index 72e5ffe..0ba95b5 100644 --- a/tests/sprint1/test/sp1_comment_fix2.alpha +++ b/tests/sprint1/test/sp1_comment_fix2.alpha @@ -1,2 +1,2 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) (*(**)*) \ No newline at end of file diff --git a/tests/sprint1/test/sp1_comment_issues.alpha b/tests/sprint1/test/sp1_comment_issues.alpha index 45b244d..05d3636 100644 --- a/tests/sprint1/test/sp1_comment_issues.alpha +++ b/tests/sprint1/test/sp1_comment_issues.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) (*(**)*) (***) (******)(*\kpp*********) diff --git a/tests/sprint1/test/sp1_comments.alpha b/tests/sprint1/test/sp1_comments.alpha index 63f216b..f30501b 100644 --- a/tests/sprint1/test/sp1_comments.alpha +++ b/tests/sprint1/test/sp1_comments.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) (* hello *) (* hello *) (* I'd think this is a legal "string" that contains several \n \t diff --git a/tests/sprint1/test/sp1_general_token.alpha b/tests/sprint1/test/sp1_general_token.alpha index dcb581f..9e1389d 100644 --- a/tests/sprint1/test/sp1_general_token.alpha +++ b/tests/sprint1/test/sp1_general_token.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) This is a test 9combined 7okens 12345 diff --git a/tests/sprint1/test/sp1_keywords.alpha b/tests/sprint1/test/sp1_keywords.alpha index 8b76ac7..e60a891 100644 --- a/tests/sprint1/test/sp1_keywords.alpha +++ b/tests/sprint1/test/sp1_keywords.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) while While whiLe diff --git a/tests/sprint1/test/sp1_operators.alpha b/tests/sprint1/test/sp1_operators.alpha index eacaec4..515ce69 100644 --- a/tests/sprint1/test/sp1_operators.alpha +++ b/tests/sprint1/test/sp1_operators.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) + - * diff --git a/tests/sprint1/test/sp1_other_punc.alpha b/tests/sprint1/test/sp1_other_punc.alpha index 87bdb10..a9981db 100644 --- a/tests/sprint1/test/sp1_other_punc.alpha +++ b/tests/sprint1/test/sp1_other_punc.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) ; : , diff --git a/tests/sprint1/test/sp1_punc_grouping.alpha b/tests/sprint1/test/sp1_punc_grouping.alpha index 57df795..c512933 100644 --- a/tests/sprint1/test/sp1_punc_grouping.alpha +++ b/tests/sprint1/test/sp1_punc_grouping.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) ) a) )a diff --git a/tests/sprint1/test/sp1_real_alpha_file1.alpha b/tests/sprint1/test/sp1_real_alpha_file1.alpha index c7713be..f729f0b 100644 --- a/tests/sprint1/test/sp1_real_alpha_file1.alpha +++ b/tests/sprint1/test/sp1_real_alpha_file1.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer diff --git a/tests/sprint1/test/sp1_real_alpha_file2.alpha b/tests/sprint1/test/sp1_real_alpha_file2.alpha index 7fe7705..409d6d3 100644 --- a/tests/sprint1/test/sp1_real_alpha_file2.alpha +++ b/tests/sprint1/test/sp1_real_alpha_file2.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) (* Type definitions *) type string: 1 -> character type int2int: integer -> integer diff --git a/tests/sprint1/test/sp1_simple_alpha.alpha b/tests/sprint1/test/sp1_simple_alpha.alpha index 2d8b2ce..3f59493 100644 --- a/tests/sprint1/test/sp1_simple_alpha.alpha +++ b/tests/sprint1/test/sp1_simple_alpha.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) type main: string -> integer function entry: main diff --git a/tests/sprint1/test/sp1_simple_int.alpha b/tests/sprint1/test/sp1_simple_int.alpha index f712914..32c572d 100644 --- a/tests/sprint1/test/sp1_simple_int.alpha +++ b/tests/sprint1/test/sp1_simple_int.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) 45 123 8392 diff --git a/tests/sprint1/test/sp1_simple_literals.alpha b/tests/sprint1/test/sp1_simple_literals.alpha index ce5b0bd..ba4aa9d 100644 --- a/tests/sprint1/test/sp1_simple_literals.alpha +++ b/tests/sprint1/test/sp1_simple_literals.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) "this is a string" 721398 'g' '/n' (* should print 3 tokens before this *) ' ' diff --git a/tests/sprint1/test/sp1_variables.alpha b/tests/sprint1/test/sp1_variables.alpha index ec787c6..7e69840 100644 --- a/tests/sprint1/test/sp1_variables.alpha +++ b/tests/sprint1/test/sp1_variables.alpha @@ -1,4 +1,4 @@ -$$ TEST: [-tok] +(* TEST: [-tok] *) valid1 Valid2 _valid3 diff --git a/tests/sprint2/expected/sp2_carls_mistake.expected b/tests/sprint2/expected/sp2_carls_mistake.st.exp similarity index 80% rename from tests/sprint2/expected/sp2_carls_mistake.expected rename to tests/sprint2/expected/sp2_carls_mistake.st.exp index cee5d6f..7fe89f6 100644 --- a/tests/sprint2/expected/sp2_carls_mistake.expected +++ b/tests/sprint2/expected/sp2_carls_mistake.st.exp @@ -1,27 +1,27 @@ NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -bar2 : 001001 : : undefined : Function Definition -bar1 : 001001 : : undefined : Function Definition -foo : 001001 : : undefined : Function Definition -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function -arr : 001001 : : 1 -> integer : Type of Array -T2 : 001001 : : rec -> integer : Type of Function -T1 : 001001 : : integer -> integer : Type of Function -rec : 001001 : : Record Type : elements-2 size-8 bytes integer : 001001 : : Primitive Type : size-4 bytes address : 001001 : : Primitive Type : size-8 bytes character : 001001 : : Primitive Type : size-1 bytes string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +rec : 001001 : : Record Type : elements-2 size-8 bytes +T1 : 001001 : : integer -> integer : Type of Function +T2 : 001001 : : rec -> integer : Type of Function +arr : 001001 : : 1 -> integer : Type of Array +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 25 +foo : 001001 : : T1 : Function Definition that starts at line 13 +bar1 : 001001 : : T2 : Function Definition that starts at line 17 +bar2 : 001001 : : T2 : Function Definition that starts at line 21 ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -w : 025000 : 001001 : rec : Record Instance -result : 025000 : 001001 : integer : Primitive Instance arg : 025000 : 001001 : string : Array Instance +result : 025000 : 001001 : integer : Primitive Instance +w : 025000 : 001001 : rec : Record Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: r : 021000 : 001001 : integer : Primitive Instance s : 021000 : 001001 : integer : Primitive Instance @@ -31,5 +31,5 @@ y : 017000 : 001001 : integer ------------------------------:--------:--------:-----------------------------------:-----------------------------------: x : 013000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 001000 : 001001 : integer : Primitive Instance x : 001000 : 001001 : integer : Primitive Instance +y : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_function_types.expected b/tests/sprint2/expected/sp2_function_types.st.exp similarity index 67% rename from tests/sprint2/expected/sp2_function_types.expected rename to tests/sprint2/expected/sp2_function_types.st.exp index 391690b..707ff66 100644 --- a/tests/sprint2/expected/sp2_function_types.expected +++ b/tests/sprint2/expected/sp2_function_types.st.exp @@ -1,29 +1,29 @@ NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -entry : 001001 : : undefined : Function Definition -integer2integer2integerFunc : 001001 : : undefined : Function Definition -released : 001001 : : undefined : Function Definition -reserved : 001001 : : undefined : Function Definition -printBoolean : 001001 : : undefined : Function Definition -printCharacter : 001001 : : undefined : Function Definition -printInteger : 001001 : : undefined : Function Definition -integer2integer2integer : 001001 : : integer2integer -> integer : Type of Function -address2integer : 001001 : : address -> integer : Type of Function -integer2address : 001001 : : integer -> address : Type of Function -Boolean2Boolean2Boolean : 001001 : : Boolean2Boolean -> Boolean : Type of Function -character2character2Boolean : 001001 : : undefined -> undefined : Type of Function -integer2integer2Boolean : 001001 : : integer2integer -> Boolean : Type of Function -string2integer : 001001 : : string -> integer : Type of Function -Boolean2integer : 001001 : : Boolean -> integer : Type of Function -character2integer : 001001 : : character -> integer : Type of Function -integer2integer : 001001 : : integer -> integer : Type of Function -Boolean2Boolean : 001001 : : Boolean -> Boolean : Type of Function integer : 001001 : : Primitive Type : size-4 bytes address : 001001 : : Primitive Type : size-8 bytes character : 001001 : : Primitive Type : size-1 bytes string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +Boolean2Boolean : 001001 : : Boolean -> Boolean : Type of Function +integer2integer : 001001 : : integer -> integer : Type of Function +character2integer : 001001 : : character -> integer : Type of Function +Boolean2integer : 001001 : : Boolean -> integer : Type of Function +string2integer : 001001 : : string -> integer : Type of Function +integer2integer2Boolean : 001001 : : integer2integer -> Boolean : Type of Function +character2character2Boolean : 001001 : : undefined -> undefined : Type of Function +Boolean2Boolean2Boolean : 001001 : : Boolean2Boolean -> Boolean : Type of Function +integer2address : 001001 : : integer -> address : Type of Function +address2integer : 001001 : : address -> integer : Type of Function +integer2integer2integer : 001001 : : integer2integer -> integer : Type of Function +printInteger : 001001 : : integer2integer : Function not defined before runtime +printCharacter : 001001 : : character2integer : Function not defined before runtime +printBoolean : 001001 : : Boolean2integer : Function not defined before runtime +reserved : 001001 : : integer2address : Function not defined before runtime +released : 001001 : : address2integer : Function not defined before runtime +integer2integer2integerFunc : 001001 : : integer2integer2integer : Function not defined before runtime +entry : 001001 : : string2integer : Function not defined before runtime diff --git a/tests/sprint2/expected/sp2_integer_binary_op.expected b/tests/sprint2/expected/sp2_integer_binary_op.st.exp similarity index 83% rename from tests/sprint2/expected/sp2_integer_binary_op.expected rename to tests/sprint2/expected/sp2_integer_binary_op.st.exp index d24c170..b418814 100644 --- a/tests/sprint2/expected/sp2_integer_binary_op.expected +++ b/tests/sprint2/expected/sp2_integer_binary_op.st.exp @@ -1,21 +1,21 @@ NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -testarr : 001001 : : 1 -> integer : Type of Array -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function integer : 001001 : : Primitive Type : size-4 bytes address : 001001 : : Primitive Type : size-8 bytes character : 001001 : : Primitive Type : size-1 bytes string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 5 +testarr : 001001 : : 1 -> integer : Type of Array ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -b1 : 005000 : 001001 : Boolean : Primitive Instance -b2 : 005000 : 001001 : Boolean : Primitive Instance -arr2 : 005000 : 001001 : testarr : Array Instance -arr : 005000 : 001001 : testarr : Array Instance -x : 005000 : 001001 : integer : Primitive Instance arg : 005000 : 001001 : string : Array Instance +x : 005000 : 001001 : integer : Primitive Instance +arr : 005000 : 001001 : testarr : Array Instance +arr2 : 005000 : 001001 : testarr : Array Instance +b2 : 005000 : 001001 : Boolean : Primitive Instance +b1 : 005000 : 001001 : Boolean : Primitive Instance diff --git a/tests/sprint2/expected/sp2_invalid_multiple_params_no_as.expected b/tests/sprint2/expected/sp2_invalid_multiple_params_no_as.st.exp similarity index 82% rename from tests/sprint2/expected/sp2_invalid_multiple_params_no_as.expected rename to tests/sprint2/expected/sp2_invalid_multiple_params_no_as.st.exp index 509c6eb..df23356 100644 --- a/tests/sprint2/expected/sp2_invalid_multiple_params_no_as.expected +++ b/tests/sprint2/expected/sp2_invalid_multiple_params_no_as.st.exp @@ -1,20 +1,20 @@ NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -test : 001001 : : undefined : Function Definition -main : 001001 : : rec -> integer : Type of Function -rec : 001001 : : Record Type : elements-2 size-8 bytes integer : 001001 : : Primitive Type : size-4 bytes address : 001001 : : Primitive Type : size-8 bytes character : 001001 : : Primitive Type : size-1 bytes string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +rec : 001001 : : Record Type : elements-2 size-8 bytes +main : 001001 : : rec -> integer : Type of Function +test : 001001 : : main : Function Definition that starts at line 5 ------------------------------:--------:--------:-----------------------------------:-----------------------------------: arg : 005000 : 001001 : integer : Primitive Instance arg2 : 005000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 001000 : 001001 : integer : Primitive Instance x : 001000 : 001001 : integer : Primitive Instance +y : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_invalid_recop.expected b/tests/sprint2/expected/sp2_invalid_recop.st.exp similarity index 82% rename from tests/sprint2/expected/sp2_invalid_recop.expected rename to tests/sprint2/expected/sp2_invalid_recop.st.exp index 642ad85..b6a78e2 100644 --- a/tests/sprint2/expected/sp2_invalid_recop.expected +++ b/tests/sprint2/expected/sp2_invalid_recop.st.exp @@ -1,20 +1,20 @@ NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -rec : 001001 : : Record Type : elements-2 size-8 bytes -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function integer : 001001 : : Primitive Type : size-4 bytes address : 001001 : : Primitive Type : size-8 bytes character : 001001 : : Primitive Type : size-1 bytes string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 6 +rec : 001001 : : Record Type : elements-2 size-8 bytes ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -w : 006000 : 001001 : rec : Record Instance arg : 006000 : 001001 : string : Array Instance +w : 006000 : 001001 : rec : Record Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 004000 : 001001 : integer : Primitive Instance x : 004000 : 001001 : integer : Primitive Instance +y : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_invalid_release.expected b/tests/sprint2/expected/sp2_invalid_release.st.exp similarity index 85% rename from tests/sprint2/expected/sp2_invalid_release.expected rename to tests/sprint2/expected/sp2_invalid_release.st.exp index 1ac0274..823a68c 100644 --- a/tests/sprint2/expected/sp2_invalid_release.expected +++ b/tests/sprint2/expected/sp2_invalid_release.st.exp @@ -1,17 +1,17 @@ NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -rec : 001001 : : Record Type : elements-2 size-8 bytes integer : 001001 : : Primitive Type : size-4 bytes address : 001001 : : Primitive Type : size-8 bytes character : 001001 : : Primitive Type : size-1 bytes string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +rec : 001001 : : Record Type : elements-2 size-8 bytes ------------------------------:--------:--------:-----------------------------------:-----------------------------------: w : 003000 : 001001 : rec : Record Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 001000 : 001001 : integer : Primitive Instance x : 001000 : 001001 : integer : Primitive Instance +y : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_library.expected b/tests/sprint2/expected/sp2_library.st.exp similarity index 79% rename from tests/sprint2/expected/sp2_library.expected rename to tests/sprint2/expected/sp2_library.st.exp index 80a9611..a625233 100644 --- a/tests/sprint2/expected/sp2_library.expected +++ b/tests/sprint2/expected/sp2_library.st.exp @@ -1,39 +1,38 @@ NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -entry : 001001 : : undefined : Function Definition -printBoolean : 001001 : : undefined : Function Definition -printCharacter : 001001 : : undefined : Function Definition -printInteger : 001001 : : undefined : Function Definition -address2integer : 001001 : : address -> integer : Type of Function -integer2address : 001001 : : integer -> address : Type of Function -BooleanXBoolean2Boolean : 001001 : : BooleanXBoolean -> Boolean : Type of Function -characterXcharacter2Boolean : 001001 : : characterXcharacter -> Boolean : Type of Function -integerXinteger2Boolean : 001001 : : integerXinteger -> Boolean : Type of Function -integerXinteger2integer : 001001 : : integerXinteger -> integer : Type of Function -string2integer : 001001 : : string -> integer : Type of Function -Boolean2integer : 001001 : : Boolean -> integer : Type of Function -character2integer : 001001 : : character -> integer : Type of Function -integer2integer : 001001 : : integer -> integer : Type of Function -Boolean2Boolean : 001001 : : Boolean -> Boolean : Type of Function -integerXinteger : 001001 : : Record Type : elements-2 size-8 bytes -characterXcharacter : 001001 : : Record Type : elements-2 size-2 bytes -BooleanXBoolean : 001001 : : Record Type : elements-2 size-8 bytes -string : 001001 : : 1 -> character : Type of Array integer : 001001 : : Primitive Type : size-4 bytes address : 001001 : : Primitive Type : size-8 bytes character : 001001 : : Primitive Type : size-1 bytes string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +BooleanXBoolean : 001001 : : Record Type : elements-2 size-2 bytes +characterXcharacter : 001001 : : Record Type : elements-2 size-2 bytes +integerXinteger : 001001 : : Record Type : elements-2 size-8 bytes +Boolean2Boolean : 001001 : : Boolean -> Boolean : Type of Function +integer2integer : 001001 : : integer -> integer : Type of Function +character2integer : 001001 : : character -> integer : Type of Function +Boolean2integer : 001001 : : Boolean -> integer : Type of Function +string2integer : 001001 : : string -> integer : Type of Function +integerXinteger2integer : 001001 : : integerXinteger -> integer : Type of Function +integerXinteger2Boolean : 001001 : : integerXinteger -> Boolean : Type of Function +characterXcharacter2Boolean : 001001 : : characterXcharacter -> Boolean : Type of Function +BooleanXBoolean2Boolean : 001001 : : BooleanXBoolean -> Boolean : Type of Function +integer2address : 001001 : : integer -> address : Type of Function +address2integer : 001001 : : address -> integer : Type of Function +printInteger : 001001 : : integer2integer : Function not defined before runtime +printCharacter : 001001 : : character2integer : Function not defined before runtime +printBoolean : 001001 : : Boolean2integer : Function not defined before runtime +entry : 001001 : : string2integer : Function not defined before runtime ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 015000 : 001001 : integer : Primitive Instance x : 015000 : 001001 : integer : Primitive Instance +y : 015000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 014000 : 001001 : character : Primitive Instance x : 014000 : 001001 : character : Primitive Instance +y : 014000 : 001001 : character : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 013000 : 001001 : Boolean : Primitive Instance x : 013000 : 001001 : Boolean : Primitive Instance +y : 013000 : 001001 : Boolean : Primitive Instance diff --git a/tests/sprint2/expected/sp2_llnode.st.exp b/tests/sprint2/expected/sp2_llnode.st.exp new file mode 100644 index 0000000..8b78bd3 --- /dev/null +++ b/tests/sprint2/expected/sp2_llnode.st.exp @@ -0,0 +1,58 @@ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-1 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : reserve type : Function not defined before runtime +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 68 +rec : 001001 : : Record Type : elements-2 size-8 bytes +T1 : 001001 : : integer -> integer : Type of Function +T2 : 001001 : : rec -> integer : Type of Function +llnode : 001001 : : Record Type : elements-3 size-24 bytes +list : 001001 : : integer -> llnode : Type of Function +foo : 001001 : : T1 : Function Definition that starts at line 45 +bar1 : 001001 : : T2 : Function Definition that starts at line 49 +bar2 : 001001 : : T2 : Function Definition that starts at line 53 +make_list : 001001 : : list : Function Definition that starts at line 16 +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +arg : 068000 : 001001 : string : Array Instance +result : 068000 : 001001 : integer : Primitive Instance +w : 068000 : 001001 : rec : Record Instance +li : 068000 : 001001 : llnode : Record Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +r : 053000 : 001001 : integer : Primitive Instance +s : 053000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +x : 058012 : 053000 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +a : 049000 : 001001 : integer : Primitive Instance +b : 049000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +x : 045000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +a : 016000 : 001001 : integer : Primitive Instance +orig_a : 016000 : 001001 : integer : Primitive Instance +ret : 016000 : 001001 : llnode : Record Instance +curr : 016000 : 001001 : llnode : Record Instance +temp : 016000 : 001001 : llnode : Record Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +prev : 008000 : 001001 : llnode : Record Instance +val : 008000 : 001001 : integer : Primitive Instance +next : 008000 : 001001 : llnode : Record Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +x : 004000 : 001001 : integer : Primitive Instance +y : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_llnode.expected b/tests/sprint2/expected/sp2_llnode_bad.st.exp similarity index 72% rename from tests/sprint2/expected/sp2_llnode.expected rename to tests/sprint2/expected/sp2_llnode_bad.st.exp index ab13e6f..cebad8b 100644 --- a/tests/sprint2/expected/sp2_llnode.expected +++ b/tests/sprint2/expected/sp2_llnode_bad.st.exp @@ -1,66 +1,58 @@ NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -make_list : 001001 : : undefined : Function Definition -bar2 : 001001 : : undefined : Function Definition -bar1 : 001001 : : undefined : Function Definition -foo : 001001 : : undefined : Function Definition -list : 001001 : : integer -> llnode : Type of Function -llnode : 001001 : : Record Type : elements-3 size-24 bytes -T2 : 001001 : : rec -> integer : Type of Function -T1 : 001001 : : integer -> integer : Type of Function -rec : 001001 : : Record Type : elements-2 size-8 bytes -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function integer : 001001 : : Primitive Type : size-4 bytes address : 001001 : : Primitive Type : size-8 bytes character : 001001 : : Primitive Type : size-1 bytes string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 69 +rec : 001001 : : Record Type : elements-2 size-8 bytes +T1 : 001001 : : integer -> integer : Type of Function +T2 : 001001 : : rec -> integer : Type of Function +llnode : 001001 : : Record Type : elements-3 size-24 bytes +list : 001001 : : integer -> llnode : Type of Function +foo : 001001 : : T1 : Function Definition that starts at line 46 +bar1 : 001001 : : T2 : Function Definition that starts at line 50 +bar2 : 001001 : : T2 : Function Definition that starts at line 54 +make_list : 001001 : : list : Function Definition that starts at line 16 ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -li : 069000 : 001001 : llnode : Record Instance -w : 069000 : 001001 : rec : Record Instance -result : 069000 : 001001 : integer : Primitive Instance arg : 069000 : 001001 : string : Array Instance +result : 069000 : 001001 : integer : Primitive Instance +w : 069000 : 001001 : rec : Record Instance +li : 069000 : 001001 : llnode : Record Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: r : 054000 : 001001 : integer : Primitive Instance s : 054000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: x : 059012 : 054000 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 062028 : 059012 : : Empty Scope ------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 055021 : 054000 : : Empty Scope ------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 056026 : 055021 : : Empty Scope ------------------------------:--------:--------:-----------------------------------:-----------------------------------: a : 050000 : 001001 : integer : Primitive Instance b : 050000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: x : 046000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -temp : 016000 : 001001 : address : Primitive Instance -curr : 016000 : 001001 : address : Primitive Instance -ret : 016000 : 001001 : address : Primitive Instance -orig_a : 016000 : 001001 : integer : Primitive Instance a : 016000 : 001001 : integer : Primitive Instance +orig_a : 016000 : 001001 : integer : Primitive Instance +ret : 016000 : 001001 : llnode : Record Instance +curr : 016000 : 001001 : llnode : Record Instance +temp : 016000 : 001001 : llnode : Record Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 021012 : 016000 : : Empty Scope ------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 026023 : 021012 : : Empty Scope ------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 035020 : 026023 : : Empty Scope ------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 031034 : 026023 : : Empty Scope ------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 019029 : 016000 : : Empty Scope ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -next : 008000 : 001001 : llnode : Record Instance -val : 008000 : 001001 : integer : Primitive Instance prev : 008000 : 001001 : llnode : Record Instance +val : 008000 : 001001 : integer : Primitive Instance +next : 008000 : 001001 : llnode : Record Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 004000 : 001001 : integer : Primitive Instance x : 004000 : 001001 : integer : Primitive Instance +y : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_one_line.expected b/tests/sprint2/expected/sp2_one_line.st.exp similarity index 77% rename from tests/sprint2/expected/sp2_one_line.expected rename to tests/sprint2/expected/sp2_one_line.st.exp index dcdd20a..f8d9751 100644 --- a/tests/sprint2/expected/sp2_one_line.expected +++ b/tests/sprint2/expected/sp2_one_line.st.exp @@ -1,22 +1,22 @@ NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -bar2 : 001001 : : undefined : Function Definition -bar1 : 001001 : : undefined : Function Definition -foo : 001001 : : undefined : Function Definition -T2 : 001001 : : rec -> integer : Type of Function -T1 : 001001 : : integer -> integer : Type of Function -rec : 001001 : : Record Type : elements-2 size-8 bytes -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function integer : 001001 : : Primitive Type : size-4 bytes address : 001001 : : Primitive Type : size-8 bytes character : 001001 : : Primitive Type : size-1 bytes string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function not defined before runtime +rec : 001001 : : Record Type : elements-2 size-8 bytes +T1 : 001001 : : integer -> integer : Type of Function +T2 : 001001 : : rec -> integer : Type of Function +foo : 001001 : : T1 : Function Definition that starts at line 1 +bar1 : 001001 : : T2 : Function Definition that starts at line 1 +bar2 : 001001 : : T2 : Function not defined before runtime ------------------------------:--------:--------:-----------------------------------:-----------------------------------: : 000000 : 001001 : : Empty Scope ------------------------------:--------:--------:-----------------------------------:-----------------------------------: @@ -25,5 +25,5 @@ undefined : 001000 : 001001 : integer ------------------------------:--------:--------:-----------------------------------:-----------------------------------: x : 001000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 001000 : 001001 : integer : Primitive Instance x : 001000 : 001001 : integer : Primitive Instance +y : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_presidence.expected b/tests/sprint2/expected/sp2_presidence.st.exp similarity index 84% rename from tests/sprint2/expected/sp2_presidence.expected rename to tests/sprint2/expected/sp2_presidence.st.exp index 80d2312..2c97464 100644 --- a/tests/sprint2/expected/sp2_presidence.expected +++ b/tests/sprint2/expected/sp2_presidence.st.exp @@ -1,23 +1,23 @@ NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -entry : 001001 : : undefined : Function Definition -rec : 001001 : : Record Type : elements-2 size-8 bytes -main : 001001 : : string -> integer : Type of Function integer : 001001 : : Primitive Type : size-4 bytes address : 001001 : : Primitive Type : size-8 bytes character : 001001 : : Primitive Type : size-1 bytes string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +rec : 001001 : : Record Type : elements-2 size-8 bytes +entry : 001001 : : main : Function Definition that starts at line 6 ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -arg_bool : 006000 : 001001 : Boolean : Primitive Instance -arg_record : 006000 : 001001 : rec : Record Instance -arg_y : 006000 : 001001 : integer : Primitive Instance -arg_x : 006000 : 001001 : integer : Primitive Instance arg : 006000 : 001001 : string : Array Instance +arg_x : 006000 : 001001 : integer : Primitive Instance +arg_y : 006000 : 001001 : integer : Primitive Instance +arg_record : 006000 : 001001 : rec : Record Instance +arg_bool : 006000 : 001001 : Boolean : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -rec_y : 002000 : 001001 : integer : Primitive Instance rec_x : 002000 : 001001 : integer : Primitive Instance +rec_y : 002000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_simple.expected b/tests/sprint2/expected/sp2_simple.st.exp similarity index 77% rename from tests/sprint2/expected/sp2_simple.expected rename to tests/sprint2/expected/sp2_simple.st.exp index 649bea7..71d24c9 100644 --- a/tests/sprint2/expected/sp2_simple.expected +++ b/tests/sprint2/expected/sp2_simple.st.exp @@ -1,16 +1,16 @@ NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function integer : 001001 : : Primitive Type : size-4 bytes address : 001001 : : Primitive Type : size-8 bytes character : 001001 : : Primitive Type : size-1 bytes string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 4 ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -x : 004000 : 001001 : integer : Primitive Instance arg : 004000 : 001001 : string : Array Instance +x : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_sp2_arrayargs.expected b/tests/sprint2/expected/sp2_sp2_arrayargs.st.exp similarity index 79% rename from tests/sprint2/expected/sp2_sp2_arrayargs.expected rename to tests/sprint2/expected/sp2_sp2_arrayargs.st.exp index 0db9d5a..b76e609 100644 --- a/tests/sprint2/expected/sp2_sp2_arrayargs.expected +++ b/tests/sprint2/expected/sp2_sp2_arrayargs.st.exp @@ -1,17 +1,16 @@ NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -a_of_s : 001001 : : 1 -> string : Type of Array -string : 001001 : : 1 -> character : Type of Array integer : 001001 : : Primitive Type : size-4 bytes address : 001001 : : Primitive Type : size-8 bytes character : 001001 : : Primitive Type : size-1 bytes string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +a_of_s : 001001 : : 1 -> string : Type of Array ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -many_names : 006000 : 001001 : a_of_s : Array Instance -another_name : 006000 : 001001 : string : Array Instance one_name : 006000 : 001001 : string : Array Instance +another_name : 006000 : 001001 : string : Array Instance +many_names : 006000 : 001001 : a_of_s : Array Instance diff --git a/tests/sprint2/expected/sp2_valid_assignable_and_mem.expected b/tests/sprint2/expected/sp2_valid_assignable_and_mem.expected deleted file mode 100644 index aa4b733..0000000 --- a/tests/sprint2/expected/sp2_valid_assignable_and_mem.expected +++ /dev/null @@ -1,21 +0,0 @@ -NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -T2 : 001001 : : rec -> integer : Type of Function -rec : 001001 : : Record Type : elements-2 size-8 bytes -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function -integer : 001001 : : Primitive Type : size-4 bytes -address : 001001 : : Primitive Type : size-8 bytes -character : 001001 : : Primitive Type : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes -reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition -release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -w : 007000 : 001001 : rec : Record Instance -arg : 007000 : 001001 : string : Array Instance -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 004000 : 001001 : integer : Primitive Instance -x : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint3/expected/sp3_primitive_type_check.expected b/tests/sprint2/expected/sp2_valid_assignable_and_mem.st.exp similarity index 50% rename from tests/sprint3/expected/sp3_primitive_type_check.expected rename to tests/sprint2/expected/sp2_valid_assignable_and_mem.st.exp index 0a57752..e755b52 100644 --- a/tests/sprint3/expected/sp3_primitive_type_check.expected +++ b/tests/sprint2/expected/sp2_valid_assignable_and_mem.st.exp @@ -1,19 +1,13 @@ NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function integer : 001001 : : Primitive Type : size-4 bytes address : 001001 : : Primitive Type : size-8 bytes character : 001001 : : Primitive Type : size-1 bytes string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -bool : 015000 : 001001 : Boolean : Primitive Instance -char : 015000 : 001001 : character : Primitive Instance -add : 015000 : 001001 : address : Primitive Instance -i : 015000 : 001001 : integer : Primitive Instance -arg : 015000 : 001001 : string : Array Instance + : 000000 : 001001 : : Empty Scope diff --git a/tests/sprint2/test/sp2_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha index b7fa8ee..72fa548 100644 --- a/tests/sprint2/test/sp2_carls_mistake.alpha +++ b/tests/sprint2/test/sp2_carls_mistake.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type rec: [integer: x; integer: y] type T1: integer -> integer diff --git a/tests/sprint2/test/sp2_function_types.alpha b/tests/sprint2/test/sp2_function_types.alpha index 62711c3..00dba5a 100644 --- a/tests/sprint2/test/sp2_function_types.alpha +++ b/tests/sprint2/test/sp2_function_types.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type Boolean2Boolean: Boolean -> Boolean type integer2integer: integer -> integer type character2integer: character -> integer diff --git a/tests/sprint2/test/sp2_integer_binary_op.alpha b/tests/sprint2/test/sp2_integer_binary_op.alpha index 2dfeb73..cd14c82 100644 --- a/tests/sprint2/test/sp2_integer_binary_op.alpha +++ b/tests/sprint2/test/sp2_integer_binary_op.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type main: string -> integer function entry: main type testarr : 1 -> integer diff --git a/tests/sprint2/test/sp2_invalid_multiple_params_no_as.alpha b/tests/sprint2/test/sp2_invalid_multiple_params_no_as.alpha index 805fb6e..882688e 100644 --- a/tests/sprint2/test/sp2_invalid_multiple_params_no_as.alpha +++ b/tests/sprint2/test/sp2_invalid_multiple_params_no_as.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type rec: [integer: x; integer: y] type main: rec -> integer function test: main diff --git a/tests/sprint2/test/sp2_invalid_recop.alpha b/tests/sprint2/test/sp2_invalid_recop.alpha index 41b3a55..79202f5 100644 --- a/tests/sprint2/test/sp2_invalid_recop.alpha +++ b/tests/sprint2/test/sp2_invalid_recop.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type main: string -> integer function entry: main diff --git a/tests/sprint2/test/sp2_invalid_release.alpha b/tests/sprint2/test/sp2_invalid_release.alpha index 2bd645a..e29ac0b 100644 --- a/tests/sprint2/test/sp2_invalid_release.alpha +++ b/tests/sprint2/test/sp2_invalid_release.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type rec: [integer: x; integer: y] entry (arg) := { diff --git a/tests/sprint2/test/sp2_library.alpha b/tests/sprint2/test/sp2_library.alpha index 82120be..d0c9d6c 100644 --- a/tests/sprint2/test/sp2_library.alpha +++ b/tests/sprint2/test/sp2_library.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) (* At compiler start-up your program should create symbol table entries for the four primitive types: Boolean (1 byte) diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index c78687d..7367fb5 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type main: string -> integer function entry: main diff --git a/tests/sprint2/test/sp2_llnode_bad.alpha b/tests/sprint2/test/sp2_llnode_bad.alpha index 4eab1ae..0862fa0 100644 --- a/tests/sprint2/test/sp2_llnode_bad.alpha +++ b/tests/sprint2/test/sp2_llnode_bad.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type main: string -> integer function entry: main diff --git a/tests/sprint2/test/sp2_one_line.alpha b/tests/sprint2/test/sp2_one_line.alpha index f1062e9..5502979 100644 --- a/tests/sprint2/test/sp2_one_line.alpha +++ b/tests/sprint2/test/sp2_one_line.alpha @@ -1 +1,2 @@ +(* TEST: [-st] *) type main: string -> integer function entry: main type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer function foo : T1 function bar1 : T2 function bar2 : T2 foo(x) := { return x * x; } bar1(a) := { return a.x * a.y; } bar2 as (r,s) := { return r * s; } entry(arg) := { [ integer: result ; rec: w] result := foo(5); w := reserve w; w.x := 5; w.y := 7; result := bar1(w); result := bar2(5,7); return 0; } diff --git a/tests/sprint2/test/sp2_presidence.alpha b/tests/sprint2/test/sp2_presidence.alpha index d60611d..a81a5eb 100644 --- a/tests/sprint2/test/sp2_presidence.alpha +++ b/tests/sprint2/test/sp2_presidence.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type main: string -> integer type rec: [integer: rec_x; integer: rec_y] diff --git a/tests/sprint2/test/sp2_simple.alpha b/tests/sprint2/test/sp2_simple.alpha index 4042a5a..bc56caf 100644 --- a/tests/sprint2/test/sp2_simple.alpha +++ b/tests/sprint2/test/sp2_simple.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type main: string -> integer function entry: main diff --git a/tests/sprint2/test/sp2_sp2_arrayargs.alpha b/tests/sprint2/test/sp2_sp2_arrayargs.alpha index dfb0332..9ea2a1c 100644 --- a/tests/sprint2/test/sp2_sp2_arrayargs.alpha +++ b/tests/sprint2/test/sp2_sp2_arrayargs.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type string: 1 -> character type a_of_s: 1 -> string diff --git a/tests/sprint2/test/sp2_sp2_arrayargs.alpha~ b/tests/sprint2/test/sp2_sp2_arrayargs.alpha~ deleted file mode 100644 index ce1673d..0000000 --- a/tests/sprint2/test/sp2_sp2_arrayargs.alpha~ +++ /dev/null @@ -1,16 +0,0 @@ -type string: 1 -> character -type a_of_s: 1 -> string - -(* maybe some other type definitions *) - -entry(arg) := { - [ string: one_name; string: another_name; a_of_s: many_names ] - another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *) - many_names := reserve a_of_s(3); - many_names(0) := one_name; - many_names(1) := another_name; - many_names(2) := reserve a_of_s(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *) - many_names(2)(0) := "P"; - - return 0; -} \ No newline at end of file diff --git a/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha b/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha index a49c5dd..9fe5655 100644 --- a/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha +++ b/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha @@ -1,4 +1,5 @@ -type main: string -> integer +(* TEST: [-st] *) +ype main: string -> integer function entry: main type rec: [integer: x; integer: y] diff --git a/tests/sprint3/expected/sp3_and_or_type_check.asc.exp b/tests/sprint3/expected/sp3_and_or_type_check.asc.exp new file mode 100644 index 0000000..fb7fe0c --- /dev/null +++ b/tests/sprint3/expected/sp3_and_or_type_check.asc.exp @@ -0,0 +1,92 @@ +001: type rec: [integer: x; integer: y] +002: type main: rec -> integer +003: function test: main +004: +005: test (arg) := { +006: [integer:x; Boolean: b] +007: while (true) { +008: x := 0; + LINE (8:9) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t1 of type integer + LINE (8:9) ** TYPE ERROR: Invalid type passed to assignable. + LINE (8:3) ** TYPE ERROR: Undefined variable x +009: } +010: +011: while (7) { +012: x := 1; + LINE (12:9) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t3 of type integer + LINE (12:9) ** TYPE ERROR: Invalid type passed to assignable. + LINE (12:3) ** TYPE ERROR: Undefined variable x +013: } +014: +015: if (true) then { +016: x := 1; + LINE (16:9) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t5 of type integer + LINE (16:9) ** TYPE ERROR: Invalid type passed to assignable. + LINE (16:3) ** TYPE ERROR: Undefined variable x +017: } else { +018: x := 0; + LINE (18:9) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t6 of type integer + LINE (18:9) ** TYPE ERROR: Invalid type passed to assignable. + LINE (18:3) ** TYPE ERROR: Undefined variable x +019: } +020: +021: if (x) then { + LINE (21:6) ** TYPE ERROR: Undefined variable x +022: x := 0; + LINE (22:9) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t7 of type integer + LINE (22:9) ** TYPE ERROR: Invalid type passed to assignable. + LINE (22:3) ** TYPE ERROR: Undefined variable x +023: } else { +024: x := 1; + LINE (24:9) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t8 of type integer + LINE (24:9) ** TYPE ERROR: Invalid type passed to assignable. + LINE (24:3) ** TYPE ERROR: Undefined variable x +025: } +026: +027: b := b | b; + LINE (27:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (27:12) ** TYPE ERROR: Object undefined of type undefined and Object undefined of type undefined must both be Boolean + LINE (27:11) ** TYPE ERROR: Undefined variable b + LINE (27:7) ** TYPE ERROR: Undefined variable b + LINE (27:2) ** TYPE ERROR: Undefined variable b +028: b := b & b; + LINE (28:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (28:12) ** TYPE ERROR: Object undefined of type undefined and Object undefined of type undefined must both be Boolean + LINE (28:11) ** TYPE ERROR: Undefined variable b + LINE (28:7) ** TYPE ERROR: Undefined variable b + LINE (28:2) ** TYPE ERROR: Undefined variable b +029: b := 1 | b; + LINE (29:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (29:12) ** TYPE ERROR: Object $t9 of type integer and Object undefined of type undefined must both be Boolean + LINE (29:11) ** TYPE ERROR: Undefined variable b + LINE (29:2) ** TYPE ERROR: Undefined variable b +030: b := b | 1; + LINE (30:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (30:12) ** TYPE ERROR: Object undefined of type undefined and Object $t10 of type integer must both be Boolean + LINE (30:7) ** TYPE ERROR: Undefined variable b + LINE (30:2) ** TYPE ERROR: Undefined variable b +031: b := b & 1; + LINE (31:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (31:12) ** TYPE ERROR: Object undefined of type undefined and Object $t11 of type integer must both be Boolean + LINE (31:7) ** TYPE ERROR: Undefined variable b + LINE (31:2) ** TYPE ERROR: Undefined variable b +032: b := 1 & b; + LINE (32:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (32:12) ** TYPE ERROR: Object $t12 of type integer and Object undefined of type undefined must both be Boolean + LINE (32:11) ** TYPE ERROR: Undefined variable b + LINE (32:2) ** TYPE ERROR: Undefined variable b +033: b := 1 = 1; + LINE (33:12) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t15 of type Boolean + LINE (33:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (33:2) ** TYPE ERROR: Undefined variable b +034: +035: +036: +037: b := 1 = b; + LINE (37:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (37:12) ** TYPE ERROR: Object $t16 of type integer and Object undefined of type undefined must both be the same type + LINE (37:11) ** TYPE ERROR: Undefined variable b + LINE (37:2) ** TYPE ERROR: Undefined variable b +038: +039: return 0; +040: } diff --git a/tests/sprint3/expected/sp3_and_or_type_check.expected b/tests/sprint3/expected/sp3_and_or_type_check.expected deleted file mode 100644 index 493f53b..0000000 --- a/tests/sprint3/expected/sp3_and_or_type_check.expected +++ /dev/null @@ -1,50 +0,0 @@ -001: type rec: [integer: x; integer: y] -002: type main: rec -> integer -003: function test: main -004: -005: test (arg) := { -006: [integer:x; Boolean: b] -007: while (true) { -008: x := 0; -009: } -010: -011: while (7) { -012: x := 1; -013: } -014: -015: if (true) then { -016: x := 1; -017: } else { -018: x := 0; -019: } -020: -021: if (x) then { -022: x := 0; -023: } else { -024: x := 1; -025: } -026: -027: b := b | b; -028: b := b & b; -029: b := 1 | b; - LINE (29:12) ** TYPE ERROR: b != undefined - -030: b := b | 1; - LINE (30:12) ** TYPE ERROR: b != undefined - -031: b := b & 1; - LINE (31:12) ** TYPE ERROR: b != undefined - -032: b := 1 & b; - LINE (32:12) ** TYPE ERROR: b != undefined - -033: b := 1 = 1; -034: -035: -036: -037: b := 1 = b; - LINE (37:12) ** TYPE ERROR: b != undefined - -038: -039: return 0; -040: } diff --git a/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.asc.exp b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.asc.exp new file mode 100644 index 0000000..b9eabd2 --- /dev/null +++ b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.asc.exp @@ -0,0 +1,17 @@ +001: type main: string -> integer +002: function entry: main +003: +004: entry (arg) := { +005: [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] +006: +007: b2 := 3 < x; +008: b1 := arr = 2; + LINE (8:18) ** TYPE ERROR: Assignable Assign Expression - Object b1 of type Boolean != Object undefined of type undefined + LINE (8:18) ** TYPE ERROR: Object arr of type address and Object $t2 of type integer must both be the same type +009: b1 := 6<7 & arr2=7; + LINE (9:23) ** TYPE ERROR: Assignable Assign Expression - Object b1 of type Boolean != Object undefined of type undefined + LINE (9:23) ** TYPE ERROR: Object $t5 of type Boolean and Object undefined of type undefined must both be Boolean + LINE (9:23) ** TYPE ERROR: Object arr2 of type address and Object $t6 of type integer must both be the same type +010: +011: return 0; +012: } diff --git a/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected deleted file mode 100644 index f95e765..0000000 --- a/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected +++ /dev/null @@ -1,16 +0,0 @@ -001: type main: string -> integer -002: function entry: main -003: -004: entry (arg) := { -005: [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] -006: -007: b2 := 3 < x; -008: b1 := arr = 2; - LINE (8:18) ** TYPE ERROR: b1 != undefined - -009: b1 := 6<7 & arr2=7; - LINE (9:23) ** TYPE ERROR: b1 != undefined - -010: -011: return 0; -012: } diff --git a/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected b/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.asc.exp similarity index 52% rename from tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected rename to tests/sprint3/expected/sp3_boolean_unary_op_typecheck.asc.exp index 39237bc..181f3c4 100644 --- a/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected +++ b/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.asc.exp @@ -6,8 +6,8 @@ 006: 007: b2 := !(3 < 2); 008: b1 := !5; - LINE (8:13) ** TYPE ERROR: b1 != undefined - + LINE (8:13) ** TYPE ERROR: Assignable Assign Expression - Object b1 of type Boolean != Object undefined of type undefined + LINE (8:12) ** TYPE ERROR: Object $t4 of type integer is not of type Boolean and can't be negated 009: 010: return 0; 011: } diff --git a/tests/sprint3/expected/sp3_carls_second_mistake.asc.exp b/tests/sprint3/expected/sp3_carls_second_mistake.asc.exp new file mode 100644 index 0000000..51a366e --- /dev/null +++ b/tests/sprint3/expected/sp3_carls_second_mistake.asc.exp @@ -0,0 +1,36 @@ +001: type main: string -> integer +002: function entry: main +003: +004: type string: 1 -> character +005: type a_of_s: 1 -> string +006: +007: (* maybe some other type definitions *) +008: +009: entry (arg) := { +010: [ string: one_name; string: another_name; a_of_s: many_names ] +011: +012: one_name := "a string literal"; +013: another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *) + LINE (13:44) ** TYPE ERROR: Assignable Assign Expression - Object another_name of type string != Object undefined of type undefined +014: another_name(0) := 'C'; +015: another_name(1) := 'a'; +016: another_name(2) := 'r'; +017: another_name(3) := 'l'; +018: many_names := reserve many_names(3); + LINE (18:40) ** TYPE ERROR: Assignable Assign Expression - Object many_names of type a_of_s != Object undefined of type undefined +019: many_names(0) := one_name; +020: many_names(1) := another_name; +021: many_names(2) := reserve many_names(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *) + LINE (21:45) ** SYNTAX ERROR: Incorrect syntax at token ')' + LINE (21:44) ** SYNTAX ERROR: Incorrect syntax at token '6' + LINE (21:43) ** SYNTAX ERROR: Incorrect syntax at token '(' + LINE (21:43) ** TYPE ERROR: Assignable Assign Expression - Object $t20 of type string != Object undefined of type undefined +022: many_names(2)(0) := 'P'; +023: many_names(2)(1) := 'a'; +024: many_names(2)(2) := 'r'; +025: many_names(2)(3) := 't'; +026: many_names(2)(4) := 'h'; +027: many_names(2)(5) := 'o'; +028: +029: return 0; +030: } \ No newline at end of file diff --git a/tests/sprint3/expected/sp3_carls_second_mistake.expected b/tests/sprint3/expected/sp3_carls_second_mistake.expected deleted file mode 100644 index 6f509e0..0000000 --- a/tests/sprint3/expected/sp3_carls_second_mistake.expected +++ /dev/null @@ -1,20 +0,0 @@ -NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -a_of_s : 001001 : : 1 -> string : Type of Array -string : 001001 : : 1 -> character : Type of Array -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function -integer : 001001 : : Primitive Type : size-4 bytes -address : 001001 : : Primitive Type : size-8 bytes -character : 001001 : : Primitive Type : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes -reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition -release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -many_names : 009000 : 001001 : a_of_s : Array Instance -another_name : 009000 : 001001 : string : Array Instance -one_name : 009000 : 001001 : string : Array Instance -arg : 009000 : 001001 : string : Array Instance diff --git a/tests/sprint3/expected/sp3_if_else.asc.exp b/tests/sprint3/expected/sp3_if_else.asc.exp new file mode 100644 index 0000000..9bdc9e7 --- /dev/null +++ b/tests/sprint3/expected/sp3_if_else.asc.exp @@ -0,0 +1,25 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ integer: result ; rec: w] +015: if ( result = result ) then { +016: if ( result < w.y ) then { +017: result := 8; +018: } else { +019: result := 9; +020: }(* *) +021: } else { +022: result := bar('c', 7); +023: } +024: return 0; +025: } diff --git a/tests/sprint3/expected/sp3_if_while.asc.exp b/tests/sprint3/expected/sp3_if_while.asc.exp new file mode 100644 index 0000000..f071f8c --- /dev/null +++ b/tests/sprint3/expected/sp3_if_while.asc.exp @@ -0,0 +1,27 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ integer: result ; rec: w] +015: while ( result = result ) { +016: result := result + 8; +017: if ( result < w.y ) then { +018: while (true) { +019: result := 8; +020: } +021: } else { +022: result := 9; +023: } +024: result := bar('c', 7); +025: } +026: return 0; +027: } diff --git a/tests/sprint3/expected/sp3_integer_binary_op_typecheck.asc.exp b/tests/sprint3/expected/sp3_integer_binary_op_typecheck.asc.exp new file mode 100644 index 0000000..bff4a30 --- /dev/null +++ b/tests/sprint3/expected/sp3_integer_binary_op_typecheck.asc.exp @@ -0,0 +1,28 @@ +001: type main: string -> integer +002: +003: type rec: [integer: x; integer: y] +004: function entry: main +005: +006: entry (arg) := { +007: [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a; rec : r] +008: +009: x := 3 + 2 * 8; +010: x := 3 - 2 / 8; +011: x := a * 2 % 8; + LINE (11:20) ** TYPE ERROR: Assignable Assign Expression - Object x of type integer != Object undefined of type undefined + LINE (11:19) ** TYPE ERROR: Object undefined of type undefined and Object $t11 of type integer must both be integers + LINE (11:15) ** TYPE ERROR: Object a of type character and Object $t10 of type integer must both be integers +012: b2 := 3 * 2 % 8; +013: x := 3 % 2 * 8; +014: x := 3 + arr - 8; + LINE (14:22) ** TYPE ERROR: Assignable Assign Expression - Object x of type integer != Object undefined of type undefined + LINE (14:22) ** TYPE ERROR: Object undefined of type undefined and Object $t23 of type integer must both be integers + LINE (14:19) ** TYPE ERROR: Object $t22 of type integer and Object arr of type address must both be integers + LINE (14:19) ** TYPE ERROR: $t22 != arr +015: x := r.x; +016: x := a.x; + LINE (16:10) ** TYPE ERROR: Assignable Assign Expression - Object x of type integer != Object undefined of type undefined + LINE (16:9) ** TYPE ERROR: Invalid type passed to record access +017: +018: return 0; +019: } diff --git a/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected b/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected deleted file mode 100644 index 0b4c83f..0000000 --- a/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected +++ /dev/null @@ -1,25 +0,0 @@ -001: type main: string -> integer -002: -003: type rec: [integer: x; integer: y] -004: function entry: main -005: -006: entry (arg) := { -007: [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a; rec : r] -008: -009: x := 3 + 2 * 8; -010: x := 3 - 2 / 8; -011: x := a * 2 % 8; - LINE (11:20) ** TYPE ERROR: x != undefined - -012: b2 := 3 * 2 % 8; -013: x := 3 % 2 * 8; -014: x := 3 + arr - 8; - LINE (14:22) ** TYPE ERROR: x != undefined - -015: x := r.x; - LINE (15:10) ** TYPE ERROR: x != r - -016: x := a.x; -017: -018: return 0; -019: } diff --git a/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected b/tests/sprint3/expected/sp3_integer_unary_op_typecheck.asc.exp similarity index 53% rename from tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected rename to tests/sprint3/expected/sp3_integer_unary_op_typecheck.asc.exp index 18bd5a7..0ed98b5 100644 --- a/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected +++ b/tests/sprint3/expected/sp3_integer_unary_op_typecheck.asc.exp @@ -6,8 +6,8 @@ 006: 007: x := -8; 008: x := -b1; - LINE (8:10) ** TYPE ERROR: x != undefined - + LINE (8:10) ** TYPE ERROR: Assignable Assign Expression - Object x of type integer != Object undefined of type undefined + LINE (8:10) ** TYPE ERROR: Object b1 of type Boolean is not of type integer and can't be negated 009: b2 := -x; 010: 011: return 0; diff --git a/tests/sprint3/expected/sp3_multiple_args.asc.exp b/tests/sprint3/expected/sp3_multiple_args.asc.exp new file mode 100644 index 0000000..ffd92c2 --- /dev/null +++ b/tests/sprint3/expected/sp3_multiple_args.asc.exp @@ -0,0 +1,23 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ integer: result ; rec: w] +015: while ( result = result ) { +016: while ( result < w.y ) { +017: result := 8; +018: } +019: result := 9; +020: } +021: result := bar('c', 7); +022: return 0; +023: } diff --git a/tests/sprint3/expected/sp3_multiple_args.expected b/tests/sprint3/expected/sp3_multiple_args.expected deleted file mode 100644 index c0128e1..0000000 --- a/tests/sprint3/expected/sp3_multiple_args.expected +++ /dev/null @@ -1,25 +0,0 @@ -NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -bar : 001001 : : undefined : Function Definition -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function -T2 : 001001 : : rec -> integer : Type of Function -rec : 001001 : : Record Type : elements-2 size-6 bytes -integer : 001001 : : Primitive Type : size-4 bytes -address : 001001 : : Primitive Type : size-8 bytes -character : 001001 : : Primitive Type : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes -reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition -release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -w : 013000 : 001001 : rec : Record Instance -result : 013000 : 001001 : integer : Primitive Instance -arg : 013000 : 001001 : string : Array Instance -------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 009000 : 001001 : : Empty Scope -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 001000 : 001001 : integer : Primitive Instance -x : 001000 : 001001 : character : Primitive Instance diff --git a/tests/sprint3/expected/sp3_primitive_type_check.asc.exp b/tests/sprint3/expected/sp3_primitive_type_check.asc.exp new file mode 100644 index 0000000..7afd2a4 --- /dev/null +++ b/tests/sprint3/expected/sp3_primitive_type_check.asc.exp @@ -0,0 +1,23 @@ +001: (* +002: Testing the following type checks: +003: - integer : primitive +004: - character : primitive +005: - boolean : primitive +006: +007: - address (not included, special case) +008: *) +009: +010: +011: +012: type main: string -> integer +013: function entry: main +014: +015: entry (arg) := { +016: [integer: i; address: add; character: char; Boolean: bool] +017: +018: i := 3 + 2 * 8; +019: char := 'a'; +020: bool := true; +021: +022: return 0; +023: } diff --git a/tests/sprint3/expected/sp3_record_size_check.asc.exp b/tests/sprint3/expected/sp3_record_size_check.asc.exp new file mode 100644 index 0000000..2b5700c --- /dev/null +++ b/tests/sprint3/expected/sp3_record_size_check.asc.exp @@ -0,0 +1,3 @@ +001: type tom : [integer : x; integer: y] +002: type rec : [integer : x; tom : prev; character : c; character : d; Boolean: b; integer : y] +003: type tricky : [Boolean : b1; integer : k1; Boolean : b2; integer : k2] \ No newline at end of file diff --git a/tests/sprint3/expected/sp3_record_size_check.expected b/tests/sprint3/expected/sp3_record_size_check.expected deleted file mode 100644 index a061979..0000000 --- a/tests/sprint3/expected/sp3_record_size_check.expected +++ /dev/null @@ -1,29 +0,0 @@ -NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -tricky : 001001 : : Record Type : elements-4 size-16 bytes -rec : 001001 : : Record Type : elements-6 size-24 bytes -tom : 001001 : : Record Type : elements-2 size-8 bytes -integer : 001001 : : Primitive Type : size-4 bytes -address : 001001 : : Primitive Type : size-8 bytes -character : 001001 : : Primitive Type : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes -reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition -release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -k2 : 003000 : 001001 : integer : Primitive Instance -b2 : 003000 : 001001 : Boolean : Primitive Instance -k1 : 003000 : 001001 : integer : Primitive Instance -b1 : 003000 : 001001 : Boolean : Primitive Instance -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 002000 : 001001 : integer : Primitive Instance -b : 002000 : 001001 : Boolean : Primitive Instance -d : 002000 : 001001 : character : Primitive Instance -c : 002000 : 001001 : character : Primitive Instance -prev : 002000 : 001001 : tom : Record Instance -x : 002000 : 001001 : integer : Primitive Instance -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 001000 : 001001 : integer : Primitive Instance -x : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint3/test/sp3_and_or_type_check.alpha b/tests/sprint3/test/sp3_and_or_type_check.alpha index c01fc10..63c9f62 100644 --- a/tests/sprint3/test/sp3_and_or_type_check.alpha +++ b/tests/sprint3/test/sp3_and_or_type_check.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type rec: [integer: x; integer: y] type main: rec -> integer function test: main diff --git a/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha index 538d982..53ef65c 100644 --- a/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type main: string -> integer function entry: main diff --git a/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha b/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha index 6a23ff6..d099993 100644 --- a/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type main: string -> integer function entry: main diff --git a/tests/sprint3/test/sp3_carls_second_mistake.alpha b/tests/sprint3/test/sp3_carls_second_mistake.alpha index ddb58a4..652dc48 100644 --- a/tests/sprint3/test/sp3_carls_second_mistake.alpha +++ b/tests/sprint3/test/sp3_carls_second_mistake.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type main: string -> integer function entry: main diff --git a/tests/sprint3/test/sp3_if_else.alpha b/tests/sprint3/test/sp3_if_else.alpha index 02c9525..e8f4bd7 100644 --- a/tests/sprint3/test/sp3_if_else.alpha +++ b/tests/sprint3/test/sp3_if_else.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type rec: [character: x; integer: y] type T2: rec -> integer diff --git a/tests/sprint3/test/sp3_if_while.alpha b/tests/sprint3/test/sp3_if_while.alpha index bb6a519..45300bc 100644 --- a/tests/sprint3/test/sp3_if_while.alpha +++ b/tests/sprint3/test/sp3_if_while.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type rec: [character: x; integer: y] type T2: rec -> integer diff --git a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha index 2adb394..71bb0e5 100644 --- a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type main: string -> integer type rec: [integer: x; integer: y] diff --git a/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha index 7ab6817..3469bb6 100644 --- a/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type main: string -> integer function entry: main diff --git a/tests/sprint3/test/sp3_multiple_args.alpha b/tests/sprint3/test/sp3_multiple_args.alpha index f069230..6cd4144 100644 --- a/tests/sprint3/test/sp3_multiple_args.alpha +++ b/tests/sprint3/test/sp3_multiple_args.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type rec: [character: x; integer: y] type T2: rec -> integer diff --git a/tests/sprint3/test/sp3_primitive_type_check.alpha b/tests/sprint3/test/sp3_primitive_type_check.alpha index 6980aba..9a078ad 100644 --- a/tests/sprint3/test/sp3_primitive_type_check.alpha +++ b/tests/sprint3/test/sp3_primitive_type_check.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) (* Testing the following type checks: - integer : primitive diff --git a/tests/sprint3/test/sp3_record_size_check.alpha b/tests/sprint3/test/sp3_record_size_check.alpha index 8e123d0..d8526d5 100644 --- a/tests/sprint3/test/sp3_record_size_check.alpha +++ b/tests/sprint3/test/sp3_record_size_check.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type tom : [integer : x; integer: y] type rec : [integer : x; tom : prev; character : c; character : d; Boolean: b; integer : y] type tricky : [Boolean : b1; integer : k1; Boolean : b2; integer : k2] \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_add.asc.exp b/tests/sprint4/expected/sp4_cg_add.asc.exp new file mode 100644 index 0000000..bff5d97 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_add.asc.exp @@ -0,0 +1,10 @@ +001: type main: integer -> integer +002: function test: main +003: +004: test (a) := { +005: [integer:x; integer:y] +006: y := 1; +007: x := 3; +008: y := x + y; +009: return y; +010: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_add.ir.exp b/tests/sprint4/expected/sp4_cg_add.ir.exp new file mode 100644 index 0000000..d0a05ab --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_add.ir.exp @@ -0,0 +1,8 @@ + 1: func : test + 2: $t0 = 1 + 3: y = $t0 + 4: $t1 = 3 + 5: x = $t1 + 6: $t2 = x + y + 7: y = $t2 + 8: return : y diff --git a/tests/sprint4/expected/sp4_cg_add.expected b/tests/sprint4/expected/sp4_cg_add.s.exp similarity index 100% rename from tests/sprint4/expected/sp4_cg_add.expected rename to tests/sprint4/expected/sp4_cg_add.s.exp diff --git a/tests/sprint4/expected/sp4_cg_and.asc.exp b/tests/sprint4/expected/sp4_cg_and.asc.exp new file mode 100644 index 0000000..8676177 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_and.asc.exp @@ -0,0 +1,10 @@ +001: type main: integer -> integer +002: function test: main +003: +004: test (a) := { +005: [Boolean:b; Boolean: c; Boolean: d] +006: c := true; +007: d := false; +008: d := c & d; +009: return 1; +010: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_and.expected b/tests/sprint4/expected/sp4_cg_and.expected deleted file mode 100644 index be6a53e..0000000 --- a/tests/sprint4/expected/sp4_cg_and.expected +++ /dev/null @@ -1,20 +0,0 @@ - movl $-1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $-1, -12(%rbp) #constant assign - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - cmpl $0, -8(%rbp) #start and - je .L1or2 - cmpl $0, -16(%rbp) - je .L1or2 - movl $1, %eax - jmp .L1or3 -.L1or2: - movl $0, %eax -.L1or3: - movb %al, -20(%rbp) - andb $1, -20(%rbp) #and end - movl -20(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - movl $1, -24(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_and.ir.exp b/tests/sprint4/expected/sp4_cg_and.ir.exp new file mode 100644 index 0000000..462a6ad --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_and.ir.exp @@ -0,0 +1,9 @@ + 1: func : test + 2: $t0 = true + 3: c = $t0 + 4: $t1 = false + 5: d = $t1 + 6: $t2 = c & d + 7: d = $t2 + 8: $t3 = 1 + 9: return : $t3 diff --git a/tests/sprint4/expected/sp4_cg_and.s.exp b/tests/sprint4/expected/sp4_cg_and.s.exp new file mode 100644 index 0000000..0a3128d --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_and.s.exp @@ -0,0 +1,20 @@ + movl $-1, -1(%rbp) #constant assign + movl -1(%rbp), %eax #assign start + movl %eax, -2(%rbp) #assign end + movl $-1, -3(%rbp) #constant assign + movl -3(%rbp), %eax #assign start + movl %eax, -4(%rbp) #assign end + cmpl $0, -2(%rbp) #start and + je .L1or2 + cmpl $0, -4(%rbp) + je .L1or2 + movl $1, %eax + jmp .L1or3 +.L1or2: + movl $0, %eax +.L1or3: + movb %al, -5(%rbp) + andb $1, -5(%rbp) #and end + movl -5(%rbp), %eax #assign start + movl %eax, -4(%rbp) #assign end + movl $1, -9(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_div.asc.exp b/tests/sprint4/expected/sp4_cg_div.asc.exp new file mode 100644 index 0000000..87b68f2 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_div.asc.exp @@ -0,0 +1,10 @@ +001: type main: integer -> integer +002: function test: main +003: +004: test (a) := { +005: [integer:x; integer:y] +006: y := 1; +007: x := 3; +008: y := x / y; +009: return y; +010: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_div.ir.exp b/tests/sprint4/expected/sp4_cg_div.ir.exp new file mode 100644 index 0000000..905d038 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_div.ir.exp @@ -0,0 +1,8 @@ + 1: func : test + 2: $t0 = 1 + 3: y = $t0 + 4: $t1 = 3 + 5: x = $t1 + 6: $t2 = x / y + 7: y = $t2 + 8: return : y diff --git a/tests/sprint4/expected/sp4_cg_div.expected b/tests/sprint4/expected/sp4_cg_div.s.exp similarity index 100% rename from tests/sprint4/expected/sp4_cg_div.expected rename to tests/sprint4/expected/sp4_cg_div.s.exp diff --git a/tests/sprint4/expected/sp4_cg_equal_to.asc.exp b/tests/sprint4/expected/sp4_cg_equal_to.asc.exp new file mode 100644 index 0000000..df0cbd5 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_equal_to.asc.exp @@ -0,0 +1,10 @@ +001: type main: integer -> integer +002: function test: main +003: +004: test (a) := { +005: [Boolean: b; integer: x; integer: y] +006: x := 1; +007: y := 2; +008: b := x = y; +009: return 1; +010: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_equal_to.ir.exp b/tests/sprint4/expected/sp4_cg_equal_to.ir.exp new file mode 100644 index 0000000..1739814 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_equal_to.ir.exp @@ -0,0 +1,10 @@ + 1: func : test + 2: $t0 = 1 + 3: x = $t0 + 4: $t1 = 2 + 5: y = $t1 + 6: if ( x = y ) GOTO 0 + 7: GOTO : 0 + 8: b = $t2 + 9: $t3 = 1 + 10: return : $t3 diff --git a/tests/sprint4/expected/sp4_cg_equal_to.expected b/tests/sprint4/expected/sp4_cg_equal_to.s.exp similarity index 66% rename from tests/sprint4/expected/sp4_cg_equal_to.expected rename to tests/sprint4/expected/sp4_cg_equal_to.s.exp index e29c6c1..5f73e0b 100644 --- a/tests/sprint4/expected/sp4_cg_equal_to.expected +++ b/tests/sprint4/expected/sp4_cg_equal_to.s.exp @@ -7,7 +7,5 @@ movl -8(%rbp), %eax #equal to start cmpl -16(%rbp), %eax sete %al - movb %al, -20(%rbp) #equal to end - movl -20(%rbp), %eax #assign start - movl %eax, -24(%rbp) #assign end - movl $1, -28(%rbp) #constant assign + movb %al, -15(%rbp) #equal to end + movl $1, -20(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_less_than.asc.exp b/tests/sprint4/expected/sp4_cg_less_than.asc.exp new file mode 100644 index 0000000..63b0136 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_less_than.asc.exp @@ -0,0 +1,10 @@ +001: type main: integer -> integer +002: function test: main +003: +004: test (a) := { +005: [Boolean: b; integer: x; integer: y] +006: x := 1; +007: y := 2; +008: b := x < y; +009: return 1; +010: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_less_than.ir.exp b/tests/sprint4/expected/sp4_cg_less_than.ir.exp new file mode 100644 index 0000000..5feb329 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_less_than.ir.exp @@ -0,0 +1,10 @@ + 1: func : test + 2: $t0 = 1 + 3: x = $t0 + 4: $t1 = 2 + 5: y = $t1 + 6: if ( x < y ) GOTO 0 + 7: GOTO : 0 + 8: b = $t2 + 9: $t3 = 1 + 10: return : $t3 diff --git a/tests/sprint4/expected/sp4_cg_less_than.expected b/tests/sprint4/expected/sp4_cg_less_than.s.exp similarity index 66% rename from tests/sprint4/expected/sp4_cg_less_than.expected rename to tests/sprint4/expected/sp4_cg_less_than.s.exp index b8d8904..4ed5ad1 100644 --- a/tests/sprint4/expected/sp4_cg_less_than.expected +++ b/tests/sprint4/expected/sp4_cg_less_than.s.exp @@ -7,7 +7,5 @@ movl -8(%rbp), %eax #less than start cmpl -16(%rbp), %eax setl %al - movb %al, -20(%rbp) #less than end - movl -20(%rbp), %eax #assign start - movl %eax, -24(%rbp) #assign end - movl $1, -28(%rbp) #constant assign + movb %al, -15(%rbp) #less than end + movl $1, -20(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_mod.asc.exp b/tests/sprint4/expected/sp4_cg_mod.asc.exp new file mode 100644 index 0000000..32294ec --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_mod.asc.exp @@ -0,0 +1,10 @@ +001: type main: integer -> integer +002: function test: main +003: +004: test (a) := { +005: [integer:x; integer:y] +006: y := 1; +007: x := 3; +008: y := x % y; +009: return y; +010: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_mod.ir.exp b/tests/sprint4/expected/sp4_cg_mod.ir.exp new file mode 100644 index 0000000..b16f1de --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_mod.ir.exp @@ -0,0 +1,8 @@ + 1: func : test + 2: $t0 = 1 + 3: y = $t0 + 4: $t1 = 3 + 5: x = $t1 + 6: $t2 = x % y + 7: y = $t2 + 8: return : y diff --git a/tests/sprint4/expected/sp4_cg_mod.expected b/tests/sprint4/expected/sp4_cg_mod.s.exp similarity index 100% rename from tests/sprint4/expected/sp4_cg_mod.expected rename to tests/sprint4/expected/sp4_cg_mod.s.exp diff --git a/tests/sprint4/expected/sp4_cg_mult.asc.exp b/tests/sprint4/expected/sp4_cg_mult.asc.exp new file mode 100644 index 0000000..15138ee --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_mult.asc.exp @@ -0,0 +1,10 @@ +001: type main: integer -> integer +002: function test: main +003: +004: test (a) := { +005: [integer:x; integer:y] +006: y := 1; +007: x := 3; +008: y := x * x; +009: return y; +010: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_mult.ir.exp b/tests/sprint4/expected/sp4_cg_mult.ir.exp new file mode 100644 index 0000000..c125e68 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_mult.ir.exp @@ -0,0 +1,8 @@ + 1: func : test + 2: $t0 = 1 + 3: y = $t0 + 4: $t1 = 3 + 5: x = $t1 + 6: $t2 = x * x + 7: y = $t2 + 8: return : y diff --git a/tests/sprint4/expected/sp4_cg_mult.expected b/tests/sprint4/expected/sp4_cg_mult.s.exp similarity index 100% rename from tests/sprint4/expected/sp4_cg_mult.expected rename to tests/sprint4/expected/sp4_cg_mult.s.exp diff --git a/tests/sprint4/expected/sp4_cg_neg.asc.exp b/tests/sprint4/expected/sp4_cg_neg.asc.exp new file mode 100644 index 0000000..647d812 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_neg.asc.exp @@ -0,0 +1,9 @@ +001: type main: integer -> integer +002: function test: main +003: +004: test (a) := { +005: [integer:x; integer:y] +006: x := 3; +007: y := -x; +008: return y; +009: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_neg.ir.exp b/tests/sprint4/expected/sp4_cg_neg.ir.exp new file mode 100644 index 0000000..6a42a7c --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_neg.ir.exp @@ -0,0 +1,6 @@ + 1: func : test + 2: $t0 = 3 + 3: x = $t0 + 4: $t1 = -x + 5: y = $t1 + 6: return : y diff --git a/tests/sprint4/expected/sp4_cg_neg.expected b/tests/sprint4/expected/sp4_cg_neg.s.exp similarity index 100% rename from tests/sprint4/expected/sp4_cg_neg.expected rename to tests/sprint4/expected/sp4_cg_neg.s.exp diff --git a/tests/sprint4/expected/sp4_cg_not.asc.exp b/tests/sprint4/expected/sp4_cg_not.asc.exp new file mode 100644 index 0000000..ac22520 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_not.asc.exp @@ -0,0 +1,9 @@ +001: type main: integer -> integer +002: function test: main +003: +004: test (a) := { +005: [Boolean: c; Boolean: d] +006: c := true; +007: d := !c; +008: return 1; +009: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_not.expected b/tests/sprint4/expected/sp4_cg_not.expected deleted file mode 100644 index b2e4bda..0000000 --- a/tests/sprint4/expected/sp4_cg_not.expected +++ /dev/null @@ -1,13 +0,0 @@ - movl $-1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movzbl -8(%rbp), %eax #not start - testl %eax, %eax - setne %al - xorl $1, %eax - movzbl %al, %eax - movb %al, -12(%rbp) - andb $1, -12(%rbp) #not end - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - movl $1, -20(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_not.ir.exp b/tests/sprint4/expected/sp4_cg_not.ir.exp new file mode 100644 index 0000000..f1b6d6b --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_not.ir.exp @@ -0,0 +1,7 @@ + 1: func : test + 2: $t0 = true + 3: c = $t0 + 4: $t1 = !c + 5: d = $t1 + 6: $t2 = 1 + 7: return : $t2 diff --git a/tests/sprint4/expected/sp4_cg_not.s.exp b/tests/sprint4/expected/sp4_cg_not.s.exp new file mode 100644 index 0000000..39c04ce --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_not.s.exp @@ -0,0 +1,13 @@ + movl $-1, -1(%rbp) #constant assign + movl -1(%rbp), %eax #assign start + movl %eax, -2(%rbp) #assign end + movzbl -2(%rbp), %eax #not start + testl %eax, %eax + setne %al + xorl $1, %eax + movzbl %al, %eax + movb %al, -3(%rbp) + andb $1, -3(%rbp) #not end + movl -3(%rbp), %eax #assign start + movl %eax, -4(%rbp) #assign end + movl $1, -8(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_or.asc.exp b/tests/sprint4/expected/sp4_cg_or.asc.exp new file mode 100644 index 0000000..5a99180 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_or.asc.exp @@ -0,0 +1,10 @@ +001: type main: integer -> integer +002: function test: main +003: +004: test (a) := { +005: [Boolean:b; Boolean: c; Boolean: d] +006: c := true; +007: d := false; +008: d := c | d; +009: return 1; +010: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_or.expected b/tests/sprint4/expected/sp4_cg_or.expected deleted file mode 100644 index 120058f..0000000 --- a/tests/sprint4/expected/sp4_cg_or.expected +++ /dev/null @@ -1,21 +0,0 @@ - movl $-1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $-1, -12(%rbp) #constant assign - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - cmpl $0, -8(%rbp) #start or - jne .L1or2 - cmpl $0, -16(%rbp) - je .L1or3 -.L1or2: - movl $1, %eax - jmp .L1or4 -.L1or3: - movl $0, %eax -.L1or4: - movb %al, -20(%rbp) - andb $1, -20(%rbp) #or end - movl -20(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - movl $1, -24(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_or.ir.exp b/tests/sprint4/expected/sp4_cg_or.ir.exp new file mode 100644 index 0000000..5dfac99 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_or.ir.exp @@ -0,0 +1,9 @@ + 1: func : test + 2: $t0 = true + 3: c = $t0 + 4: $t1 = false + 5: d = $t1 + 6: $t2 = c | d + 7: d = $t2 + 8: $t3 = 1 + 9: return : $t3 diff --git a/tests/sprint4/expected/sp4_cg_or.s.exp b/tests/sprint4/expected/sp4_cg_or.s.exp new file mode 100644 index 0000000..7faecdd --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_or.s.exp @@ -0,0 +1,21 @@ + movl $-1, -1(%rbp) #constant assign + movl -1(%rbp), %eax #assign start + movl %eax, -2(%rbp) #assign end + movl $-1, -3(%rbp) #constant assign + movl -3(%rbp), %eax #assign start + movl %eax, -4(%rbp) #assign end + cmpl $0, -2(%rbp) #start or + jne .L1or2 + cmpl $0, -4(%rbp) + je .L1or3 +.L1or2: + movl $1, %eax + jmp .L1or4 +.L1or3: + movl $0, %eax +.L1or4: + movb %al, -5(%rbp) + andb $1, -5(%rbp) #or end + movl -5(%rbp), %eax #assign start + movl %eax, -4(%rbp) #assign end + movl $1, -9(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_sub.asc.exp b/tests/sprint4/expected/sp4_cg_sub.asc.exp new file mode 100644 index 0000000..4b4496c --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_sub.asc.exp @@ -0,0 +1,10 @@ +001: type main: integer -> integer +002: function test: main +003: +004: test (a) := { +005: [integer:x; integer:y] +006: y := 1; +007: x := 3; +008: y := x - y; +009: return y; +010: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_sub.ir.exp b/tests/sprint4/expected/sp4_cg_sub.ir.exp new file mode 100644 index 0000000..c4ef79a --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_sub.ir.exp @@ -0,0 +1,8 @@ + 1: func : test + 2: $t0 = 1 + 3: y = $t0 + 4: $t1 = 3 + 5: x = $t1 + 6: $t2 = x - y + 7: y = $t2 + 8: return : y diff --git a/tests/sprint4/expected/sp4_cg_sub.expected b/tests/sprint4/expected/sp4_cg_sub.s.exp similarity index 99% rename from tests/sprint4/expected/sp4_cg_sub.expected rename to tests/sprint4/expected/sp4_cg_sub.s.exp index 743ef59..8bf3d80 100644 --- a/tests/sprint4/expected/sp4_cg_sub.expected +++ b/tests/sprint4/expected/sp4_cg_sub.s.exp @@ -9,3 +9,4 @@ movl %eax, -20(%rbp) #subtraction end movl -20(%rbp), %eax #assign start movl %eax, -8(%rbp) #assign end +s \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_add.alpha b/tests/sprint4/test/sp4_cg_add.alpha index f4f8138..0398f89 100644 --- a/tests/sprint4/test/sp4_cg_add.alpha +++ b/tests/sprint4/test/sp4_cg_add.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc -cg -ir] *) type main: integer -> integer function test: main diff --git a/tests/sprint4/test/sp4_cg_and.alpha b/tests/sprint4/test/sp4_cg_and.alpha index 5017e35..97adf47 100644 --- a/tests/sprint4/test/sp4_cg_and.alpha +++ b/tests/sprint4/test/sp4_cg_and.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc -cg -ir] *) type main: integer -> integer function test: main diff --git a/tests/sprint4/test/sp4_cg_div.alpha b/tests/sprint4/test/sp4_cg_div.alpha index 32d3537..e6f9cbd 100644 --- a/tests/sprint4/test/sp4_cg_div.alpha +++ b/tests/sprint4/test/sp4_cg_div.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc -cg -ir] *) type main: integer -> integer function test: main diff --git a/tests/sprint4/test/sp4_cg_equal_to.alpha b/tests/sprint4/test/sp4_cg_equal_to.alpha index a3da50c..23ecf91 100644 --- a/tests/sprint4/test/sp4_cg_equal_to.alpha +++ b/tests/sprint4/test/sp4_cg_equal_to.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc -cg -ir] *) type main: integer -> integer function test: main diff --git a/tests/sprint4/test/sp4_cg_less_than.alpha b/tests/sprint4/test/sp4_cg_less_than.alpha index 8f41ced..a1e6bbb 100644 --- a/tests/sprint4/test/sp4_cg_less_than.alpha +++ b/tests/sprint4/test/sp4_cg_less_than.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc -cg -ir] *) type main: integer -> integer function test: main diff --git a/tests/sprint4/test/sp4_cg_mod.alpha b/tests/sprint4/test/sp4_cg_mod.alpha index 1b579d5..ccf0b85 100644 --- a/tests/sprint4/test/sp4_cg_mod.alpha +++ b/tests/sprint4/test/sp4_cg_mod.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc -cg -ir] *) type main: integer -> integer function test: main diff --git a/tests/sprint4/test/sp4_cg_mult.alpha b/tests/sprint4/test/sp4_cg_mult.alpha index c151a6b..630fa14 100644 --- a/tests/sprint4/test/sp4_cg_mult.alpha +++ b/tests/sprint4/test/sp4_cg_mult.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc -cg -ir] *) type main: integer -> integer function test: main diff --git a/tests/sprint4/test/sp4_cg_neg.alpha b/tests/sprint4/test/sp4_cg_neg.alpha index 345980b..58683a4 100644 --- a/tests/sprint4/test/sp4_cg_neg.alpha +++ b/tests/sprint4/test/sp4_cg_neg.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc -cg -ir] *) type main: integer -> integer function test: main diff --git a/tests/sprint4/test/sp4_cg_not.alpha b/tests/sprint4/test/sp4_cg_not.alpha index 40252f9..f7ad95c 100644 --- a/tests/sprint4/test/sp4_cg_not.alpha +++ b/tests/sprint4/test/sp4_cg_not.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc -cg -ir] *) type main: integer -> integer function test: main diff --git a/tests/sprint4/test/sp4_cg_or.alpha b/tests/sprint4/test/sp4_cg_or.alpha index b6d6766..0ce14f3 100644 --- a/tests/sprint4/test/sp4_cg_or.alpha +++ b/tests/sprint4/test/sp4_cg_or.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc -cg -ir] *) type main: integer -> integer function test: main diff --git a/tests/sprint4/test/sp4_cg_sub.alpha b/tests/sprint4/test/sp4_cg_sub.alpha index f280c9d..abf6608 100644 --- a/tests/sprint4/test/sp4_cg_sub.alpha +++ b/tests/sprint4/test/sp4_cg_sub.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc -cg -ir] *) type main: integer -> integer function test: main From 6bef4bdc263fd75cf43f63ff03c8eb48c4b3ec2c Mon Sep 17 00:00:00 2001 From: Scarlett Date: Sun, 4 May 2025 16:23:35 -0400 Subject: [PATCH 043/109] make --- Makefile | 36 +++++++++---------------- test.sh | 24 +++++++++++++++-- tests/sprint4/expected/sp4_cg_sub.s.exp | 1 - 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 794b839..68a4858 100644 --- a/Makefile +++ b/Makefile @@ -12,11 +12,6 @@ YACC := src/grammar.y EXE := alpha OBJS := tmp/runner.o tmp/symbol_table.o tmp/grammar.tab.o tmp/lex.yy.o tmp/intermediate_code.o tmp/codegen.o - -TESTS-S1 := $(wildcard tests/sprint1/test/*.alpha) -TESTS-S2 := $(wildcard tests/sprint2/test/*.alpha) -TESTS-S3 := $(wildcard tests/sprint3/test/*.alpha) -TESTS-S4 := $(wildcard tests/sprint4/test/*.alpha) # ---------- @@ -71,35 +66,30 @@ tmp/runner.o: src/runner.c src/runner.h tmp/flex.h tmp/grammar.tab.h # ----- Tests ----- test: - chmod +x ./check.sh chmod +x ./test.sh - $(foreach test, $(TESTS-S1), (./$(EXE) -tok -debug $(test) || true);) - ./test.sh sp2 - ./test.sh sp3 - ./test.sh sp4 - ./check.sh + ./test.sh tests/sprint1/test/ -diff + ./test.sh tests/sprint2/test/ -diff + ./test.sh tests/sprint3/test/ -diff + ./test.sh tests/sprint4/test/ -diff + ./test.sh tests/given/test/ -diff test-s1: - chmod +x ./check.sh chmod +x ./test.sh - $(foreach test, $(TESTS-S1), (./$(EXE) -tok -debug $(test) || true);) - ./check.sh sp1 + ./test.sh tests/sprint1/test/ -diff test-s2: - chmod +x ./check.sh chmod +x ./test.sh - ./test.sh sp2 - ./check.sh sp2 + ./test.sh tests/sprint2/test/ -diff test-s3: - chmod +x ./check.sh chmod +x ./test.sh - ./test.sh sp3 - ./check.sh sp3 + ./test.sh tests/sprint3/test/ -diff test-s4: - chmod +x ./check.sh chmod +x ./test.sh - ./test.sh sp4 - ./check.sh sp4 + ./test.sh tests/sprint4/test/ -diff + +test-given: + chmod +x ./test.sh + ./test.sh tests/given/test/ -diff # ----------- \ No newline at end of file diff --git a/test.sh b/test.sh index 3f3c266..ce2d31d 100755 --- a/test.sh +++ b/test.sh @@ -33,8 +33,26 @@ if [ $# -eq 0 ]; then fi help() { - echo -e "${GREEN}[HELP] ${YELLOW}Usage: ./test.sh [-exp] ${WHITE}" - echo -e "${GREEN}[HELP] ${YELLOW}To all tests in a folder: ./test/sh / [-exp]${WHITE}" + echo -e "${WHITE}-----{ ${BLUE}Test.sh Help ${WHITE}}-----\n" + echo -e "${YELLOW} Arguments: ${WHITE}" + echo -e "${GREEN} -exp ${WHITE} Generate expected output files" + echo -e "${GREEN} -diff ${WHITE} Compare output files with expected output files" + echo -e "${GREEN} -help ${WHITE} Show this help message\n" + echo -e "${YELLOW} Usage: ${WHITE}" + echo -e "${GREEN} ./test.sh [flags] ${WHITE} Run the test on a single file" + echo -e "${GREEN} ./test.sh [flags] ${WHITE} Run the test on all files in a directory\n" + echo -e "${YELLOW} Examples: ${WHITE}" + echo -e "${GREEN} ./test.sh test.alpha ${WHITE} Runs test flags in header on test.alpha" + echo -e "${GREEN} ./test.sh test/ ${WHITE} Runs test flags in header on all .alpha files in test/" + echo -e "${GREEN} ./test.sh test/ -exp ${WHITE} Runs test flags in header on all .alpha files in test/ and generates expected output files" + echo -e "${GREEN} ./test.sh test/ -diff ${WHITE} Runs test flags in header on all .alpha files in test/ and compares output files with expected output files" + echo -e "${GREEN} ./test.sh test/ -exp -diff ${WHITE} Runs test flags in header on all .alpha files in test/ and generates expected output files and compares output files with expected output files\n" + echo -e "${YELLOW} Notes: ${WHITE}" + echo -e "${ORANGE} To create a test file, on the first line of the .alpha file, add:" + echo -e "${LIGHTBLUE} (* TEST: [ ] *)" + echo -e "${ORANGE} where are the alpha flags to be used. Ex:" + echo -e "${LIGHTBLUE} (* TEST: [ -debug -asc -tc ] *)\n" + echo -e "${WHITE}-----------------------------------------\n" exit 1 } @@ -136,4 +154,6 @@ if [ -f "$1" ]; then echo -e "${RED}[ERROR] ${YELLOW}File $1 is not a .alpha file!${WHITE}" help fi +else + help fi diff --git a/tests/sprint4/expected/sp4_cg_sub.s.exp b/tests/sprint4/expected/sp4_cg_sub.s.exp index 8bf3d80..743ef59 100644 --- a/tests/sprint4/expected/sp4_cg_sub.s.exp +++ b/tests/sprint4/expected/sp4_cg_sub.s.exp @@ -9,4 +9,3 @@ movl %eax, -20(%rbp) #subtraction end movl -20(%rbp), %eax #assign start movl %eax, -8(%rbp) #assign end -s \ No newline at end of file From 85629fbf14114b1423737180465781530a7f13b2 Mon Sep 17 00:00:00 2001 From: Annie Date: Sun, 4 May 2025 16:44:55 -0400 Subject: [PATCH 044/109] function calls are starting to work i think --- src/codegen.c | 70 +++++++++++++++++-------- src/grammar.y | 2 +- tests/carl/NoErrors/functionValue.alpha | 6 +-- 3 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index a3c4dff..49748ce 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -493,6 +493,7 @@ int generateAssign(Instruction *inst) { cg = addCG(getResult(inst), offset); } + CGNode *op1CG = findCG(getTN(op1)); //add option for constant assignment (should be easy) if (isConst(op1) == true) { @@ -500,9 +501,8 @@ int generateAssign(Instruction *inst) { return 0; } - CGNode *op1CG = findCG(getTN(op1)); - if (op1CG == NULL) { - printdebug("generateAssign failed, op1 is not constant but not in CGlist"); + else if (op1CG == NULL) { + printdebug("generateAssign failed, %s is not constant but not in CGlist", getName(getTN(op1))); return -1; } @@ -608,35 +608,61 @@ int generateCall(Instruction *inst){ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); if (op1 == NULL) { - printdebug("%sgenerateFunctionStart failed, NULL operand", COLOR_RED); + printdebug("%sgenerateFunctionCall failed, NULL operand", COLOR_RED); return -1; } if (op1 == NULL) { - printdebug("%sgenerateFunctionStart failed, NULL operand", COLOR_RED); + printdebug("%sgenerateFunctionCall failed, NULL operand", COLOR_RED); return -1; } if (getTN(op1) == NULL) { - printdebug("generateFunctionCall failed, NULL tablenode"); + printdebug("generateFunctionCall failed, NULL tablenode1"); return -1; } - if (getTN(op2) == NULL) { - printdebug("generateFunctionCall failed, NULL tablenode"); - return -1; - } + // if (getTN(op2) == NULL) { + // printdebug("generateFunctionCall failed, NULL tablenode2"); + // return -1; + //} fprintf(cg_flag, "\tcall %s\n", getName(getTN(op1))); fprintf(cg_flag, "\taddq\t$%d, %%rsp\n", 8 + getConst(op1)); - + + //now for the return + CGNode *cg = findCG(getResult(inst)); + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#store return from call\n", getAddress(cg)); + return 0; } int generateReturn(Instruction *inst){ - return -1; - //will movl the result into the appropriate register and move the stack pointer/offset stuff back to correct value + TNodeOrConst *op1 = getOperand1(inst); + CGNode *cg; + + + if (op1 == NULL) { + printdebug("generateReturn failed, NULL operand"); + return -1; + } + + cg = findCG(getTN(op1)); + if (cg == NULL) { + printdebug("generateReturn failed, trying to return %s not in CGList", getName(getTN(op1))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#return %s\n", getAddress(cg), getName(getTN(op1))); + fprintf(cg_flag, "\tpopq\t%%rbp\n"); + fprintf(cg_flag, "\tret\n"); + return 0; } int generateCopyRight(Instruction *inst){ return -1; @@ -658,7 +684,7 @@ int generateParam(Instruction *inst){ CGNode *op1CG = findCG(getTN(op1)); if (op1CG == NULL) { - printdebug("generateParam failed, op1 is not in CGlist"); + printdebug("generateParam failed, %s is not in CGlist", getName(getTN(op1))); return -1; } @@ -668,7 +694,7 @@ int generateParam(Instruction *inst){ } int generateFunctionStart(Instruction *inst) { - + currentsp = offset; TableNode *funDecTN = getResult(inst); if (funDecTN == NULL) { @@ -690,20 +716,18 @@ int generateFunctionStart(Instruction *inst) { TableNode *paramTN = getParameter(getTypeEntry(funDecTN)); SymbolTable *st = getFunScope(funDecTN); int paramOffset = 16; + TableNode *tnToAdd = getFirstEntry(st); if (getAdInfoType(paramTN) != TYPE_RECORD_TYPE) { - fprintf(stderr, "%d\n", getAdInfoType(funDecTN)); - CGNode *paramCG = addCG(paramTN, currentsp); + CGNode *paramCG = addCG(tnToAdd, offset); fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getPrimSize(getTypeEntry(paramTN))); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getAddress(paramCG)); } else { - fprintf(stderr, "record type\n"); int numParams = getRecLength(paramTN); - TableNode *tnToAdd = getFirstEntry(st); for (int i = 0; i < numParams; i++) { - CGNode *paramCG = addCG(tnToAdd, currentsp); + CGNode *paramCG = addCG(tnToAdd, offset); fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getPrimSize(getTypeEntry(paramTN))); - paramOffset += getPrimSize(getTypeEntry(tnToAdd)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getAddress(paramCG)); + paramOffset = getPrimSize(getTypeEntry(tnToAdd)); tnToAdd = getNextEntry(tnToAdd); } } diff --git a/src/grammar.y b/src/grammar.y index 9d5d5a3..fb33253 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1244,7 +1244,7 @@ constant: char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, chara, temp, NULL); emit_assignment(node, tn_or_const(CHARACTER,&$1)); - printdebug("string of C_CHARACTER in constant is %s",$1); + //printdebug("string of C_CHARACTER in constant is %s",$1); $$ = node; } diff --git a/tests/carl/NoErrors/functionValue.alpha b/tests/carl/NoErrors/functionValue.alpha index c1134ce..cac92bb 100644 --- a/tests/carl/NoErrors/functionValue.alpha +++ b/tests/carl/NoErrors/functionValue.alpha @@ -28,8 +28,8 @@ function c: string2int_2_integer function d: iic2b d(x,y,z) := { - [string: s;integer: s] - return (x < y & z < 'm'); + [string: s] + return 0; } function entry: string2int @@ -61,7 +61,7 @@ entry(arg) := { temp := a("Hello"); f := b(temp); result := c(f); - if (d(1,2,char)) + if (d(1,2,'a')) then { result := 0; } From f43ab2452a945161799d6503ff1ac9e27f9235a9 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Sun, 4 May 2025 17:03:19 -0400 Subject: [PATCH 045/109] tilda --- tests/sprint4/test/sp4_cg_demo.alpha~ | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 tests/sprint4/test/sp4_cg_demo.alpha~ diff --git a/tests/sprint4/test/sp4_cg_demo.alpha~ b/tests/sprint4/test/sp4_cg_demo.alpha~ deleted file mode 100644 index 6f69389..0000000 --- a/tests/sprint4/test/sp4_cg_demo.alpha~ +++ /dev/null @@ -1,8 +0,0 @@ -type main: string -> integer -function entry: main - -entry(arg) := { - [integer:x] - x := 3 + 2 * 8; - return 0; - } \ No newline at end of file From 3a33cc0f88a1a0d40679e96bad22e0183cff7ddb Mon Sep 17 00:00:00 2001 From: Scarlett Date: Sun, 4 May 2025 17:33:59 -0400 Subject: [PATCH 046/109] include lex --- a.out | Bin 464 -> 0 bytes src/codegen.h~ | 2 -- src/grammar.y | 14 ++++++++++++++ src/lexicalStructure.lex | 2 ++ src/typedefs.h | 3 ++- tests/sprint1/test/sp1_include.alpha | 4 ++++ 6 files changed, 22 insertions(+), 3 deletions(-) delete mode 100644 a.out delete mode 100644 src/codegen.h~ create mode 100644 tests/sprint1/test/sp1_include.alpha diff --git a/a.out b/a.out deleted file mode 100644 index 8540d49290617f7498e8df1dc190587a92561a76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 464 zcmb<-^>JfjWMqH=Mg}_u1P><4z%T*9WN-kp9T->{SQw7G{$U1kkGuY00#jc&fK<2Z z5B~M8Upiesbi4lPcKyJ3q0{wEx9giu*B1lX*gfr5Zs{n+dVSqHOU L2E;)E==K8uL2Dw) diff --git a/src/codegen.h~ b/src/codegen.h~ deleted file mode 100644 index 2d4c660..0000000 --- a/src/codegen.h~ +++ /dev/null @@ -1,2 +0,0 @@ -/* Code Generation File - Contains functions to generate assembly code */ - diff --git a/src/grammar.y b/src/grammar.y index 9d5d5a3..a29ae39 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -87,6 +87,7 @@ %token RESERVE 613 %token RELEASE 614 %token COMMENT 700 +%token INCLUDE 901 //precedence order %left ASSIGN @@ -106,6 +107,7 @@ program: prototype_or_definition_list + | include_list prototype_or_definition_list ; @@ -123,7 +125,19 @@ prototype_or_definition_list: prototype: L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID + ; + + +include_list: + include_statement SEMI_COLON include_list + | include_statement + ; + + + +include_statement: + INCLUDE C_STRING SEMI_COLON ; diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index 7034997..a8bd8af 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -19,6 +19,8 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] %% +"#include" { if(tok_flag != NULL) {print_tok(INCLUDE);} incr(line_number,column_number,INCLUDE); return INCLUDE; } + "integer" { if(tok_flag != NULL) {print_tok(T_INTEGER);} incr(line_number,column_number,T_INTEGER); yylval.tn = integ; return T_INTEGER; } "address" { if(tok_flag != NULL) {print_tok(T_ADDRESS);} incr(line_number,column_number,T_ADDRESS); yylval.tn = addr; return T_ADDRESS; } "Boolean" { if(tok_flag != NULL) {print_tok(T_INTEGER);} incr(line_number,column_number,T_INTEGER); yylval.tn = boo; return T_BOOLEAN; } diff --git a/src/typedefs.h b/src/typedefs.h index 3b75b3a..15fe996 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -56,4 +56,5 @@ // comments #define COMMENT 700 //Additional tokens -#define ACCESS 801 \ No newline at end of file +#define ACCESS 801 +#define INCLUDE 901 \ No newline at end of file diff --git a/tests/sprint1/test/sp1_include.alpha b/tests/sprint1/test/sp1_include.alpha new file mode 100644 index 0000000..190d02c --- /dev/null +++ b/tests/sprint1/test/sp1_include.alpha @@ -0,0 +1,4 @@ +(* TEST: [-tok -asc -tc] *) +#include "alpha.h"; +#include "alpha.h"; +#include "alpha.h"; \ No newline at end of file From accb21c78a295433f1d64834b26b9267ee3756d9 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Sun, 4 May 2025 17:43:08 -0400 Subject: [PATCH 047/109] I added some more backpatching and some more files for testing --- src/grammar.y | 82 ++++++++++++++++++++--- src/intermediate_code.c | 2 + tests/carl/NoErrors/functionValue.alpha | 6 +- tests/sprint3/test/sp3_arr_reserve.alpha | 11 +++ tests/sprint3/test/sp3_if_else_sse.alpha | 4 +- tests/sprint3/test/sp3_while_sse.alpha | 4 +- tests/sprint4/test/sp4_cg_fib.alpha | 18 +++++ tests/sprint4/test/sp4_cg_less_than.alpha | 4 +- 8 files changed, 113 insertions(+), 18 deletions(-) create mode 100644 tests/sprint3/test/sp3_arr_reserve.alpha create mode 100644 tests/sprint4/test/sp4_cg_fib.alpha diff --git a/src/grammar.y b/src/grammar.y index c190783..6a09303 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -609,7 +609,14 @@ compound_statement: simple_statement: assignable ASSIGN expression - { printdebug("simple statement"); + { +// ---------------------------------------------------------------------------- + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); + emit_backpatch(S_Pop(FalseList), getLabel(current)); +// ---------------------------------------------------------------------------- + + printdebug("simple statement"); TableNode* node; if((getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_FUNCTION_TYPE)|| (getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_ARRAY_TYPE)|| @@ -691,7 +698,7 @@ ablock: argument_list: expression{ - TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); + TableNode * arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); // ---------------------------------------------------------------------------- // this is emitting the param withthe wrong TableNode // We need to fiture out how to get the right one. @@ -838,7 +845,11 @@ expression: | expression AND expression { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); // ---------------------------------------------------------------------------- + uint_least8_t b = 0; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_conditional_jump(E_IF_X_FALSE, 0, tn_or_const(NODE, $1)); @@ -864,7 +875,8 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); - + b = 1; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); emit_goto(0); t = S_Peek(TrueList); if(t==NULL){ @@ -875,8 +887,6 @@ expression: S_Merge(FalseList); // ---------------------------------------------------------------------------- printdebug("AND"); - char* temp = temp_var_gen(); - TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { //emit_binary_op(E_AND,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; @@ -888,7 +898,11 @@ expression: | expression OR expression { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); // ---------------------------------------------------------------------------- + uint_least8_t b = 1; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $1)); @@ -914,6 +928,8 @@ expression: S_Push(TrueList, t, 1); } S_Push(t, current, 1); + b = 0; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); emit_goto(0); t = S_Peek(FalseList); if(t==NULL){ @@ -925,8 +941,6 @@ expression: // ---------------------------------------------------------------------------- printdebug("OR"); if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { - char* temp = temp_var_gen(); - TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); $$ = node; } else { $$=undefined; @@ -1014,9 +1028,59 @@ expression: } // TODO: We need to type check this. - | RESERVE ID {$$ = undefined; } + | RESERVE ID { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) != TYPE_RECORD){ + throw_error(ERROR_TYPE, "Invalid Reserve expression with object %s of type %s.", + getName((TableNode*)n), getType((TableNode*)n)); + $$=undefined; + } + int v = getRecTotal(getTypeEntry(n)); + emit_reserve(node, tn_or_const(INTEGER, &v)); + $$ = node; + } | RELEASE ID {$$ = undefined; } - | RESERVE ID L_PAREN argument_list R_PAREN {$$ = undefined; } + | RESERVE ID { + cur = CreateScope(cur, -1,-1); + } L_PAREN argument_list R_PAREN { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); + 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, $2)); + $$ = node; +/* + TableNode * t = getFirstEntry(cur); + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) == TYPE_ARRAY){ + int array_dims = getNumArrDim(getTypeEntry(n)); + if ($5 != array_dims) { + throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", array_dims, $5); + }else{ + while(t != NULL && t != undefined && getName(t)[0] != '&'){ + t = getNextEntry(t); + } + if(getTypeEntry(t) != integ){ + throw_error(ERROR_TYPE, "Arg for an array is not of type integer"); + } + t = getNextEntry(t); + while(t != NULL && t != undefined && getName(t)[0] != '&'){ + while(getTypeEntry(t) != integ)(arg_given != NULL && getName(arg_given)[0]!='&'){ + arg_given = getNextEntry(arg_given); + } + if(getTypeEntry(arg_given) != getTypeEntry(param_arg_type)){ + throw_error(ERROR_TYPE, "expected type %s expression as argument of a record in function call but got type %s", getType(param_arg_type), getType(arg_given)); + } + arg_given = getNextEntry(arg_given); + param_arg_type = getNextEntry(param_arg_type); + } + } + } +*/ + } | RELEASE ID L_PAREN argument_list R_PAREN { int d = getAdInfoType((TableNode*)$2); diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 62fb563..957accb 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -309,6 +309,8 @@ void emit_return(TNodeOrConst * value){ } void emit_reserve(TableNode * result, TNodeOrConst * size){ + // this needs to change + // we need to take a int emit_parameter(size); emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); } diff --git a/tests/carl/NoErrors/functionValue.alpha b/tests/carl/NoErrors/functionValue.alpha index 8ad0e6c..0832c43 100644 --- a/tests/carl/NoErrors/functionValue.alpha +++ b/tests/carl/NoErrors/functionValue.alpha @@ -44,13 +44,13 @@ b(x) := { i := x; return a; } - + c(x) := { [string: s] s := "Hi!"; return x(s); } - + (* Function definition entry is the first function called @@ -65,7 +65,7 @@ entry(arg) := { result := 0; } else { - [ Boolean : b] + [ Boolean : b] result := entry("hello"); } result := c(f); diff --git a/tests/sprint3/test/sp3_arr_reserve.alpha b/tests/sprint3/test/sp3_arr_reserve.alpha new file mode 100644 index 0000000..114da34 --- /dev/null +++ b/tests/sprint3/test/sp3_arr_reserve.alpha @@ -0,0 +1,11 @@ + +type main: string -> integer +function entry: main +type t: 3 -> integer + + +entry (arg) := { + [ t:a] + a := reserve a(1, 3, 4); + return 0; +} diff --git a/tests/sprint3/test/sp3_if_else_sse.alpha b/tests/sprint3/test/sp3_if_else_sse.alpha index f5d7d79..cbbf116 100644 --- a/tests/sprint3/test/sp3_if_else_sse.alpha +++ b/tests/sprint3/test/sp3_if_else_sse.alpha @@ -14,7 +14,7 @@ bar (r,s) := { *) entry (arg) := { [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] - if ( ( x < y ) (* < ( z & t )*)) then { + if ( ( x & y ) ) then { (* if ( x Date: Sun, 4 May 2025 17:46:14 -0400 Subject: [PATCH 048/109] include added --- src/grammar.y | 5 +++-- tests/sprint1/test/sp1_include.alpha | 6 +++--- tests/sprint4/test/sp4_cg_add.alpha | 3 +++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index a29ae39..ef5bbcf 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -107,6 +107,7 @@ program: prototype_or_definition_list + | include_list | include_list prototype_or_definition_list ; @@ -130,14 +131,14 @@ prototype: include_list: - include_statement SEMI_COLON include_list + include_statement include_list | include_statement ; include_statement: - INCLUDE C_STRING SEMI_COLON + INCLUDE C_STRING ; diff --git a/tests/sprint1/test/sp1_include.alpha b/tests/sprint1/test/sp1_include.alpha index 190d02c..27a2500 100644 --- a/tests/sprint1/test/sp1_include.alpha +++ b/tests/sprint1/test/sp1_include.alpha @@ -1,4 +1,4 @@ (* TEST: [-tok -asc -tc] *) -#include "alpha.h"; -#include "alpha.h"; -#include "alpha.h"; \ No newline at end of file +#include "alpha.h" +#include "alpha.h" +#include "alpha.h" \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_add.alpha b/tests/sprint4/test/sp4_cg_add.alpha index 0398f89..97d23b4 100644 --- a/tests/sprint4/test/sp4_cg_add.alpha +++ b/tests/sprint4/test/sp4_cg_add.alpha @@ -1,4 +1,7 @@ (* TEST: [-asc -tc -cg -ir] *) +#include "alpha.h" +#include "alpha.h2" +#include "alpha.h3" type main: integer -> integer function test: main From cd72d46ec34ee6b97763e81087e37188eaa056f2 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Sat, 3 May 2025 12:52:23 -0400 Subject: [PATCH 049/109] I fixed the way we are doing the evaluation of == and < Getting to &&, || next. Not sure if ! is correct --- src/grammar.y | 53 ++++++++++++++++++++++++++++++++++------- src/intermediate_code.c | 21 +++++++++------- 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index ef5bbcf..374a3dd 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -603,6 +603,21 @@ compound_statement: emit_label(*l); S_Push(stack, l, 2); } expression R_PAREN { + emit_backpatch(S_Pop(TrueList), getLabel(current)); + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $4)); + 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); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); } sblock { @@ -616,8 +631,23 @@ compound_statement: S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); }expression R_PAREN THEN { + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $4)); + 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); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); + } sblock ELSE { // NOTE we are not going back to int l = label_gen(); @@ -805,8 +835,10 @@ expression: if(getTypeEntry((TableNode*)$2) == boo) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - emit_unary_op(E_NOT,node,tn_or_const(NODE,$2)); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + Stack * t = S_Pop(TrueList); + Stack * f = S_Pop(FalseList); + S_Push(TrueList, f, 0); + S_Push(FalseList, t, 0); //result of unary operation $$ = node; } else { @@ -917,7 +949,12 @@ expression: | expression LESS_THAN expression { - emit_conditional_jump(E_LESS_THAN, 0, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); +// ---------------------------------------------------------------------------- + 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)); + /* + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); if(t==NULL){ t = S_Init(); @@ -931,15 +968,12 @@ expression: 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(); - TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); $$ = node; } else if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==boo){ - 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; @@ -953,6 +987,8 @@ 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)); Stack * t = S_Peek(TrueList); if(t==NULL){ @@ -967,6 +1003,7 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); + */ $$ = node; } else { diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 44c6016..c807096 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -58,6 +58,11 @@ int S_Size(Stack *s){ return s->size; } +void S_Merge(Stack *s1, Stack *s2){ + for (Instruction * i = S_Pop(s1); i; i = S_Pop(s1)){ + S_Push(s2, i, 1); + } +} void emit_backpatch(Stack * s, int l){ for (Instruction * i = S_Pop(s); i; i = S_Pop(s)){ i->label = l; @@ -501,7 +506,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 True GOTO %d\n", i->index, get_string(i->operand1), i->label @@ -509,7 +514,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 @@ -518,21 +523,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: if ( %s < %s ) GOTO %d\n", + "%4.d: %s = %s < %s\n", i->index, + getName(i->result), get_string(i->operand1), - get_string(i->operand2), - i->label + get_string(i->operand2) ); break; case E_EQUAL_TO: // this feels wrong I need to TODO: this fprintf(out_file, - "%4.d: if ( %s = %s ) GOTO %d\n", + "%4.d: %s = %s == %s\n", i->index, + getName(i->result), get_string(i->operand1), - get_string(i->operand2), - i->label + get_string(i->operand2) ); break; case E_CALL: From 468e3f67f7c6c593a7a18a5de278648ab24163c7 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Sat, 3 May 2025 12:53:13 -0400 Subject: [PATCH 050/109] I added some test files Looks good so far Need someone to spot check --- .../sprint3/test/sp3_if_else_nested_exp.alpha | 25 ++++++++++++++++ .../sprint3/test/sp3_while_nested_bools.alpha | 29 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 tests/sprint3/test/sp3_if_else_nested_exp.alpha create mode 100644 tests/sprint3/test/sp3_while_nested_bools.alpha diff --git a/tests/sprint3/test/sp3_if_else_nested_exp.alpha b/tests/sprint3/test/sp3_if_else_nested_exp.alpha new file mode 100644 index 0000000..08161f2 --- /dev/null +++ b/tests/sprint3/test/sp3_if_else_nested_exp.alpha @@ -0,0 +1,25 @@ +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: x ; integer: y; integer: z;integer: t] + + if ( (x = y) < ( z = t ) ) then { + if ( (x < y) = ( z < t ) ) then { + x := x; + } else { + x := 1; (* bar('c', 7); *) + } + } else { + return 0; + } +} diff --git a/tests/sprint3/test/sp3_while_nested_bools.alpha b/tests/sprint3/test/sp3_while_nested_bools.alpha new file mode 100644 index 0000000..5a6920e --- /dev/null +++ b/tests/sprint3/test/sp3_while_nested_bools.alpha @@ -0,0 +1,29 @@ +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: x ; integer: y; integer: z;integer: t] + while ( (!(x = y)) < ( z = t ) ) { + x := x; + while ( (x < y) = ( z < t ) ) { + y := y; + } + (* + if ( (x = y) = ( z < t ) ) then { + x := 1; + } else { + x := 1; + } + *) + } + return 0; +} From 18b5daea0edcddbe22df2b737b40409086466b0e Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Sat, 3 May 2025 19:29:38 -0400 Subject: [PATCH 051/109] It seems to be working but I need to ckeck again --- src/grammar.y | 114 +++++++++++++++++----- src/intermediate_code.c | 11 ++- src/intermediate_code.h | 1 + tests/sprint3/test/sp3_if_else_sse.alpha | 26 +++++ tests/sprint3/test/sp3_if_else_sse2.alpha | 29 ++++++ tests/sprint3/test/sp3_while_sse.alpha | 27 +++++ 6 files changed, 181 insertions(+), 27 deletions(-) create mode 100644 tests/sprint3/test/sp3_if_else_sse.alpha create mode 100644 tests/sprint3/test/sp3_if_else_sse2.alpha create mode 100644 tests/sprint3/test/sp3_while_sse.alpha diff --git a/src/grammar.y b/src/grammar.y index 374a3dd..9c50823 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -631,23 +631,8 @@ compound_statement: S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); }expression R_PAREN THEN { - emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $4)); - 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); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); - } sblock ELSE { // NOTE we are not going back to int l = label_gen(); @@ -921,11 +906,47 @@ expression: | expression AND expression { +// ---------------------------------------------------------------------------- + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $1)); + Stack * t1 = S_Peek(TrueList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(TrueList, t1, 1); + } + S_Push(t1, current, 1); + emit_goto(0); + t1 = S_Peek(FalseList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(FalseList, t1, 1); + } + S_Push(t1, current, 1); + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); + + emit_conditional_jump(E_IF_X_TRUE, 0, 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); + S_Merge(FalseList); + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); +// ---------------------------------------------------------------------------- printdebug("AND"); + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { - char* temp = temp_var_gen(); - TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - emit_binary_op(E_AND,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); + //emit_binary_op(E_AND,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -935,11 +956,47 @@ expression: | expression OR expression { +// ---------------------------------------------------------------------------- + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $1)); + Stack * t1 = S_Peek(TrueList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(TrueList, t1, 1); + } + S_Push(t1, current, 1); + emit_goto(0); + t1 = S_Peek(FalseList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(FalseList, t1, 1); + } + S_Push(t1, current, 1); + emit_label(label_gen()); + emit_backpatch(S_Pop(FalseList), getLabel(current)); + + emit_conditional_jump(E_IF_X_TRUE, 0, 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); + S_Merge(TrueList); + // This is very inportant. + // With OR W DO NOT BP THE TRUELIST Only with AND +// ---------------------------------------------------------------------------- printdebug("OR"); if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - emit_binary_op(E_OR,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); + // emit_binary_op(E_OR,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -949,11 +1006,10 @@ expression: | expression LESS_THAN expression { -// ---------------------------------------------------------------------------- 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)); - /* emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); if(t==NULL){ @@ -968,6 +1024,9 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); + // emit_label(label_gen()); + // emit_backpatch(S_Pop(TrueList), getLabel(current)); + /* */ // ---------------------------------------------------------------------------- printdebug("less than expression"); @@ -983,13 +1042,11 @@ expression: | expression EQUAL_TO expression { - printdebug("equals check 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)); + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); if(t==NULL){ t = S_Init(); @@ -1003,7 +1060,12 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); - */ + // emit_label(label_gen()); + // emit_backpatch(S_Pop(TrueList), getLabel(current)); +// ---------------------------------------------------------------------------- + printdebug("equals check expression"); + if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1) != undefined) { + // emit_binary_op(E_EQUAL_TO, node, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); $$ = node; } else { diff --git a/src/intermediate_code.c b/src/intermediate_code.c index c807096..62fb563 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -58,7 +58,16 @@ int S_Size(Stack *s){ return s->size; } -void S_Merge(Stack *s1, Stack *s2){ +void S_Merge(Stack *list){ + Stack* s1 = S_Pop(list); + Stack* s2 = S_Peek(list); + if(s1 == NULL){ + return; + } + if(s2 == NULL){ + S_Push(list, s1, 0); + return; + } for (Instruction * i = S_Pop(s1); i; i = S_Pop(s1)){ S_Push(s2, i, 1); } diff --git a/src/intermediate_code.h b/src/intermediate_code.h index ace41a8..f362874 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -32,6 +32,7 @@ void * S_Pop(Stack *s); void * S_Peek(Stack *s); bool S_IsEmpty(Stack *s); int S_Size(Stack *s); +void S_Merge(Stack *list); //______________________________________________________________________________________________ typedef union TNConstUnion TNConstUnion; diff --git a/tests/sprint3/test/sp3_if_else_sse.alpha b/tests/sprint3/test/sp3_if_else_sse.alpha new file mode 100644 index 0000000..24ec9ee --- /dev/null +++ b/tests/sprint3/test/sp3_if_else_sse.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) := { + [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] + if ( !( x < y ) & ( z & t ) ) then { + (* if ( result < w.y ) then { + result := 8; + } else { + result := 9; + } *) + z := t; + } else { + y := true; (* bar('c', 7); *) + } + return 0; +} diff --git a/tests/sprint3/test/sp3_if_else_sse2.alpha b/tests/sprint3/test/sp3_if_else_sse2.alpha new file mode 100644 index 0000000..c26ce11 --- /dev/null +++ b/tests/sprint3/test/sp3_if_else_sse2.alpha @@ -0,0 +1,29 @@ +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) := { + [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] + if ( y & z | t ) then { + (* if ( ( x < y ) & ( z = t ) ) then { + y := z < t; + t:= 0; + } else { + t := z = t; + z := 1; + } *) + t := true; + } else { + y := true; (* bar('c', 7); *) + } + (* x := x & y; *) + return 0; +} diff --git a/tests/sprint3/test/sp3_while_sse.alpha b/tests/sprint3/test/sp3_while_sse.alpha new file mode 100644 index 0000000..89fa23f --- /dev/null +++ b/tests/sprint3/test/sp3_while_sse.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) := { + [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] + while ( !( x & y ) (* | ( z | t ) *) ) { + (* + if ( ( x < y ) & ( z = t ) ) then { + y := z < t; + } else { + t := z = t; + } + *) + y := true; (* bar('c', 7); *) + } + (* x := x & y; *) + return 0; +} From 4ae76d0341fece2ac9ed5be576efc973b703ed6d Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Sun, 4 May 2025 14:30:04 -0400 Subject: [PATCH 052/109] I think it was broken so I fixed it --- src/grammar.y | 73 +++++++------------ tests/sprint3/test/sp3_if_else_sse.alpha | 17 +++-- tests/sprint3/test/sp3_if_else_sse2.alpha | 23 +++--- .../sprint3/test/sp3_while_nested_bools.alpha | 10 +-- 4 files changed, 57 insertions(+), 66 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 9c50823..774f843 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -603,21 +603,6 @@ compound_statement: emit_label(*l); S_Push(stack, l, 2); } expression R_PAREN { - emit_backpatch(S_Pop(TrueList), getLabel(current)); - emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $4)); - 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); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); } sblock { @@ -907,40 +892,40 @@ expression: | expression AND expression { // ---------------------------------------------------------------------------- - emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $1)); - Stack * t1 = S_Peek(TrueList); - if(t1==NULL){ - t1 = S_Init(); - S_Push(TrueList, t1, 1); - } - S_Push(t1, current, 1); - emit_goto(0); - t1 = S_Peek(FalseList); + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); + emit_conditional_jump(E_IF_X_FALSE, 0, tn_or_const(NODE, $1)); + Stack * t1 = S_Peek(FalseList); if(t1==NULL){ t1 = S_Init(); S_Push(FalseList, t1, 1); } S_Push(t1, current, 1); + emit_goto(0); + t1 = S_Peek(TrueList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(TrueList, t1, 1); + } + S_Push(t1, current, 1); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); - - emit_conditional_jump(E_IF_X_TRUE, 0, 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); + emit_conditional_jump(E_IF_X_FALSE, 0, tn_or_const(NODE, $3)); + Stack * t = S_Peek(FalseList); if(t==NULL){ t = S_Init(); S_Push(FalseList, t, 1); } S_Push(t, current, 1); + + emit_goto(0); + t = S_Peek(TrueList); + if(t==NULL){ + t = S_Init(); + S_Push(TrueList, t, 1); + } + S_Push(t, current, 1); S_Merge(FalseList); - emit_label(label_gen()); - emit_backpatch(S_Pop(TrueList), getLabel(current)); // ---------------------------------------------------------------------------- printdebug("AND"); char* temp = temp_var_gen(); @@ -957,6 +942,8 @@ expression: | expression OR expression { // ---------------------------------------------------------------------------- + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $1)); Stack * t1 = S_Peek(TrueList); if(t1==NULL){ @@ -973,7 +960,6 @@ expression: S_Push(t1, current, 1); emit_label(label_gen()); emit_backpatch(S_Pop(FalseList), getLabel(current)); - emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $3)); Stack * t = S_Peek(TrueList); if(t==NULL){ @@ -989,14 +975,11 @@ expression: } S_Push(t, current, 1); S_Merge(TrueList); - // This is very inportant. - // With OR W DO NOT BP THE TRUELIST Only with AND // ---------------------------------------------------------------------------- printdebug("OR"); if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - // emit_binary_op(E_OR,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -1009,6 +992,8 @@ expression: char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); // ---------------------------------------------------------------------------- + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_binary_op(E_LESS_THAN, node, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); @@ -1024,10 +1009,6 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); - // emit_label(label_gen()); - // emit_backpatch(S_Pop(TrueList), getLabel(current)); - /* - */ // ---------------------------------------------------------------------------- printdebug("less than expression"); if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==integ) { @@ -1045,6 +1026,8 @@ expression: char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); // ---------------------------------------------------------------------------- + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_binary_op(E_EQUAL_TO, node, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); @@ -1060,8 +1043,6 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); - // emit_label(label_gen()); - // emit_backpatch(S_Pop(TrueList), getLabel(current)); // ---------------------------------------------------------------------------- printdebug("equals check expression"); if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1) != undefined) { diff --git a/tests/sprint3/test/sp3_if_else_sse.alpha b/tests/sprint3/test/sp3_if_else_sse.alpha index 24ec9ee..f5d7d79 100644 --- a/tests/sprint3/test/sp3_if_else_sse.alpha +++ b/tests/sprint3/test/sp3_if_else_sse.alpha @@ -6,19 +6,24 @@ type main: string -> integer function entry: main function bar: T2 + (* bar (r,s) := { return 0; } + *) entry (arg) := { [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] - if ( !( x < y ) & ( z & t ) ) then { - (* if ( result < w.y ) then { - result := 8; + if ( ( x < y ) (* < ( z & t )*)) then { + + (* + if ( x Date: Sun, 4 May 2025 17:43:08 -0400 Subject: [PATCH 053/109] I added some more backpatching and some more files for testing --- src/grammar.y | 82 ++++++++++++++++++++--- src/intermediate_code.c | 2 + tests/given/test/functionValue.alpha | 6 +- tests/sprint3/test/sp3_arr_reserve.alpha | 11 +++ tests/sprint3/test/sp3_if_else_sse.alpha | 4 +- tests/sprint3/test/sp3_while_sse.alpha | 4 +- tests/sprint4/test/sp4_cg_fib.alpha | 18 +++++ tests/sprint4/test/sp4_cg_less_than.alpha | 4 +- 8 files changed, 113 insertions(+), 18 deletions(-) create mode 100644 tests/sprint3/test/sp3_arr_reserve.alpha create mode 100644 tests/sprint4/test/sp4_cg_fib.alpha diff --git a/src/grammar.y b/src/grammar.y index 774f843..064e56b 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -662,7 +662,14 @@ compound_statement: simple_statement: assignable ASSIGN expression - { printdebug("simple statement"); + { +// ---------------------------------------------------------------------------- + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); + emit_backpatch(S_Pop(FalseList), getLabel(current)); +// ---------------------------------------------------------------------------- + + printdebug("simple statement"); TableNode* node; if((getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_FUNCTION_TYPE)|| (getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_ARRAY_TYPE)|| @@ -744,7 +751,7 @@ ablock: argument_list: expression{ - TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); + TableNode * arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); // ---------------------------------------------------------------------------- // this is emitting the param withthe wrong TableNode // We need to fiture out how to get the right one. @@ -891,7 +898,11 @@ expression: | expression AND expression { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); // ---------------------------------------------------------------------------- + uint_least8_t b = 0; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_conditional_jump(E_IF_X_FALSE, 0, tn_or_const(NODE, $1)); @@ -917,7 +928,8 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); - + b = 1; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); emit_goto(0); t = S_Peek(TrueList); if(t==NULL){ @@ -928,8 +940,6 @@ expression: S_Merge(FalseList); // ---------------------------------------------------------------------------- printdebug("AND"); - char* temp = temp_var_gen(); - TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { //emit_binary_op(E_AND,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; @@ -941,7 +951,11 @@ expression: | expression OR expression { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); // ---------------------------------------------------------------------------- + uint_least8_t b = 1; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $1)); @@ -967,6 +981,8 @@ expression: S_Push(TrueList, t, 1); } S_Push(t, current, 1); + b = 0; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); emit_goto(0); t = S_Peek(FalseList); if(t==NULL){ @@ -978,8 +994,6 @@ expression: // ---------------------------------------------------------------------------- printdebug("OR"); if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { - char* temp = temp_var_gen(); - TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); $$ = node; } else { $$=undefined; @@ -1067,9 +1081,59 @@ expression: } // TODO: We need to type check this. - | RESERVE ID {$$ = undefined; } + | RESERVE ID { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) != TYPE_RECORD){ + throw_error(ERROR_TYPE, "Invalid Reserve expression with object %s of type %s.", + getName((TableNode*)n), getType((TableNode*)n)); + $$=undefined; + } + int v = getRecTotal(getTypeEntry(n)); + emit_reserve(node, tn_or_const(INTEGER, &v)); + $$ = node; + } | RELEASE ID {$$ = undefined; } - | RESERVE ID L_PAREN argument_list R_PAREN {$$ = undefined; } + | RESERVE ID { + cur = CreateScope(cur, -1,-1); + } L_PAREN argument_list R_PAREN { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); + 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, $2)); + $$ = node; +/* + TableNode * t = getFirstEntry(cur); + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) == TYPE_ARRAY){ + int array_dims = getNumArrDim(getTypeEntry(n)); + if ($5 != array_dims) { + throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", array_dims, $5); + }else{ + while(t != NULL && t != undefined && getName(t)[0] != '&'){ + t = getNextEntry(t); + } + if(getTypeEntry(t) != integ){ + throw_error(ERROR_TYPE, "Arg for an array is not of type integer"); + } + t = getNextEntry(t); + while(t != NULL && t != undefined && getName(t)[0] != '&'){ + while(getTypeEntry(t) != integ)(arg_given != NULL && getName(arg_given)[0]!='&'){ + arg_given = getNextEntry(arg_given); + } + if(getTypeEntry(arg_given) != getTypeEntry(param_arg_type)){ + throw_error(ERROR_TYPE, "expected type %s expression as argument of a record in function call but got type %s", getType(param_arg_type), getType(arg_given)); + } + arg_given = getNextEntry(arg_given); + param_arg_type = getNextEntry(param_arg_type); + } + } + } +*/ + } | RELEASE ID L_PAREN argument_list R_PAREN { int d = getAdInfoType((TableNode*)$2); diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 62fb563..957accb 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -309,6 +309,8 @@ void emit_return(TNodeOrConst * value){ } void emit_reserve(TableNode * result, TNodeOrConst * size){ + // this needs to change + // we need to take a int emit_parameter(size); emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); } diff --git a/tests/given/test/functionValue.alpha b/tests/given/test/functionValue.alpha index 1ff9d50..31629bc 100644 --- a/tests/given/test/functionValue.alpha +++ b/tests/given/test/functionValue.alpha @@ -45,13 +45,13 @@ b(x) := { i := x; return a; } - + c(x) := { [string: s] s := "Hi!"; return x(s); } - + (* Function definition entry is the first function called @@ -66,7 +66,7 @@ entry(arg) := { result := 0; } else { - [ Boolean : b] + [ Boolean : b] result := entry("hello"); } result := c(f); diff --git a/tests/sprint3/test/sp3_arr_reserve.alpha b/tests/sprint3/test/sp3_arr_reserve.alpha new file mode 100644 index 0000000..114da34 --- /dev/null +++ b/tests/sprint3/test/sp3_arr_reserve.alpha @@ -0,0 +1,11 @@ + +type main: string -> integer +function entry: main +type t: 3 -> integer + + +entry (arg) := { + [ t:a] + a := reserve a(1, 3, 4); + return 0; +} diff --git a/tests/sprint3/test/sp3_if_else_sse.alpha b/tests/sprint3/test/sp3_if_else_sse.alpha index f5d7d79..cbbf116 100644 --- a/tests/sprint3/test/sp3_if_else_sse.alpha +++ b/tests/sprint3/test/sp3_if_else_sse.alpha @@ -14,7 +14,7 @@ bar (r,s) := { *) entry (arg) := { [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] - if ( ( x < y ) (* < ( z & t )*)) then { + if ( ( x & y ) ) then { (* if ( x Date: Sun, 4 May 2025 17:53:17 -0400 Subject: [PATCH 054/109] carl --- .gitignore | 3 +- Makefile | 1 + integer | 0 library/Makefile | 61 ++++++++++++++++++ library/alpha_driver.s | 81 ++++++++++++++++++++++++ library/alpha_lib_reg.s | 115 ++++++++++++++++++++++++++++++++++ library/printBoolean_reg.s | 26 ++++++++ library/printInt_reg.s | 22 +++++++ library/reserve_release_reg.s | 37 +++++++++++ 9 files changed, 345 insertions(+), 1 deletion(-) delete mode 100644 integer create mode 100644 library/Makefile create mode 100644 library/alpha_driver.s create mode 100644 library/alpha_lib_reg.s create mode 100644 library/printBoolean_reg.s create mode 100644 library/printInt_reg.s create mode 100644 library/reserve_release_reg.s diff --git a/.gitignore b/.gitignore index a6fca1a..0416ca8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ grammar.tab.h out tmp parser -*.save \ No newline at end of file +*.save +binaries \ No newline at end of file diff --git a/Makefile b/Makefile index 68a4858..45c4b02 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,7 @@ compiler: clean tmp $(OBJS) clean: rm -f $(EXE) rm -rf out + rm -rf binaries rm -rf tmp rm -f *.s rm -f *.out diff --git a/integer b/integer deleted file mode 100644 index e69de29..0000000 diff --git a/library/Makefile b/library/Makefile new file mode 100644 index 0000000..c02f4cd --- /dev/null +++ b/library/Makefile @@ -0,0 +1,61 @@ +# Makefile to make executables from alpha source code files +# and also make executables from some sample assembly files execising the alpha library +# +# Carl Alphonce +# April 20, 2024 + +# The alpha compiler and flags (adjust the flags as needed) +AC := ./alpha +AFLAGS := -tok -asc -tc -st -ir -cg + +# The preprocessor and flags (you should not adjust these) +CPP := cpp +CPPFLAGS := -P -x c + +# Adjust for the library your team is using (register-based or stack-based parameter passing) + +ALPHA_LIB = alpha_lib_reg.s ## Register-based parameter passing +#ALPHA_LIB = alpha_lib_st.s ## Stack-based parameter passing + +# Adjust for the parameter passing approach your compiler uses: +# alpha_driver_reg.s for register-based parameter passing +# alpha_driver_st.s for stack-based parameter passing +# This file provides a main function that packages up argv[1] (or "") as an alpha string +# (type 1->character) and calls entry with that argument + +ALPHA_DRIVER = alpha_driver_reg.s ## Register-based parameter passing +#ALPHA_DRIVER = alpha_driver_st.s ## Stack-based parameter passing + + +# Create an assembly (.s) file from an alpha source file +# This involves several steps: +%.s : %.alpha + @mv $< $<._temporary_ # 1. rename input file so we can us it as + @$(CPP) $(CPPFLAGS) $<._temporary_ > $< # 2. input to CPP, writing output to original filename + @$(AC) $(AFLAGS) $< # 3. run the alpha compiler on the pre-processed file + @mv $<._temporary_ $< # 4. restore the original input file + + + +# Examples of assembly code using the alpha library files +# In these examples the calling code is in assembly, and defines main (so the driver is not included here) + +# Example #1: calling the printBoolean function +printBoolean : printBoolean_reg.s + @gcc $< $(ALPHA_LIB) -no-pie -o $@ + +# Example #2: calling the printInt function +printInt : printInt_reg.s + @gcc $< $(ALPHA_LIB) -no-pie -o $@ + +# Example #3: calling the reserve and release functions +reserve_release : reserve_release_reg.s + @gcc $< $(ALPHA_LIB) -no-pie -o $@ + + +# The rule for assembling .s files and linking them together (using the gcc compiler driver) +# to produce an executable (assuming no earlier make rule triggers first) + +% : %.s $(ALPHA_LIB) $(ALPHA_DRIVER) + @gcc $< $(ALPHA_LIB) $(ALPHA_DRIVER) -no-pie -o $@ + diff --git a/library/alpha_driver.s b/library/alpha_driver.s new file mode 100644 index 0000000..0092d30 --- /dev/null +++ b/library/alpha_driver.s @@ -0,0 +1,81 @@ + .file "alpha_driver.c" + .text + .globl main + .type main, @function +main: +.LFB0: + endbr64 + pushq %rbp + movq %rsp, %rbp + subq $48, %rsp + movl %edi, -36(%rbp) + movq %rsi, -48(%rbp) + movl $0, -32(%rbp) + cmpl $1, -36(%rbp) + jle .L2 + movq -48(%rbp), %rax + addq $8, %rax + movq (%rax), %rax + movq %rax, %rdi + call strlen@PLT + movl %eax, -32(%rbp) +.L2: + movl -32(%rbp), %eax + cltq + addq $4, %rax + movq %rax, %rdi + call malloc@PLT + movq %rax, -16(%rbp) + movq -16(%rbp), %rax + movq %rax, -24(%rbp) + movq -24(%rbp), %rax + movl -32(%rbp), %edx + movl %edx, (%rax) + cmpl $1, -36(%rbp) + jle .L3 + addq $4, -24(%rbp) + movq -48(%rbp), %rax + movq 8(%rax), %rax + movq %rax, -8(%rbp) + movl $0, -28(%rbp) + jmp .L4 +.L5: + movl -28(%rbp), %eax + movslq %eax, %rdx + movq -8(%rbp), %rax + addq %rdx, %rax + movzbl (%rax), %edx + movq -24(%rbp), %rax + movb %dl, (%rax) + addq $1, -24(%rbp) + addl $1, -28(%rbp) +.L4: + movl -28(%rbp), %eax + cmpl -32(%rbp), %eax + jl .L5 +.L3: + movq -16(%rbp), %rax + movq %rax, %rdi + call entry@PLT + leave + ret +.LFE0: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/library/alpha_lib_reg.s b/library/alpha_lib_reg.s new file mode 100644 index 0000000..c8be988 --- /dev/null +++ b/library/alpha_lib_reg.s @@ -0,0 +1,115 @@ + .file "alpha_lib.c" + .section .rodata +.LC0: + .string "%d" + + .text + .globl printInteger + .type printInteger, @function +printInteger: +.LFB2: + pushq %rbp # push old base pointer + movq %rsp, %rbp # move base pointer + + subq $16, %rsp # make room on stack + movl %edi, -4(%rbp) # spill arg to stack + movl -4(%rbp), %eax # move argument to %eax + movl %eax, %esi + movl $.LC0, %edi + movl $0, %eax + call printf + movl $0, %eax + leave + ret +.LFE2: + .size printInteger, .-printInteger + + .globl printCharacter + .type printCharacter, @function +printCharacter: +.LFB4: + pushq %rbp + movq %rsp, %rbp + + subq $16, %rsp + movb %dil, %al + movb %al, -4(%rbp) + movsbl -4(%rbp), %eax + movl %eax, %edi + call putchar + movl $0, %eax + leave + ret +.LFE4: + .size printCharacter, .-printCharacter + + .section .rodata +.LC2: + .string "false" +.LC3: + .string "true" +.LC4: + .string "%s" + + .text + .globl printBoolean + .type printBoolean, @function +printBoolean: +.LFB5: + pushq %rbp + movq %rsp, %rbp + subq $16, %rsp + movb %dil, -4(%rbp) + cmpb $0, -4(%rbp) + jne .L8 + movl $.LC2, %eax + jmp .L9 +.L8: + movl $.LC3, %eax +.L9: + movq %rax, %rsi + movl $.LC4, %edi + movl $0, %eax + call printf + movl $0, %eax + leave + ret +.LFE5: + .size printBoolean, .-printBoolean + + .globl reserve + .type reserve, @function +reserve: +.LFB8: + pushq %rbp + movq %rsp, %rbp + subq $16, %rsp + movl %edi, -4(%rbp) + movl -4(%rbp), %eax + cltq + movq %rax, %rdi + call malloc + leave + ret +.LFE8: + .size reserve, .-reserve + + .globl release + .type release, @function +release: +.LFB9: + pushq %rbp + movq %rsp, %rbp + subq $16, %rsp + movq %rdi, -8(%rbp) + movq -8(%rbp), %rax + movq %rax, %rdi + call free + movl $0, %eax + leave + ret +.LFE9: + .size release, .-release + + .ident "GCC: (GNU) 6.4.0" + .section .note.GNU-stack,"",@progbits diff --git a/library/printBoolean_reg.s b/library/printBoolean_reg.s new file mode 100644 index 0000000..dd1eb84 --- /dev/null +++ b/library/printBoolean_reg.s @@ -0,0 +1,26 @@ + .file "printBoolean.c" + .text + .globl main + .type main, @function +main: +.LFB0: + pushq %rbp + movq %rsp, %rbp + + movb $1, %dil # the representation of 'true' + call printBoolean + movb $10, %dil + call printCharacter + + movb $0, %dil # the representation of 'false' + call printBoolean + movb $10, %dil + call printCharacter + + movl $0, %eax + popq %rbp + ret +.LFE0: + .size main, .-main + .ident "GCC: (GNU) 6.4.0" + .section .note.GNU-stack,"",@progbits diff --git a/library/printInt_reg.s b/library/printInt_reg.s new file mode 100644 index 0000000..512c576 --- /dev/null +++ b/library/printInt_reg.s @@ -0,0 +1,22 @@ + .file "printInt.c" + .text + .globl main + .type main, @function +main: +.LFB0: + pushq %rbp + movq %rsp, %rbp + + movl $10, %edi # Move the immediate value 10 to %edi + call printInteger # call the alpha_lib function printInteger + + movl $10, %edi # Put the \n character (decimal 10) into %edi + call printCharacter # then call the alpha_lib function printCharacter + + movl $0, %eax + popq %rbp + ret +.LFE0: + .size main, .-main + .ident "GCC: (GNU) 6.4.0" + .section .note.GNU-stack,"",@progbits diff --git a/library/reserve_release_reg.s b/library/reserve_release_reg.s new file mode 100644 index 0000000..827436a --- /dev/null +++ b/library/reserve_release_reg.s @@ -0,0 +1,37 @@ + .file "reserve_release.c" + .text + .globl main + .type main, @function +main: +.LFB0: + pushq %rbp + movq %rsp, %rbp + subq $16, %rsp + + movl $8, %edi # move sizeof(*a) into %edi + call reserve # call alpha_lib_reg function reserve + + movq %rax, -8(%rbp) # put the returned pointer on the stack at offset -8 + + movq -8(%rbp), %rax # put base pointer of struct (a) into %rax + movl $20, (%rax) # put value 20 into location pointed at by %rax --> (*a).x + movq -8(%rbp), %rax # put base pointer of struct (a) into %rax + movl $45, 4(%rax) # put value 45 into location 4(%rax) --> (*a).y + movq -8(%rbp), %rax # put base pointer of struct (a) into %rax + movl 4(%rax), %eax # move (*a).y into %eax + movl %eax, %edi # and then into %edi + call printInteger # call alpha_lib_reg function printInteger + movl $10, %edi # move '\n' into %edi + call printCharacter # call alpha_lib_reg function printCharacter + + movq -8(%rbp), %rax # put base pointer of struct (a) into %rax + movq %rax, %rdi # and then into %rdi + call release # call alpha_lib_reg function reserve + + movl $0, %eax + leave + ret +.LFE0: + .size main, .-main + .ident "GCC: (GNU) 6.4.0" + .section .note.GNU-stack,"",@progbits From 3f7c79b801d778f87ec0b5a8d7b22054af4a9c10 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Sun, 4 May 2025 18:41:02 -0400 Subject: [PATCH 055/109] genx --- Makefile | 8 ++++ genx.sh | 74 +++++++++++++++++++++++++++++ tests/sprint4/test/sp4_cg_add.alpha | 10 ++-- 3 files changed, 86 insertions(+), 6 deletions(-) create mode 100755 genx.sh diff --git a/Makefile b/Makefile index 45c4b02..3e6cbc7 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,8 @@ all: compiler compiler: clean tmp $(OBJS) $(CC) $(CFLAGS) -o $(EXE) $(OBJS) $(LDFLAGS) + chmod +x ./genx.sh + chmod +x ./test.sh clean: rm -f $(EXE) @@ -68,6 +70,7 @@ tmp/runner.o: src/runner.c src/runner.h tmp/flex.h tmp/grammar.tab.h # ----- Tests ----- test: chmod +x ./test.sh + chmod +x ./genx.sh ./test.sh tests/sprint1/test/ -diff ./test.sh tests/sprint2/test/ -diff ./test.sh tests/sprint3/test/ -diff @@ -76,21 +79,26 @@ test: test-s1: chmod +x ./test.sh + chmod +x ./genx.sh ./test.sh tests/sprint1/test/ -diff test-s2: chmod +x ./test.sh + chmod +x ./genx.sh ./test.sh tests/sprint2/test/ -diff test-s3: chmod +x ./test.sh + chmod +x ./genx.sh ./test.sh tests/sprint3/test/ -diff test-s4: chmod +x ./test.sh + chmod +x ./genx.sh ./test.sh tests/sprint4/test/ -diff test-given: chmod +x ./test.sh + chmod +x ./genx.sh ./test.sh tests/given/test/ -diff # ----------- \ No newline at end of file diff --git a/genx.sh b/genx.sh new file mode 100755 index 0000000..3534a7d --- /dev/null +++ b/genx.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +# GenX Tool # +# The Translators - Spring 2025 # + +RED='\033[0;31m' +GREEN='\033[0;32m' +ORANGE='\033[0;33m' +BLUE='\033[0;34m' +PURPLE='\033[0;35m' +CYAN='\033[0;36m' +LIGHTGRAY='\033[0;37m' +DARKGRAY='\033[1;30m' +LIGHTRED='\033[1;31m' +LIGHTGREEN='\033[1;32m' +YELLOW='\033[1;33m' +LIGHTBLUE='\033[1;34m' +LIGHTPURPLE='\033[1;35m' +LIGHTCYAN='\033[1;36m' +WHITE='\033[1;37m' + +if [ ! -f "./alpha" ]; then + echo -e "${RED}[GenX] ${YELLOW}File ./alpha not found! Generating with 'make'.${WHITE}" + make +fi + +help() { + echo -e "${WHITE}-----{ ${BLUE}GenX.sh Help ${WHITE}}-----\n" + echo -e "${YELLOW} Arguments: ${WHITE}" + echo -e "${GREEN} -help ${WHITE} Displays this message\n" + echo -e "${YELLOW} Usage: ${WHITE}" + echo -e "${GREEN} ./genx.sh ${WHITE} Generates executable file from \n" + echo -e "${YELLOW} Notes: ${WHITE}" + echo -e "${ORANGE} Generates .s and links alpha driver and general library." + echo -e "${WHITE}-----------------------------------------\n" + exit 1 +} + +if [ $# -eq 0 ]; then + help +fi + +if [ ! -d "binaries" ]; then + mkdir -p binaries +fi + +if [ $# -eq 1 ]; then + if [ -f "$1" ]; then + if [[ "$1" == *.alpha ]]; then + ./alpha -cg "$1" + filename=$(basename -- "$1") + filename="${filename:0:${#filename}-6}" + s_name="out/${filename}.s" + echo -e "${GREEN}[GenX] ${WHITE}Generated .s file..." + gcc ${s_name} library/alpha_lib_reg.s library/alpha_driver.s -no-pie -o binaries/${filename} + if [ $? -eq 0 ]; then + echo -e "${GREEN}[GenX] ${WHITE}Generated executable file..." + echo -e "${GREEN}[GenX] ${WHITE}Executable file: binaries/${filename}" + echo -e "${GREEN}[GenX] ${WHITE}Done!" + else + echo -e "${RED}[GenX] ${YELLOW}Error generating executable file!${WHITE}" + exit 1 + fi + else + echo -e "${RED}[GenX] ${YELLOW}File $1 is not a .alpha file!${WHITE}" + exit 1 + fi + else + echo -e "${RED}[GenX] ${YELLOW}File $1 not found!${WHITE}" + exit 1 + fi +else + help +fi \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_add.alpha b/tests/sprint4/test/sp4_cg_add.alpha index 97d23b4..3344ed5 100644 --- a/tests/sprint4/test/sp4_cg_add.alpha +++ b/tests/sprint4/test/sp4_cg_add.alpha @@ -1,11 +1,9 @@ (* TEST: [-asc -tc -cg -ir] *) -#include "alpha.h" -#include "alpha.h2" -#include "alpha.h3" -type main: integer -> integer -function test: main + +type main: string -> integer +function entry: main -test (a) := { +entry (arg) := { [integer:x; integer:y] y := 1; x := 3; From d57fa081d7f5c90a794b13c2396d7edc0c2465d5 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Sun, 4 May 2025 18:58:17 -0400 Subject: [PATCH 056/109] dont mess up silly --- src/grammar.h | 1 + src/grammar.y | 1 + src/runner.c | 17 +++++++++++++++-- src/runner.h | 3 +++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/grammar.h b/src/grammar.h index 5e1276b..86300f4 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -9,6 +9,7 @@ extern FILE *asc_flag; extern bool tc_flag; extern void insert_code_line(char * error_message, int line_number); +extern bool contains_errors; typedef enum { ERROR_RUNTIME = 1, diff --git a/src/grammar.y b/src/grammar.y index 064e56b..caea862 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1536,6 +1536,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; + contains_errors = true; // Grammar Fallback Case if (strcmp(err, "syntax error") == 0) { diff --git a/src/runner.c b/src/runner.c index 09a080f..ba25b2c 100644 --- a/src/runner.c +++ b/src/runner.c @@ -157,13 +157,22 @@ int run(FILE *alpha) { if (ir_flag != NULL) { printdebug("[-ir] Intermediate code is enabled."); - emit_as_file(ir_flag, begin); + if (contains_errors) { + emit_as_file(ir_flag, begin); + } else { + remove(ir_name); + } fclose(ir_flag); } if (cg_flag != NULL) { printdebug("[-cg] Code generation is enabled."); - generate(); + + if (contains_errors) { + generate(); + } else { + remove(cg_name); + } fclose(cg_flag); } @@ -236,8 +245,12 @@ int new_file(char *arg, char *alpha) { } else if (strcmp(arg, "-asc") == 0) { asc_flag = fopen(file_name, "w"); } else if (strcmp(arg, "-ir") == 0) { + ir_name = malloc(strlen(file_name) + 1); + strcpy(ir_name, file_name); ir_flag = fopen(file_name, "w"); } else if (strcmp(arg, "-cg") == 0) { + cg_name = malloc(strlen(file_name) + 1); + strcpy(cg_name, file_name); cg_flag = fopen(file_name, "w"); } return 0; diff --git a/src/runner.h b/src/runner.h index 979c36b..c423a36 100644 --- a/src/runner.h +++ b/src/runner.h @@ -58,6 +58,9 @@ bool tc_flag = false; bool DEBUG = false; int no_flag = 0; int arg; +bool contains_errors = false; +char * cg_name; +char * ir_name; TableNode *funprime; TableNode *arrayprim; From 31b1b051befa9c49656865abdca6a23d0f959cdd Mon Sep 17 00:00:00 2001 From: Scarlett Date: Sun, 4 May 2025 19:10:05 -0400 Subject: [PATCH 057/109] oop --- src/runner.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runner.c b/src/runner.c index ba25b2c..ab2754a 100644 --- a/src/runner.c +++ b/src/runner.c @@ -157,7 +157,7 @@ int run(FILE *alpha) { if (ir_flag != NULL) { printdebug("[-ir] Intermediate code is enabled."); - if (contains_errors) { + if (!contains_errors) { emit_as_file(ir_flag, begin); } else { remove(ir_name); @@ -168,7 +168,7 @@ int run(FILE *alpha) { if (cg_flag != NULL) { printdebug("[-cg] Code generation is enabled."); - if (contains_errors) { + if (!contains_errors) { generate(); } else { remove(cg_name); From 7e6bb2af8394c90844da0571ed953f99bce6abcc Mon Sep 17 00:00:00 2001 From: Partho Date: Sun, 4 May 2025 21:04:37 -0400 Subject: [PATCH 058/109] working on making sure arrays and reserve/release are working properly --- src/grammar.y | 142 ++++++++++++++++++++----- src/symbol_table.c | 74 ++++++++++++- tests/sprint4/test/sp4_tc_arrays.alpha | 27 +++++ 3 files changed, 216 insertions(+), 27 deletions(-) create mode 100644 tests/sprint4/test/sp4_tc_arrays.alpha diff --git a/src/grammar.y b/src/grammar.y index 064e56b..5e9ed19 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -752,6 +752,11 @@ ablock: argument_list: expression{ TableNode * arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); + if(getLine(cur)==-2){ + if(getTypeEntry(arg) != integ){ + throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg)); + } + } // ---------------------------------------------------------------------------- // this is emitting the param withthe wrong TableNode // We need to fiture out how to get the right one. @@ -772,6 +777,11 @@ argument_list: { TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); + if(getLine(cur)==-2){ + if(getTypeEntry(arg) != integ){ + throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg)); + } + } emit_parameter(tn_or_const(NODE,$1)); $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); @@ -1094,10 +1104,21 @@ expression: emit_reserve(node, tn_or_const(INTEGER, &v)); $$ = node; } - | RELEASE ID {$$ = undefined; } + | RELEASE ID { + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) != TYPE_RECORD){ + throw_error(ERROR_TYPE, "Invalid Release expression with object %s of type %s.", + getName((TableNode*)n), getType((TableNode*)n)); + $$=undefined; + } + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //emit release needed here + $$ = node; + } | RESERVE ID { - cur = CreateScope(cur, -1,-1); - } L_PAREN argument_list R_PAREN { + cur = CreateScope(cur, -2,-1); + } ablock { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); int a = S_Size(S_Peek(stack)) + 1; @@ -1105,6 +1126,81 @@ expression: S_Pop(stack); emit_function_call(node, a, tn_or_const(NODE, $2)); $$ = node; + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) != TYPE_ARRAY){ + throw_error(ERROR_TYPE, "Invalid Reserve expression with object %s of type %s.", + getName(n), getType(n)); + $$=undefined; + } + //doing more complicated type checking in a block + if(getNumArrDim(getTypeEntry(n)) != $4){ + throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", getNumArrDim(getTypeEntry(n)), $4); + $$=undefined; + } + cur = getParent(cur); + + + + /*TableNode * t = getFirstEntry(cur); + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) == TYPE_ARRAY){ + int array_dims = getNumArrDim(getTypeEntry(n)); + if ($5 != array_dims) { + throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", array_dims, $5); + }else{ + int traverse = 0; + while(t != NULL && t != undefined && getName(t)[0] != '&'){ + t = getNextEntry(t); + } + if(getTypeEntry(t) != integ){ + throw_error(ERROR_TYPE, "Arg for an array is not of type integer"); + $$= undefined; + }else{ + //seen first number + traverse++; + t = getNextEntry(t); + while(traverseadditionalinfo->RecAdInfo->numofelements; } -// This gets the array. Needs to up be updated to get the scope instead + SymbolTable *getRecList(TableNode *definition) { if (definition == NULL) { printdebug( @@ -462,6 +462,76 @@ int getRecSize(SymbolTable *tn) { } return -1; } +int getRecPosition(TableNode* rec, char* id){ + if (rec == NULL) { + printdebug( + "passed a NULL entry to getRecPosition. Invalid."); + return -1; + } + if (rec == undefined) { + printdebug( + "passed an undefined entry to getRecPosition. Invalid."); + return -1; + } + if (getAdInfoType(rec) != TYPE_RECORD_TYPE) { + printdebug( + "not checking the position of a record -- invalid op"); + return -1; + } + TableNode* cur = getFirstEntry(getRecList(rec)); + int i = 1; + while(cur != NULL){ + if(strcmp(getName(cur), id) == 0){ + return i; + } + cur = getNextEntry(cur); + i++; + } + if (cur == NULL){ + printdebug( + "passed an invalid entry to getRecPosition. Invalid."); + return -1; + }else{ + return i; + } +} + +int getElementOffset(TableNode *rec, char* id) { + if (rec == NULL) { + printdebug( + "passed a NULL entry to getElementOffset. Invalid."); + return -1; + } + if (rec == undefined) { + printdebug( + "passed an undefined entry to getElementOffset. Invalid."); + return -1; + } + if (getAdInfoType(rec) != TYPE_RECORD_TYPE) { + printdebug( + "not checking the offset of a record -- invalid op"); + return -1; + } + int* offsets = getRecOffsets(rec); + int position = getRecPosition(rec, id); + if (position == -1) { + printdebug( + "passed an invalid entry to getElementOffset. Invalid."); + return -1; + } + position = position - 1; + int total_offset = 0; + int current_position = 1; + while(current_position < position+1){ + //adding current element in struct + total_offset += offsets[2*current_position]; + //adding padding between elements + total_offset += offsets[2*current_position+1]; + current_position++; + } + //returning the offset of the start of the element + return total_offset; +} // below function takes a bool to see if parameter should be decomposed or not ; // note that functions only take one input and have one output @@ -1419,7 +1489,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if ((getFirstChild(node)) == NULL) { print_symbol_table(getFirstChild(node), file_ptr); } else { - if (getLine(getFirstChild(node)) == -1) { + if (getLine(getFirstChild(node)) < 0) { continue; } else { print_symbol_table(getFirstChild(node), file_ptr); diff --git a/tests/sprint4/test/sp4_tc_arrays.alpha b/tests/sprint4/test/sp4_tc_arrays.alpha new file mode 100644 index 0000000..19a31de --- /dev/null +++ b/tests/sprint4/test/sp4_tc_arrays.alpha @@ -0,0 +1,27 @@ +type string: 1 -> character +type a_of_s: 1 -> string +type main: integer -> integer +function entry: main + +(* maybe some other type definitions *) + +entry(arg) := { + [ string: one_name; string: another_name; a_of_s: many_names ] + one_name := "a string literal"; + another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *) + another_name(0) := 'C'; + another_name(1) := 'a'; + another_name(2) := 'r'; + another_name(3) := 'l'; + many_names := reserve many_names(3); + many_names(0) := one_name; + many_names(1) := another_name; + many_names(2) := reserve many_names(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *) + many_names(2)(0) := 'P'; + many_names(2)(1) := 'a'; + many_names(2)(2) := 'r'; + many_names(2)(3) := 't'; + many_names(2)(4) := 'h'; + many_names(2)(5) := 'o'; + return 0; +} \ No newline at end of file From 8b0d1914096204e1a8f48d79213fb984245f6857 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Sun, 4 May 2025 22:53:55 -0400 Subject: [PATCH 059/109] EXECUTION!!!!!!!!!!!!!!!!!!! --- src/codegen.c | 16 +++++++++------- tests/sprint4/test/sp4_cg_add.alpha | 29 ++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 49748ce..9512929 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -7,6 +7,10 @@ int generate(){ offset = 0; currentsp = 0; Instruction *i = begin; + + // temporary + fprintf(cg_flag, ".globl entry\n"); + while (i != NULL) { switch(getOp(i)) { case E_LABEL: @@ -170,9 +174,8 @@ int generateAdd(Instruction *inst) { printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2))); return -1; } - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#addition start\n", getAddress(op1CG)); - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\taddl\t%%edx, %%eax\n"); + fprintf(cg_flag, "\n\tmovl\t%d(%%rbp), %%eax\t#addition start\n", getAddress(op1CG)); + fprintf(cg_flag, "\taddl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#addition end\n", getAddress(cg)); return 0; } @@ -629,7 +632,6 @@ int generateCall(Instruction *inst){ fprintf(cg_flag, "\tcall %s\n", getName(getTN(op1))); - fprintf(cg_flag, "\taddq\t$%d, %%rsp\n", 8 + getConst(op1)); //now for the return CGNode *cg = findCG(getResult(inst)); @@ -660,7 +662,7 @@ int generateReturn(Instruction *inst){ } fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#return %s\n", getAddress(cg), getName(getTN(op1))); - fprintf(cg_flag, "\tpopq\t%%rbp\n"); + fprintf(cg_flag, "\tleave\n"); fprintf(cg_flag, "\tret\n"); return 0; } @@ -688,8 +690,7 @@ int generateParam(Instruction *inst){ return -1; } - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#adding param start\n", getAddress(op1CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#adding param end\n", getPrimSize(getTypeEntry(getTN(op1)))); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%edi\t#adding param start\n", getAddress(op1CG)); return 0; } @@ -706,6 +707,7 @@ int generateFunctionStart(Instruction *inst) { fprintf(cg_flag, "%s:\n", getName(funDecTN)); fprintf(cg_flag, "\tpushq\t%%rbp\n"); fprintf(cg_flag, "\tmovq\t%%rsp, %%rbp\n"); + fprintf(cg_flag, "\tsubq\t$%d, %%rsp\n", 128); // [CHANGE ME] 128 is a placeholder for the stack size //now we need to add the CGs of nodes to the CG list by doing assign from the // have function declararation node diff --git a/tests/sprint4/test/sp4_cg_add.alpha b/tests/sprint4/test/sp4_cg_add.alpha index 3344ed5..e3da55e 100644 --- a/tests/sprint4/test/sp4_cg_add.alpha +++ b/tests/sprint4/test/sp4_cg_add.alpha @@ -1,12 +1,35 @@ (* TEST: [-asc -tc -cg -ir] *) -type main: string -> integer -function entry: main +type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer0: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +function entry: string2integer entry (arg) := { - [integer:x; integer:y] + [integer:x; integer:y; integer: result] y := 1; x := 3; y := x + y; + + result := printInteger(y); + return y; } \ No newline at end of file From 0fc796aa25e063d9182d831066e1642a90313d53 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Sun, 4 May 2025 23:54:42 -0400 Subject: [PATCH 060/109] =?UTF-8?q?=F0=9F=A4=AF=F0=9F=A4=AF=F0=9F=A4=AF?= =?UTF-8?q?=F0=9F=A4=AF=F0=9F=A4=AF=F0=9F=A4=AF=F0=9F=A4=AF=F0=9F=A4=AF?= =?UTF-8?q?=F0=9F=A4=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- genx.sh | 44 +- library/Makefile | 61 -- library/printBoolean_reg.s | 26 - library/printInt_reg.s | 22 - library/reserve_release_reg.s | 37 - library/std.alpha | 24 + src/codegen.c | 238 +++--- src/grammar.h | 8 +- src/grammar.y | 2 +- src/intermediate_code.c | 935 +++++++++++----------- src/intermediate_code.h | 193 +++-- src/lexicalStructure.h | 5 +- src/runner.c | 1 - src/runner.h | 12 +- src/symbol_table.c | 46 +- src/symbol_table.h | 4 +- tests/programs/test/fib.alpha | 1 + tests/programs/test/ll.alpha | 1 + tests/sprint4/test/sp4_cg_add.alpha | 25 +- tests/sprint4/test/sp4_cg_and.alpha | 18 +- tests/sprint4/test/sp4_cg_demo.alpha | 8 - tests/sprint4/test/sp4_cg_demo.cg | 9 - tests/sprint4/test/sp4_cg_div.alpha | 18 +- tests/sprint4/test/sp4_cg_equal_to.alpha | 14 +- tests/sprint4/test/sp4_cg_fib.alpha | 18 - tests/sprint4/test/sp4_cg_less_than.alpha | 14 +- tests/sprint4/test/sp4_cg_mod.alpha | 18 +- tests/sprint4/test/sp4_cg_mult.alpha | 18 +- tests/sprint4/test/sp4_cg_neg.alpha | 16 +- tests/sprint4/test/sp4_cg_not.alpha | 16 +- tests/sprint4/test/sp4_cg_or.alpha | 18 +- tests/sprint4/test/sp4_cg_sub.alpha | 18 +- 32 files changed, 867 insertions(+), 1021 deletions(-) delete mode 100644 library/Makefile delete mode 100644 library/printBoolean_reg.s delete mode 100644 library/printInt_reg.s delete mode 100644 library/reserve_release_reg.s create mode 100644 library/std.alpha create mode 100644 tests/programs/test/fib.alpha create mode 100644 tests/programs/test/ll.alpha delete mode 100644 tests/sprint4/test/sp4_cg_demo.alpha delete mode 100644 tests/sprint4/test/sp4_cg_demo.cg delete mode 100644 tests/sprint4/test/sp4_cg_fib.alpha diff --git a/genx.sh b/genx.sh index 3534a7d..8da7039 100755 --- a/genx.sh +++ b/genx.sh @@ -44,17 +44,57 @@ if [ ! -d "binaries" ]; then mkdir -p binaries fi + +appendStd() { + if [ ! -f "$1" ]; then + echo "File not found: $1" + return 1 + fi + + backup_file="${1}.bak" + cp "$1" "$backup_file" + + temp_file=$(mktemp) + + while IFS= read -r line || [ -n "$line" ]; do + echo "$line" >> "$temp_file" + if [[ $line =~ ^#include\ \"[^\"]+\" ]]; then + include_file=$(echo "$line" | sed -n 's/.*"\([^"]*\)".*/\1/p') + if [[ $include_file == "std.alpha" ]]; then + echo -e "${GREEN}[GenX] ${WHITE}Including ${BLUE}std.alpha${WHITE}..." + if [ -f "library/std.alpha" ]; then + cat library/std.alpha >> "$temp_file" + else + echo -e "${RED}[GenX] ${YELLOW}File library/std.alpha not found!${WHITE}" + rm "$temp_file" + return 1 + fi + fi + fi + done < "$1" + + mv "$temp_file" "$1" +} + + if [ $# -eq 1 ]; then if [ -f "$1" ]; then if [[ "$1" == *.alpha ]]; then + appendStd "$1" ./alpha -cg "$1" + backup_file="${1}.bak" + if [ -f "$backup_file" ]; then + mv "$backup_file" "$1" + echo -e "${GREEN}[GenX] ${WHITE}Reverted $1 to its original state." + fi + filename=$(basename -- "$1") filename="${filename:0:${#filename}-6}" s_name="out/${filename}.s" - echo -e "${GREEN}[GenX] ${WHITE}Generated .s file..." + echo -e "${GREEN}[GenX] ${WHITE}Generated .s file." gcc ${s_name} library/alpha_lib_reg.s library/alpha_driver.s -no-pie -o binaries/${filename} if [ $? -eq 0 ]; then - echo -e "${GREEN}[GenX] ${WHITE}Generated executable file..." + echo -e "${GREEN}[GenX] ${WHITE}Generated executable file." echo -e "${GREEN}[GenX] ${WHITE}Executable file: binaries/${filename}" echo -e "${GREEN}[GenX] ${WHITE}Done!" else diff --git a/library/Makefile b/library/Makefile deleted file mode 100644 index c02f4cd..0000000 --- a/library/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -# Makefile to make executables from alpha source code files -# and also make executables from some sample assembly files execising the alpha library -# -# Carl Alphonce -# April 20, 2024 - -# The alpha compiler and flags (adjust the flags as needed) -AC := ./alpha -AFLAGS := -tok -asc -tc -st -ir -cg - -# The preprocessor and flags (you should not adjust these) -CPP := cpp -CPPFLAGS := -P -x c - -# Adjust for the library your team is using (register-based or stack-based parameter passing) - -ALPHA_LIB = alpha_lib_reg.s ## Register-based parameter passing -#ALPHA_LIB = alpha_lib_st.s ## Stack-based parameter passing - -# Adjust for the parameter passing approach your compiler uses: -# alpha_driver_reg.s for register-based parameter passing -# alpha_driver_st.s for stack-based parameter passing -# This file provides a main function that packages up argv[1] (or "") as an alpha string -# (type 1->character) and calls entry with that argument - -ALPHA_DRIVER = alpha_driver_reg.s ## Register-based parameter passing -#ALPHA_DRIVER = alpha_driver_st.s ## Stack-based parameter passing - - -# Create an assembly (.s) file from an alpha source file -# This involves several steps: -%.s : %.alpha - @mv $< $<._temporary_ # 1. rename input file so we can us it as - @$(CPP) $(CPPFLAGS) $<._temporary_ > $< # 2. input to CPP, writing output to original filename - @$(AC) $(AFLAGS) $< # 3. run the alpha compiler on the pre-processed file - @mv $<._temporary_ $< # 4. restore the original input file - - - -# Examples of assembly code using the alpha library files -# In these examples the calling code is in assembly, and defines main (so the driver is not included here) - -# Example #1: calling the printBoolean function -printBoolean : printBoolean_reg.s - @gcc $< $(ALPHA_LIB) -no-pie -o $@ - -# Example #2: calling the printInt function -printInt : printInt_reg.s - @gcc $< $(ALPHA_LIB) -no-pie -o $@ - -# Example #3: calling the reserve and release functions -reserve_release : reserve_release_reg.s - @gcc $< $(ALPHA_LIB) -no-pie -o $@ - - -# The rule for assembling .s files and linking them together (using the gcc compiler driver) -# to produce an executable (assuming no earlier make rule triggers first) - -% : %.s $(ALPHA_LIB) $(ALPHA_DRIVER) - @gcc $< $(ALPHA_LIB) $(ALPHA_DRIVER) -no-pie -o $@ - diff --git a/library/printBoolean_reg.s b/library/printBoolean_reg.s deleted file mode 100644 index dd1eb84..0000000 --- a/library/printBoolean_reg.s +++ /dev/null @@ -1,26 +0,0 @@ - .file "printBoolean.c" - .text - .globl main - .type main, @function -main: -.LFB0: - pushq %rbp - movq %rsp, %rbp - - movb $1, %dil # the representation of 'true' - call printBoolean - movb $10, %dil - call printCharacter - - movb $0, %dil # the representation of 'false' - call printBoolean - movb $10, %dil - call printCharacter - - movl $0, %eax - popq %rbp - ret -.LFE0: - .size main, .-main - .ident "GCC: (GNU) 6.4.0" - .section .note.GNU-stack,"",@progbits diff --git a/library/printInt_reg.s b/library/printInt_reg.s deleted file mode 100644 index 512c576..0000000 --- a/library/printInt_reg.s +++ /dev/null @@ -1,22 +0,0 @@ - .file "printInt.c" - .text - .globl main - .type main, @function -main: -.LFB0: - pushq %rbp - movq %rsp, %rbp - - movl $10, %edi # Move the immediate value 10 to %edi - call printInteger # call the alpha_lib function printInteger - - movl $10, %edi # Put the \n character (decimal 10) into %edi - call printCharacter # then call the alpha_lib function printCharacter - - movl $0, %eax - popq %rbp - ret -.LFE0: - .size main, .-main - .ident "GCC: (GNU) 6.4.0" - .section .note.GNU-stack,"",@progbits diff --git a/library/reserve_release_reg.s b/library/reserve_release_reg.s deleted file mode 100644 index 827436a..0000000 --- a/library/reserve_release_reg.s +++ /dev/null @@ -1,37 +0,0 @@ - .file "reserve_release.c" - .text - .globl main - .type main, @function -main: -.LFB0: - pushq %rbp - movq %rsp, %rbp - subq $16, %rsp - - movl $8, %edi # move sizeof(*a) into %edi - call reserve # call alpha_lib_reg function reserve - - movq %rax, -8(%rbp) # put the returned pointer on the stack at offset -8 - - movq -8(%rbp), %rax # put base pointer of struct (a) into %rax - movl $20, (%rax) # put value 20 into location pointed at by %rax --> (*a).x - movq -8(%rbp), %rax # put base pointer of struct (a) into %rax - movl $45, 4(%rax) # put value 45 into location 4(%rax) --> (*a).y - movq -8(%rbp), %rax # put base pointer of struct (a) into %rax - movl 4(%rax), %eax # move (*a).y into %eax - movl %eax, %edi # and then into %edi - call printInteger # call alpha_lib_reg function printInteger - movl $10, %edi # move '\n' into %edi - call printCharacter # call alpha_lib_reg function printCharacter - - movq -8(%rbp), %rax # put base pointer of struct (a) into %rax - movq %rax, %rdi # and then into %rdi - call release # call alpha_lib_reg function reserve - - movl $0, %eax - leave - ret -.LFE0: - .size main, .-main - .ident "GCC: (GNU) 6.4.0" - .section .note.GNU-stack,"",@progbits diff --git a/library/std.alpha b/library/std.alpha new file mode 100644 index 0000000..a2fc025 --- /dev/null +++ b/library/std.alpha @@ -0,0 +1,24 @@ +(* Standard Alpha Library - Provided by Carl *) + +type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +function entry: string2integer diff --git a/src/codegen.c b/src/codegen.c index 9512929..6da4ddf 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -3,87 +3,86 @@ #include "codegen.h" -int generate(){ +int generate() { offset = 0; currentsp = 0; Instruction *i = begin; - + // temporary fprintf(cg_flag, ".globl entry\n"); while (i != NULL) { - switch(getOp(i)) { - case E_LABEL: - generateLabel(i); - break; - case E_ADD: - generateAdd(i); - break; - case E_SUB: - generateSub(i); - break; - case E_MUL: - generateMult(i); - break; - case E_DIV: - generateDiv(i); - break; - case E_MOD: - generateMod(i); - break; - case E_OR: - generateOr(i); - break; - case E_AND: - generateAnd(i); - break; - case E_NEG: - generateNeg(i); - break; - case E_NOT: - generateNot(i); - break; - case E_ASSIGN: - generateAssign(i); - break; - case E_GOTO: - generateGoto(i); - break; - case E_IF_X_TRUE: - generateIfTrue(i); - break; - case E_IF_X_FALSE: - generateIfFalse(i); - break; - case E_LESS_THAN: - generateLessThan(i); - break; - case E_EQUAL_TO: - generateEqualTo(i); - break; - case E_CALL: - generateCall(i); - break; - case E_PARAM: - generateParam(i); - break; - case E_RETURN: - generateReturn(i); - break; - case E_INDEX_COPY_RIGHT: - generateCopyRight(i); - break; - case E_INDEX_COPY_LEFT: - generateCopyLeft(i); - break; - case E_ADDRESS_OF: - generateAddressOf(i); - break; - case E_FUNC_START: - generateFunctionStart(i); - break; - default: - ; + switch (getOp(i)) { + case E_LABEL: + generateLabel(i); + break; + case E_ADD: + generateAdd(i); + break; + case E_SUB: + generateSub(i); + break; + case E_MUL: + generateMult(i); + break; + case E_DIV: + generateDiv(i); + break; + case E_MOD: + generateMod(i); + break; + case E_OR: + generateOr(i); + break; + case E_AND: + generateAnd(i); + break; + case E_NEG: + generateNeg(i); + break; + case E_NOT: + generateNot(i); + break; + case E_ASSIGN: + generateAssign(i); + break; + case E_GOTO: + generateGoto(i); + break; + case E_IF_X_TRUE: + generateIfTrue(i); + break; + case E_IF_X_FALSE: + generateIfFalse(i); + break; + case E_LESS_THAN: + generateLessThan(i); + break; + case E_EQUAL_TO: + generateEqualTo(i); + break; + case E_CALL: + generateCall(i); + break; + case E_PARAM: + generateParam(i); + break; + case E_RETURN: + generateReturn(i); + break; + case E_INDEX_COPY_RIGHT: + generateCopyRight(i); + break; + case E_INDEX_COPY_LEFT: + generateCopyLeft(i); + break; + case E_ADDRESS_OF: + generateAddressOf(i); + break; + case E_FUNC_START: + generateFunctionStart(i); + break; + default:; } i = i->next; } @@ -133,14 +132,13 @@ CGNode *addCG(TableNode *tn, int sp) { return cg; } - int generateLabel(Instruction *inst) { if (inst == NULL) { return -1; } fprintf(cg_flag, ".L%d:\n", getLabel(inst)); - + return 0; } int generateAdd(Instruction *inst) { @@ -162,7 +160,6 @@ int generateAdd(Instruction *inst) { cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -181,7 +178,7 @@ int generateAdd(Instruction *inst) { } int generateSub(Instruction *instruction) { - /* + /* Both immediate: One immediate: Neither immediate: @@ -217,8 +214,8 @@ int generateSub(Instruction *instruction) { return 0; } -int generateMult(Instruction *inst){ - /* +int generateMult(Instruction *inst) { + /* Both immediate: One immediate: Neither immediate: @@ -254,7 +251,7 @@ int generateMult(Instruction *inst){ } int generateDiv(Instruction *inst) { - /* + /* Both immediate: One immediate: Neither immediate: @@ -284,10 +281,10 @@ int generateDiv(Instruction *inst) { return -1; } - 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%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 return 0; } @@ -321,15 +318,15 @@ int generateMod(Instruction *inst) { 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 - fprintf(cg_flag, "\tmovl\t%%edx, %d(%%rbp)\t#mod end\n", getAddress(cg)); //stores result from edx (remainder) + 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 + fprintf(cg_flag, "\tmovl\t%%edx, %d(%%rbp)\t#mod end\n", getAddress(cg)); //stores result from edx (remainder) return 0; } int generateOr(Instruction *inst) { - /* + /* Both immediate: One immediate: Neither immediate: @@ -376,7 +373,7 @@ int generateOr(Instruction *inst) { 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; } @@ -410,7 +407,7 @@ int generateAnd(Instruction *inst) { printdebug("generateAnd failed, %s is not initialized/in CG", getName(getTN(op2))); return -1; } - int label = label_gen(); + int label = label_gen(); fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start and\n", getAddress(op1CG)); fprintf(cg_flag, "\tje\t.L%dor2\n", label); @@ -426,7 +423,7 @@ int generateAnd(Instruction *inst) { 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) { @@ -486,7 +483,6 @@ int generateAssign(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); CGNode *cg = findCG(getResult(inst)); - if (op1 == NULL) { printdebug("generateAssign failed, NULL operand"); return -1; @@ -514,7 +510,7 @@ int generateAssign(Instruction *inst) { return 0; } -int generateGoto(Instruction *inst){ +int generateGoto(Instruction *inst) { return -1; } @@ -522,17 +518,17 @@ int generateCondGoto(Instruction *inst) { return -1; } -int generateIfTrue(Instruction *inst){ +int generateIfTrue(Instruction *inst) { return -1; // might just be a goto for where to go if something is true, or returning if something is true, or checking if true and writing goto if thats the case } -int generateIfFalse(Instruction *inst){ +int generateIfFalse(Instruction *inst) { return -1; } -int generateLessThan(Instruction *inst){ - /* +int generateLessThan(Instruction *inst) { + /* Both immediate: One immediate: Neither immediate: @@ -569,8 +565,8 @@ int generateLessThan(Instruction *inst){ return 0; } -int generateEqualTo(Instruction *inst){ - /* +int generateEqualTo(Instruction *inst) { + /* Both immediate: One immediate: Neither immediate: @@ -606,8 +602,7 @@ int generateEqualTo(Instruction *inst){ fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#equal to end\n", getAddress(cg)); return 0; } -int generateCall(Instruction *inst){ - +int generateCall(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); if (op1 == NULL) { @@ -630,7 +625,6 @@ int generateCall(Instruction *inst){ // return -1; //} - fprintf(cg_flag, "\tcall %s\n", getName(getTN(op1))); //now for the return @@ -643,22 +637,20 @@ int generateCall(Instruction *inst){ fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#store return from call\n", getAddress(cg)); return 0; - } -int generateReturn(Instruction *inst){ +int generateReturn(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); CGNode *cg; - if (op1 == NULL) { printdebug("generateReturn failed, NULL operand"); return -1; } - + cg = findCG(getTN(op1)); if (cg == NULL) { printdebug("generateReturn failed, trying to return %s not in CGList", getName(getTN(op1))); - return -1; + return -1; } fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#return %s\n", getAddress(cg), getName(getTN(op1))); @@ -666,38 +658,38 @@ int generateReturn(Instruction *inst){ fprintf(cg_flag, "\tret\n"); return 0; } -int generateCopyRight(Instruction *inst){ +int generateCopyRight(Instruction *inst) { return -1; } -int generateCopyLeft(Instruction *inst){ +int generateCopyLeft(Instruction *inst) { return -1; } -int generateAddressOf(Instruction *inst){ +int generateAddressOf(Instruction *inst) { return -1; } -int generateParam(Instruction *inst){ +int generateParam(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); - + if (op1 == NULL) { printdebug("generateParam failed, NULL operand"); return -1; } - + CGNode *op1CG = findCG(getTN(op1)); if (op1CG == NULL) { printdebug("generateParam failed, %s is not in CGlist", getName(getTN(op1))); return -1; } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%edi\t#adding param start\n", getAddress(op1CG)); + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%edi\t#adding param start\n", getAddress(op1CG)); return 0; } int generateFunctionStart(Instruction *inst) { currentsp = offset; TableNode *funDecTN = getResult(inst); - + if (funDecTN == NULL) { printdebug("generateFunctionStart failed, NULL tablenode"); return -1; @@ -707,27 +699,27 @@ int generateFunctionStart(Instruction *inst) { fprintf(cg_flag, "%s:\n", getName(funDecTN)); fprintf(cg_flag, "\tpushq\t%%rbp\n"); fprintf(cg_flag, "\tmovq\t%%rsp, %%rbp\n"); - fprintf(cg_flag, "\tsubq\t$%d, %%rsp\n", 128); // [CHANGE ME] 128 is a placeholder for the stack size + fprintf(cg_flag, "\tsubq\t$%d, %%rsp\n", 128); // [CHANGE ME] 128 is a placeholder for the stack size //now we need to add the CGs of nodes to the CG list by doing assign from the // have function declararation node //declaration ->getType: if record, go through each element and load param from stack and store to correct tn cg // if not, go get one element of type of param //declaration ->getType->getDefinitionScope?: go through first n entries to get table nodes for params - + TableNode *paramTN = getParameter(getTypeEntry(funDecTN)); SymbolTable *st = getFunScope(funDecTN); int paramOffset = 16; TableNode *tnToAdd = getFirstEntry(st); if (getAdInfoType(paramTN) != TYPE_RECORD_TYPE) { CGNode *paramCG = addCG(tnToAdd, offset); - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getAddress(paramCG)); } else { int numParams = getRecLength(paramTN); for (int i = 0; i < numParams; i++) { - CGNode *paramCG = addCG(tnToAdd, offset); - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); + CGNode *paramCG = addCG(tnToAdd, offset); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getAddress(paramCG)); paramOffset = getPrimSize(getTypeEntry(tnToAdd)); tnToAdd = getNextEntry(tnToAdd); diff --git a/src/grammar.h b/src/grammar.h index 86300f4..ec850a2 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -8,7 +8,7 @@ #include "../src/symbol_table.h" extern FILE *asc_flag; extern bool tc_flag; -extern void insert_code_line(char * error_message, int line_number); +extern void insert_code_line(char *error_message, int line_number); extern bool contains_errors; typedef enum { @@ -32,6 +32,6 @@ int offset; int currentsp; CGNode *cgList; -Stack* stack; -Stack* TrueList; -Stack* FalseList; +Stack *stack; +Stack *TrueList; +Stack *FalseList; diff --git a/src/grammar.y b/src/grammar.y index 80141e6..e20fcab 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -138,7 +138,7 @@ include_list: include_statement: - INCLUDE C_STRING + INCLUDE C_STRING ; diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 957accb..73d43df 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -3,20 +3,20 @@ #include "intermediate_code.h" -Stack * S_Init(){ - Stack * s = calloc(1, sizeof(*s)); +Stack *S_Init() { + Stack *s = calloc(1, sizeof(*s)); return s; } -void S_Free(Stack *s){ +void S_Free(Stack *s) { // since we are not responsible for the values we can just pop until // NULL - for (void * p = S_Pop(s); p != NULL; p = S_Pop(s)); + for (void *p = S_Pop(s); p != NULL; p = S_Pop(s)); free(s); } -void S_Push(Stack * s, void *v, int i) { - __Node * n = calloc(1, sizeof(*n)); +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; @@ -24,338 +24,336 @@ void S_Push(Stack * s, void *v, int i) { s->size = s->size + 1; } -void * S_Pop(Stack *s) { +void *S_Pop(Stack *s) { if (s == NULL || S_IsEmpty(s)) { - return NULL; + return NULL; } - __Node * node = s->n; + __Node *node = s->n; s->n = node->next; s->size = s->size - 1; - void * r = node->v; + void *r = node->v; free(node); return r; } - -void * S_Peek(Stack *s){ +void *S_Peek(Stack *s) { if (s == NULL || S_IsEmpty(s)) { - return NULL; + return NULL; } return s->n->v; } -bool S_IsEmpty(Stack *s){ - if(s == NULL || s->size == 0) { - return true; +bool S_IsEmpty(Stack *s) { + if (s == NULL || s->size == 0) { + return true; } return false; } -int S_Size(Stack *s){ +int S_Size(Stack *s) { if (s == NULL || S_IsEmpty(s)) { - return 0; + return 0; } return s->size; } -void S_Merge(Stack *list){ - Stack* s1 = S_Pop(list); - Stack* s2 = S_Peek(list); - if(s1 == NULL){ - return; - } - if(s2 == NULL){ - S_Push(list, s1, 0); - return; - } - for (Instruction * i = S_Pop(s1); i; i = S_Pop(s1)){ - S_Push(s2, i, 1); - } +void S_Merge(Stack *list) { + Stack *s1 = S_Pop(list); + Stack *s2 = S_Peek(list); + if (s1 == NULL) { + return; + } + if (s2 == NULL) { + S_Push(list, s1, 0); + return; + } + for (Instruction *i = S_Pop(s1); i; i = S_Pop(s1)) { + S_Push(s2, i, 1); + } } -void emit_backpatch(Stack * s, int l){ - for (Instruction * i = S_Pop(s); i; i = S_Pop(s)){ - i->label = l; - } +void emit_backpatch(Stack *s, int l) { + for (Instruction *i = S_Pop(s); i; i = S_Pop(s)) { + i->label = l; + } } //_______________________________________________________________________ -char * temp = NULL; +char *temp = NULL; - - /* +/* TODO: this is here to bring your attention to the comment bellow. check if start is NULL if it is assign it to the start globle variable otherwise make it next of current and set cur to your instruction. */ -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; - } -} - -void emit_detach(){ - current = current->prev; +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; + } } -void backpatch(Stack *s, int l){ - while (!S_IsEmpty(s)){ - Instruction * i = S_Pop(s); - set_label(i, l); - } +void emit_detach() { + current = current->prev; + current->next = NULL; } -TNodeOrConst * getOperand1(Instruction * i){ - return i->operand1; +void backpatch(Stack *s, int l) { + while (!S_IsEmpty(s)) { + Instruction *i = S_Pop(s); + set_label(i, l); + } } -TNodeOrConst * getOperand2(Instruction * i){ - return i->operand2; +TNodeOrConst *getOperand1(Instruction *i) { + return i->operand1; } -TableNode * getResult(Instruction * i){ - return i->result; +TNodeOrConst *getOperand2(Instruction *i) { + return i->operand2; } -Op getOp(Instruction * i){ - return i->opcode; +TableNode *getResult(Instruction *i) { + return i->result; } -int getLabel(Instruction * i){ - return i->label; +Op getOp(Instruction *i) { + return i->opcode; } -int get_index(Instruction * i){ - return i->index; +int getLabel(Instruction *i) { + return i->label; } -void set_label(Instruction * i, int label){ - i->label = label; +int get_index(Instruction *i) { + return i->index; } -bool isConst(TNodeOrConst * tnc) { - return tnc->d != NODE; +void set_label(Instruction *i, int label) { + i->label = label; } -TNodeOrConst * tn_or_const(Discriminant d, void * tnc) { - TNodeOrConst * count = calloc(1, sizeof(*count)); - count->d = d; - count->tnc_union = calloc(1, sizeof(*count->tnc_union)); - switch (d) { - case NODE: - count->tnc_union->node = tnc; - break; - case ADDRESS: - count->tnc_union->address = tnc; - break; - case STRING: - count->tnc_union->string = tnc; - break; - case INTEGER: - count->tnc_union->integer = *(int*)tnc; - break; - case CHARACTER: - count->tnc_union->character = *(char*)tnc; - break; - case BOOLEAN: - count->tnc_union->Boolean = *(uint_least8_t*)tnc; - break; - } - return count; +bool isConst(TNodeOrConst *tnc) { + return tnc->d != NODE; } -static void emit_helper(void){ - Instruction * inst = calloc(1, sizeof(*inst)); - if(begin == NULL){ - begin = current = inst; - current->index = 1; - } else { - current->next = inst; - inst->prev = current; - inst->index = current->index + 1; - current = inst; - } +TNodeOrConst *tn_or_const(Discriminant d, void *tnc) { + TNodeOrConst *count = calloc(1, sizeof(*count)); + count->d = d; + count->tnc_union = calloc(1, sizeof(*count->tnc_union)); + switch (d) { + case NODE: + count->tnc_union->node = tnc; + break; + case ADDRESS: + count->tnc_union->address = tnc; + break; + case STRING: + count->tnc_union->string = tnc; + break; + case INTEGER: + count->tnc_union->integer = *(int *)tnc; + break; + case CHARACTER: + count->tnc_union->character = *(char *)tnc; + break; + case BOOLEAN: + count->tnc_union->Boolean = *(uint_least8_t *)tnc; + break; + } + return count; +} + +static void emit_helper(void) { + Instruction *inst = calloc(1, sizeof(*inst)); + if (begin == NULL) { + begin = current = inst; + current->index = 1; + } else { + current->next = inst; + inst->prev = current; + inst->index = current->index + 1; + current = inst; + } } void emit_binary_op( - Op op, - TableNode * result, - TNodeOrConst * arg1, - TNodeOrConst * arg2 - ){ - emit_helper(); - current->opcode = op; - // TODO: create temp and remove result from param list - current->result = result; - current->operand1 = arg1; - current->operand2 = arg2; - } - -void emit_goto(int i){ - emit_helper(); - current->opcode = E_GOTO; - current->label = i; + Op op, + TableNode *result, + TNodeOrConst *arg1, + TNodeOrConst *arg2) { + emit_helper(); + current->opcode = op; + // TODO: create temp and remove result from param list + current->result = result; + current->operand1 = arg1; + current->operand2 = arg2; } -void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){ - emit_helper(); - current->opcode = op; - current->result = result; - current->operand1 = arg; - } - -void emit_assignment(TableNode * target, TNodeOrConst * source){ - emit_helper(); - current->opcode = E_ASSIGN; - current->result = target; - current->operand1 = source; - } - -char * get_string(TNodeOrConst * tc){ - char * s; - switch (tc->d) { - case NODE: - return getName(tc->tnc_union->node); - case ADDRESS: - return strdup("null"); - case STRING: - return tc->tnc_union->string; - case INTEGER: - s = calloc(10, sizeof(char)); - sprintf(s, "%d", tc->tnc_union->integer); - return s; - case CHARACTER: - s = calloc(2, sizeof(char)); - sprintf(s, "%c", tc->tnc_union->character); - return s; - case BOOLEAN: - if(tc->tnc_union->Boolean){ - return strdup("true"); - } - return strdup("false"); - } +void emit_goto(int i) { + emit_helper(); + current->opcode = E_GOTO; + current->label = i; } -void emit_label(int label){ - emit_helper(); - current->opcode = E_LABEL; - current->label = label; +void emit_unary_op(Op op, TableNode *result, TNodeOrConst *arg) { + emit_helper(); + current->opcode = op; + current->result = result; + current->operand1 = arg; } -void emit_jump(int label){ - emit_helper(); - current->opcode = E_GOTO; - current->label = label; +void emit_assignment(TableNode *target, TNodeOrConst *source) { + emit_helper(); + current->opcode = E_ASSIGN; + current->result = target; + current->operand1 = source; } -void emit_conditional_jump(Op condition, int label, ...){ - // when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *). - // when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *) - emit_helper(); - va_list argptr; - va_start(argptr, label); - current->opcode = condition; - current->label = label; - TNodeOrConst * n1; - TNodeOrConst * n2; - switch (condition) { - case E_IF_X_TRUE: case E_IF_X_FALSE: - n1 = va_arg(argptr, TNodeOrConst *); - current->operand1 = n1; - break; - case E_LESS_THAN: case E_EQUAL_TO: - n1 = va_arg(argptr, TNodeOrConst *); - n2 = va_arg(argptr, TNodeOrConst *); - current->operand1 = n1; - current->operand2 = n2; - break; - } - va_end(argptr); +char *get_string(TNodeOrConst *tc) { + char *s; + switch (tc->d) { + case NODE: + return getName(tc->tnc_union->node); + case ADDRESS: + return strdup("null"); + case STRING: + return tc->tnc_union->string; + case INTEGER: + s = calloc(10, sizeof(char)); + sprintf(s, "%d", tc->tnc_union->integer); + return s; + case CHARACTER: + s = calloc(2, sizeof(char)); + sprintf(s, "%c", tc->tnc_union->character); + return s; + case BOOLEAN: + if (tc->tnc_union->Boolean) { + return strdup("true"); + } + return strdup("false"); + } } -void emit_function_start(TableNode * name){ - emit_helper(); - current->opcode = E_FUNC_START; - current->result = name; +void emit_label(int label) { + emit_helper(); + current->opcode = E_LABEL; + current->label = label; } -void emit_parameter(TNodeOrConst * param){ - emit_helper(); - current->opcode = E_PARAM; - current->operand1 = param; +void emit_jump(int label) { + emit_helper(); + current->opcode = E_GOTO; + current->label = label; +} + +void emit_conditional_jump(Op condition, int label, ...) { + // when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *). + // when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *) + emit_helper(); + va_list argptr; + va_start(argptr, label); + current->opcode = condition; + current->label = label; + TNodeOrConst *n1; + TNodeOrConst *n2; + switch (condition) { + case E_IF_X_TRUE: + case E_IF_X_FALSE: + n1 = va_arg(argptr, TNodeOrConst *); + current->operand1 = n1; + break; + case E_LESS_THAN: + case E_EQUAL_TO: + n1 = va_arg(argptr, TNodeOrConst *); + n2 = va_arg(argptr, TNodeOrConst *); + current->operand1 = n1; + current->operand2 = n2; + break; + } + va_end(argptr); +} + +void emit_function_start(TableNode *name) { + emit_helper(); + current->opcode = E_FUNC_START; + current->result = name; +} + +void emit_parameter(TNodeOrConst *param) { + emit_helper(); + current->opcode = E_PARAM; + current->operand1 = param; } void emit_function_call( - TableNode * result, - int param_count, - TNodeOrConst * name - ){ - emit_helper(); - current->opcode = E_CALL; - current->operand1 = name; - current->operand2 = tn_or_const(INTEGER, ¶m_count); - current->result = result; + TableNode *result, + int param_count, + TNodeOrConst *name) { + emit_helper(); + current->opcode = E_CALL; + current->operand1 = name; + current->operand2 = tn_or_const(INTEGER, ¶m_count); + current->result = result; } -void emit_return(TNodeOrConst * value){ - emit_helper(); - current->opcode = E_RETURN; - current->operand1 = value; +void emit_return(TNodeOrConst *value) { + emit_helper(); + current->opcode = E_RETURN; + current->operand1 = value; } -void emit_reserve(TableNode * result, TNodeOrConst * size){ - // this needs to change - // we need to take a int - emit_parameter(size); - emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); +void emit_reserve(TableNode *result, TNodeOrConst *size) { + // this needs to change + // we need to take a int + emit_parameter(size); + emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); } -void emit_release(TableNode * pointer){ - emit_parameter(tn_or_const(NODE, pointer)); - emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release"))); +void emit_release(TableNode *pointer) { + emit_parameter(tn_or_const(NODE, pointer)); + emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release"))); } -void emit_deref_right(TableNode * x, TNodeOrConst * y){ - emit_helper(); - current->opcode = E_DEREF_RIGHT; - current->result = x; - current->operand1 = y; +void emit_deref_right(TableNode *x, TNodeOrConst *y) { + emit_helper(); + current->opcode = E_DEREF_RIGHT; + current->result = x; + current->operand1 = y; } -void emit_deref_left(TableNode * x, TNodeOrConst * y){ - emit_helper(); - current->opcode = E_DEREF_LEFT; - current->result = x; - current->operand1 = y; +void emit_deref_left(TableNode *x, TNodeOrConst *y) { + emit_helper(); + current->opcode = E_DEREF_LEFT; + current->result = x; + current->operand1 = y; } -void emit_address_of(TableNode * x, TNodeOrConst * y){ - emit_helper(); - current->opcode = E_ADDRESS_OF; - current->result = x; - current->operand1 = y; +void emit_address_of(TableNode *x, TNodeOrConst *y) { + emit_helper(); + current->opcode = E_ADDRESS_OF; + current->result = x; + current->operand1 = y; } -void emit_field_access(char* result, char* record, char* field){ - emit_helper(); +void emit_field_access(char *result, char *record, char *field) { + emit_helper(); } -void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index){ - emit_helper(); - current->opcode = op; - current->result = result; - current->operand1 = array; - current->operand2 = index; - // TODO: Still don't know what to do with the dimentions +void emit_array_access(Op op, TableNode *result, TNodeOrConst *array, TNodeOrConst *index) { + emit_helper(); + current->opcode = op; + current->result = result; + current->operand1 = array; + current->operand2 = index; + // TODO: Still don't know what to do with the dimentions } -void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr){ - /* +void emit_bounds_check(TNodeOrConst *index, TNodeOrConst *arr) { + /* {[string: 5] . . @@ -383,7 +381,7 @@ void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr){ if t_0 < s._1 GOTO access array GOTO ERROR */ - /* We need a label ERROR to jump to + /* We need a label ERROR to jump to emit_conditional_jump(E_LESS_THAN, ); emit_conditional_jump(E_LESS_THAN, ); emit_jump(); @@ -392,245 +390,218 @@ void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr){ // * Implement temp variable generator function that produces unique names (t1, t2, etc.) -int label_gen(){ - label_count++; - return label_count; +int label_gen() { + label_count++; + return label_count; } -void emit_as_file(FILE * out_file, Instruction * i){ - if (out_file == NULL){ - fprintf(stderr, "Error: output file is NULL\n"); - return; - } +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; - } - switch(i->opcode){ - case E_FUNC_START: - fprintf(out_file, - "%4.d: func : %s\n", - i->index, - getName(i->result) - ); - break; - case E_LABEL: - fprintf(out_file, - "%4.d: Label : %d\n", - i->index, - i->label - ); - break; - case E_ADD: - fprintf(out_file, - "%4.d: %s = %s + %s\n", - i->index, - getName(i->result), - get_string(i->operand1), - get_string(i->operand2) - ); - break; - case E_SUB: - fprintf(out_file, - "%4.d: %s = %s - %s\n", - i->index, - getName(i->result), - get_string(i->operand1), - get_string(i->operand2) - ); - break; - case E_MUL: - fprintf(out_file, - "%4.d: %s = %s * %s\n", - i->index, - getName(i->result), - get_string(i->operand1), - get_string(i->operand2) - ); - break; - case E_DIV: - fprintf(out_file, - "%4.d: %s = %s / %s\n", - i->index, - getName(i->result), - get_string(i->operand1), - get_string(i->operand2) - ); - break; - case E_MOD: - fprintf(out_file, - "%4.d: %s = %s %% %s\n", - i->index, - getName(i->result), - get_string(i->operand1), - get_string(i->operand2) - ); - break; - case E_OR: - fprintf(out_file, - "%4.d: %s = %s | %s\n", - i->index, - getName(i->result), - get_string(i->operand1), - get_string(i->operand2) - ); - break; - case E_AND: - fprintf(out_file, - "%4.d: %s = %s & %s\n", - i->index, - getName(i->result), - get_string(i->operand1), - get_string(i->operand2) - ); - break; - case E_NEG: - fprintf(out_file, - "%4.d: %s = -%s\n", - i->index, - getName(i->result), - get_string(i->operand1) - ); - break; - case E_NOT: - fprintf(out_file, - "%4.d: %s = !%s\n", - i->index, - getName(i->result), - get_string(i->operand1) - ); - break; - case E_ASSIGN: - fprintf(out_file, - "%4.d: %s = %s\n", - i->index, - getName(i->result), - get_string(i->operand1) - ); - break; - case E_GOTO: - fprintf(out_file, - "%4.d: GOTO : %d\n", - i->index, - i->label - ); - break; - case E_IF_X_TRUE: - fprintf(out_file, - "%4.d: if %s True GOTO %d\n", - i->index, - get_string(i->operand1), - i->label - ); - break; - case E_IF_X_FALSE: - fprintf(out_file, - "%4.d: if %s False GOTO %d\n", - i->index, - get_string(i->operand1), - i->label - ); - break; - case E_LESS_THAN: - // this feels wrong I need to TODO: this - fprintf(out_file, - "%4.d: %s = %s < %s\n", - i->index, - getName(i->result), - get_string(i->operand1), - get_string(i->operand2) - ); - break; - case E_EQUAL_TO: - // this feels wrong I need to TODO: this - fprintf(out_file, - "%4.d: %s = %s == %s\n", - i->index, - getName(i->result), - get_string(i->operand1), - get_string(i->operand2) - ); - break; - case E_CALL: - fprintf(out_file, - "%4.d: call : %s %s\n", - i->index, - get_string(i->operand1), - get_string(i->operand2) - ); - break; - case E_PARAM: - fprintf(out_file, - "%4.d: param %s \n", - i->index, - get_string(i->operand1) - ); - break; - case E_RETURN: - fprintf(out_file, - "%4.d: return : %s\n", - i->index, - get_string(i->operand1) - ); - break; - case E_INDEX_COPY_RIGHT: - fprintf(out_file, - "%4.d: %s = %s[ %s ]\n", - i->index, - getName(i->result), - get_string(i->operand1), - get_string(i->operand2) - ); - break; - case E_INDEX_COPY_LEFT: - fprintf(out_file, - "%4.d: %s[ %s ] = %s\n", - i->index, - getName(i->result), - get_string(i->operand2), - get_string(i->operand1)); - break; - case E_ADDRESS_OF: - fprintf(out_file, - "%4.d: %s = &%s\n", - i->index, - getName(i->result), - get_string(i->operand1) - ); - break; + if (i == NULL) { + return; + } + switch (i->opcode) { + case E_FUNC_START: + fprintf(out_file, + "%4.d: func : %s\n", + i->index, + getName(i->result)); + break; + case E_LABEL: + fprintf(out_file, + "%4.d: Label : %d\n", + i->index, + i->label); + break; + case E_ADD: + fprintf(out_file, + "%4.d: %s = %s + %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_SUB: + fprintf(out_file, + "%4.d: %s = %s - %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_MUL: + fprintf(out_file, + "%4.d: %s = %s * %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_DIV: + fprintf(out_file, + "%4.d: %s = %s / %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_MOD: + fprintf(out_file, + "%4.d: %s = %s %% %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_OR: + fprintf(out_file, + "%4.d: %s = %s | %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_AND: + fprintf(out_file, + "%4.d: %s = %s & %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_NEG: + fprintf(out_file, + "%4.d: %s = -%s\n", + i->index, + getName(i->result), + get_string(i->operand1)); + break; + case E_NOT: + fprintf(out_file, + "%4.d: %s = !%s\n", + i->index, + getName(i->result), + get_string(i->operand1)); + break; + case E_ASSIGN: + fprintf(out_file, + "%4.d: %s = %s\n", + i->index, + getName(i->result), + get_string(i->operand1)); + break; + case E_GOTO: + fprintf(out_file, + "%4.d: GOTO : %d\n", + i->index, + i->label); + break; + case E_IF_X_TRUE: + fprintf(out_file, + "%4.d: if %s True GOTO %d\n", + i->index, + get_string(i->operand1), + i->label); + break; + case E_IF_X_FALSE: + fprintf(out_file, + "%4.d: if %s False GOTO %d\n", + i->index, + get_string(i->operand1), + i->label); + break; + case E_LESS_THAN: + // this feels wrong I need to TODO: this + fprintf(out_file, + "%4.d: %s = %s < %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_EQUAL_TO: + // this feels wrong I need to TODO: this + fprintf(out_file, + "%4.d: %s = %s == %s\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_CALL: + fprintf(out_file, + "%4.d: call : %s %s\n", + i->index, + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_PARAM: + fprintf(out_file, + "%4.d: param %s \n", + i->index, + get_string(i->operand1)); + break; + case E_RETURN: + fprintf(out_file, + "%4.d: return : %s\n", + i->index, + get_string(i->operand1)); + break; + case E_INDEX_COPY_RIGHT: + fprintf(out_file, + "%4.d: %s = %s[ %s ]\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_INDEX_COPY_LEFT: + fprintf(out_file, + "%4.d: %s[ %s ] = %s\n", + i->index, + getName(i->result), + get_string(i->operand2), + get_string(i->operand1)); + break; + case E_ADDRESS_OF: + fprintf(out_file, + "%4.d: %s = &%s\n", + i->index, + getName(i->result), + get_string(i->operand1)); + break; + case E_DEREF_RIGHT: + fprintf(out_file, + "%4.d: %s = *%s\n", + i->index, + getName(i->result), + get_string(i->operand1)); + case E_DEREF_LEFT: + fprintf(out_file, + "%4.d: *%s = %s\n", + i->index, + getName(i->result), + get_string(i->operand1)); + } - case E_DEREF_RIGHT: - fprintf(out_file, - "%4.d: %s = *%s\n", - i->index, - getName(i->result), - get_string(i->operand1) - ); - case E_DEREF_LEFT: - fprintf(out_file, - "%4.d: *%s = %s\n", - i->index, - getName(i->result), - get_string(i->operand1) - ); - } - - emit_as_file(out_file, i->next); + emit_as_file(out_file, i->next); } +TableNode *getTN(TNodeOrConst *tnc) { + if (tnc->d == NODE) { + return tnc->tnc_union->node; + } + return NULL; +} - -TableNode* getTN(TNodeOrConst* tnc) { - if (tnc->d == NODE) { - return tnc->tnc_union->node; - } - return NULL; - } - - int getConst(TNodeOrConst* tnc) { - if (tnc->d == INTEGER) { - return tnc->tnc_union->integer; - } - return -1; - } +int getConst(TNodeOrConst *tnc) { + if (tnc->d == INTEGER) { + return tnc->tnc_union->integer; + } + return -1; +} diff --git a/src/intermediate_code.h b/src/intermediate_code.h index f362874..1e60a91 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -16,20 +16,20 @@ typedef struct Stack Stack; typedef struct __Node __Node; typedef struct __Node { - void * v; - __Node * next; + void *v; + __Node *next; } __Node; typedef struct Stack { - __Node * n; - int w; - int size; + __Node *n; + int w; + int size; } Stack; -Stack * S_Init(); +Stack *S_Init(); void S_Free(Stack *s); -void S_Push(Stack * s, void *v, int i); -void * S_Pop(Stack *s); -void * S_Peek(Stack *s); +void S_Push(Stack *s, void *v, int i); +void *S_Pop(Stack *s); +void *S_Peek(Stack *s); bool S_IsEmpty(Stack *s); int S_Size(Stack *s); void S_Merge(Stack *list); @@ -39,137 +39,130 @@ typedef union TNConstUnion TNConstUnion; typedef struct Instruction Instruction; typedef struct TNodeOrConst TNodeOrConst; - // these are from page 364 -typedef enum { // these are from page 364 - E_LABEL = 10000, // this is not in the book - E_FUNC_START, - E_ADD, // 1 from the list - E_SUB, // 1 - E_MUL, // 1 - E_DIV, // 1 - E_MOD, // 1 TODO: Please change to REM - E_OR, // 1 - E_AND, // 1 - E_NEG, // 2 - E_NOT, // 2 - E_ASSIGN, // 3 - E_GOTO, // 4 - E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got - E_IF_X_TRUE, // 5 - E_IF_X_FALSE, // 5 - E_LESS_THAN, // 6 rule 1 + 5 - E_EQUAL_TO, // 6 rule 1 + 5 - E_CALL, // 7 - E_PARAM, // 7 - E_RETURN, // 7 - E_INDEX_COPY_RIGHT, // 8 this is x = y[i] - E_INDEX_COPY_LEFT, // 8 x[i] = y - E_ADDRESS_OF, // 9 x = &y - E_DEREF_RIGHT, // 9 x = *y - E_DEREF_LEFT // 9 x* = y +typedef enum { // these are from page 364 + E_LABEL = 10000, // this is not in the book + E_FUNC_START, + E_ADD, // 1 from the list + E_SUB, // 1 + E_MUL, // 1 + E_DIV, // 1 + E_MOD, // 1 TODO: Please change to REM + E_OR, // 1 + E_AND, // 1 + E_NEG, // 2 + E_NOT, // 2 + E_ASSIGN, // 3 + E_GOTO, // 4 + E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got + E_IF_X_TRUE, // 5 + E_IF_X_FALSE, // 5 + E_LESS_THAN, // 6 rule 1 + 5 + E_EQUAL_TO, // 6 rule 1 + 5 + E_CALL, // 7 + E_PARAM, // 7 + E_RETURN, // 7 + E_INDEX_COPY_RIGHT, // 8 this is x = y[i] + E_INDEX_COPY_LEFT, // 8 x[i] = y + E_ADDRESS_OF, // 9 x = &y + E_DEREF_RIGHT, // 9 x = *y + E_DEREF_LEFT // 9 x* = y } Op; typedef enum { - NODE = 11000, // TableNode - INTEGER, // int - STRING, // char * - CHARACTER, // char - ADDRESS, // void * - BOOLEAN // bool + NODE = 11000, // TableNode + INTEGER, // int + STRING, // char * + CHARACTER, // char + ADDRESS, // void * + BOOLEAN // bool } Discriminant; typedef union TNConstUnion { - TableNode * node; - int integer; - char * string; - char character; - void * address; - bool Boolean; + TableNode *node; + int integer; + char *string; + char character; + void *address; + bool Boolean; } TNConstUnion; typedef struct TNodeOrConst { - Discriminant d; - TNConstUnion * tnc_union; + Discriminant d; + TNConstUnion *tnc_union; } TNodeOrConst; typedef struct Instruction { - Op opcode; - TableNode * result; - TNodeOrConst * operand1; - TNodeOrConst * operand2; - int label; - int index; + Op opcode; + TableNode *result; + TNodeOrConst *operand1; + TNodeOrConst *operand2; + int label; + int index; - Instruction * prev; - Instruction * next; + Instruction *prev; + Instruction *next; } Instruction; - // NOTE We are not using this We are using the Stack api typedef struct TFList { - Instruction * i; - TFList * next; + Instruction *i; + TFList *next; } TFList; // TFList * make_list(Instruction * i); - // - makelist(i) function to create instruction lists +// - makelist(i) function to create instruction lists // void merge(TFList * l1, TFList * l2); - // - merge(p1,p2) function to concatenate lists +// - merge(p1,p2) function to concatenate lists // void backpatch(TFList * l, int label); - // - backpatch(p,i) function to fill in jump targets +// - backpatch(p,i) function to fill in jump targets // void bp_temp(int n); - -extern Instruction * begin; -extern Instruction * current; +extern Instruction *begin; +extern Instruction *current; extern int label_count; extern bool code_gen; -extern FILE * ir_flag; +extern FILE *ir_flag; - -TNodeOrConst * tn_or_const(Discriminant , void * ); -void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2); -void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg); -void emit_assignment(TableNode * target, TNodeOrConst * source); -void emit_as_file(FILE * out_file, Instruction * instr_arr); +TNodeOrConst *tn_or_const(Discriminant, void *); +void emit_binary_op(Op op, TableNode *result, TNodeOrConst *arg1, TNodeOrConst *arg2); +void emit_unary_op(Op op, TableNode *result, TNodeOrConst *arg); +void emit_assignment(TableNode *target, TNodeOrConst *source); +void emit_as_file(FILE *out_file, Instruction *instr_arr); void emit_label(int label); void emit_jump(int label); void emit_conditional_jump(Op condition, int label, ...); -void emit_function_start(TableNode* name); -void emit_parameter(TNodeOrConst * param); -void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name); -void emit_return(TNodeOrConst * value); -void emit_reserve(TableNode * result, TNodeOrConst * size); -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_function_start(TableNode *name); +void emit_parameter(TNodeOrConst *param); +void emit_function_call(TableNode *result, int param_count, TNodeOrConst *name); +void emit_return(TNodeOrConst *value); +void emit_reserve(TableNode *result, TNodeOrConst *size); +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); +void emit_push_all(Stack *s); +int getLabel(Instruction *i); +TableNode *getTN(TNodeOrConst *tnc); +int getConst(TNodeOrConst *tnc); -int getLabel(Instruction * i); -TableNode* getTN(TNodeOrConst* tnc); -int getConst(TNodeOrConst* tnc); - - - -TNodeOrConst * getOperand1(Instruction * i); -TNodeOrConst * getOperand2(Instruction * i); -TableNode * getResult(Instruction * i); -Op getOp(Instruction * i); -int getLabel(Instruction * i); -int get_index(Instruction * i); -void set_label(Instruction * i, int label); -bool isConst(TNodeOrConst * tnc); +TNodeOrConst *getOperand1(Instruction *i); +TNodeOrConst *getOperand2(Instruction *i); +TableNode *getResult(Instruction *i); +Op getOp(Instruction *i); +int getLabel(Instruction *i); +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); void emit_backpatch(Stack *s, int l); extern int offset; extern int currentsp; -extern CGNode* cgList; +extern CGNode *cgList; diff --git a/src/lexicalStructure.h b/src/lexicalStructure.h index bdd0db7..d9f23d8 100644 --- a/src/lexicalStructure.h +++ b/src/lexicalStructure.h @@ -25,10 +25,11 @@ int line_number = 1; int column_number = 1; int yycolumn = 1; -#define YY_USER_ACTION { \ +#define YY_USER_ACTION \ + { \ yylloc.first_line = yylineno; \ yylloc.last_line = yylineno; \ yylloc.first_column = yycolumn; \ yylloc.last_column = yycolumn + yyleng - 1; \ yycolumn += yyleng; \ -} + } diff --git a/src/runner.c b/src/runner.c index ab2754a..4aa6a84 100644 --- a/src/runner.c +++ b/src/runner.c @@ -103,7 +103,6 @@ int run(FILE *alpha) { int token; top = cur = init(CreateScope(NULL, 1, 1)); - // If file is not found if (alpha == NULL) { fprintf(stderr, "INPUT FILE NOT FOUND\n"); diff --git a/src/runner.h b/src/runner.h index c423a36..37c7bad 100644 --- a/src/runner.h +++ b/src/runner.h @@ -59,8 +59,8 @@ bool DEBUG = false; int no_flag = 0; int arg; bool contains_errors = false; -char * cg_name; -char * ir_name; +char *cg_name; +char *ir_name; TableNode *funprime; TableNode *arrayprim; @@ -73,9 +73,9 @@ TableNode *recprime; TableNode *funtypeprime; TableNode *undefined; extern Instruction *begin; -extern Stack* stack; -extern Stack* TrueList; -extern Stack* FalseList; +extern Stack *stack; +extern Stack *TrueList; +extern Stack *FalseList; int main(int argc, char *argv[]); int check_flag(char *arg, char *alpha); @@ -112,6 +112,6 @@ typedef struct CodeLine { CodeLine *code_head; char *file_read_line(FILE *fp); -void insert_code_line(char * error_message, int line_number); +void insert_code_line(char *error_message, int line_number); void append_code_line(CodeLine *code_line); void print_code_lines(); diff --git a/src/symbol_table.c b/src/symbol_table.c index 000fbc1..3809128 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -116,15 +116,15 @@ int getPrimSize(TableNode *definition) { "Invalid."); return -1; } - if(getAdInfoType(definition) == TYPE_ARRAY_TYPE){ + if (getAdInfoType(definition) == TYPE_ARRAY_TYPE) { //special case to return size for reference to an array return 8; } - if(getAdInfoType(definition) == TYPE_FUNCTION_TYPE){ + if (getAdInfoType(definition) == TYPE_FUNCTION_TYPE) { //special case to return size for reference to a function return 8; } - if(getAdInfoType(definition) == TYPE_RECORD_TYPE){ + if (getAdInfoType(definition) == TYPE_RECORD_TYPE) { //special case to return size for reference to a record return getRecTotal(definition); } @@ -469,7 +469,7 @@ int getRecSize(SymbolTable *tn) { // multiple inputs Below function also has the line number where the function is // first defined AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular, SymbolTable *scope) { - AdInfo *info = (AdInfo *)calloc(1,sizeof(AdInfo)); + AdInfo *info = (AdInfo *)calloc(1, sizeof(AdInfo)); info->FunDecAdInfo = (function_declaration_info *)malloc( sizeof(function_declaration_info)); info->FunDecAdInfo->startlinenumber = line; @@ -561,12 +561,12 @@ SymbolTable *getFunScope(TableNode *definition) { "node has NULL additionalinfo. Invalid."); return NULL; } - if(definition->additionalinfo->FunDecAdInfo == NULL) { + if (definition->additionalinfo->FunDecAdInfo == NULL) { printdebug( "node has NULL additionalinfo. Invalid."); return NULL; } - if(definition->additionalinfo->FunDecAdInfo->scope == NULL) { + if (definition->additionalinfo->FunDecAdInfo->scope == NULL) { printdebug( "node has no scope initialized."); return NULL; @@ -587,17 +587,17 @@ TableNode *setFunScope(TableNode *tn, SymbolTable *scope) { "invalid"); return undefined; } - if(tn->additionalinfo == NULL) { + if (tn->additionalinfo == NULL) { printdebug( "node has NULL additionalinfo. Invalid."); return undefined; } - if(tn->additionalinfo->FunDecAdInfo == NULL) { + if (tn->additionalinfo->FunDecAdInfo == NULL) { printdebug( "node has NULL additionalinfo. Invalid."); return undefined; } - if(scope == NULL) { + if (scope == NULL) { printdebug( "passed in an empty scope."); return undefined; @@ -705,7 +705,7 @@ TableNode *getReturn(TableNode *definition) { "node has NULL additionalinfo. Invalid."); return undefined; } - printdebug("function:%s with return type %s\n",getName(definition),getName(definition->additionalinfo->FunTypeAdInfo->returntype)); + printdebug("function:%s with return type %s\n", getName(definition), getName(definition->additionalinfo->FunTypeAdInfo->returntype)); return definition->additionalinfo->FunTypeAdInfo->returntype; } @@ -862,10 +862,10 @@ SymbolTable *init(SymbolTable *start) { chara->additionalinfo = CreatePrimitiveInfo(SIZE_CHAR); stri->additionalinfo = CreateArrayInfo(1, chara); boo->additionalinfo = CreatePrimitiveInfo(SIZE_BOOL); - reserve->additionalinfo = CreateFunctionDeclarationInfo(0, false,NULL); + reserve->additionalinfo = CreateFunctionDeclarationInfo(0, false, NULL); reservetype->additionalinfo = CreateFunctionTypeInfo(integ, addr); releasetype->additionalinfo = CreateFunctionTypeInfo(addr, integ); - release->additionalinfo = CreateFunctionDeclarationInfo(0, false,NULL); + release->additionalinfo = CreateFunctionDeclarationInfo(0, false, NULL); integ->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for integ addr->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for addr @@ -1031,7 +1031,7 @@ TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, return NULL; } */ - if((id != NULL) && table_lookup(cur,id)!=undefined){ + if ((id != NULL) && table_lookup(cur, id) != undefined) { printdebug("This name is already defined in the current scope"); //throw_error(ERROR_TYPE, "Already defined."); return undefined; @@ -1062,7 +1062,7 @@ TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, printdebug("[CreateEntry] Adding %s to the symbol table", id); return newEntry; } else { - TableNode*oldEntry = table->entries; + TableNode *oldEntry = table->entries; while (oldEntry->next != NULL) { oldEntry = oldEntry->next; } @@ -1309,7 +1309,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } for (; entry != NULL; entry = getNextEntry(entry)) { - if((getName(entry)[0] == '$' || getName(entry)[0] == '&') && ir_flag == NULL){ + if ((getName(entry)[0] == '$' || getName(entry)[0] == '&') && ir_flag == NULL) { continue; } if (getAdInfoType(entry) == TYPE_ARRAY_TYPE) { @@ -1391,11 +1391,11 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (getAdInfoType(entry) == TYPE_FUNCTION_DECLARATION) { char *functiontype = (char *)malloc(100); sprintf(functiontype, " %s", getName(getTypeEntry(entry))); - char* functionScope = (char *)malloc(100); - if(getLine(getFunScope(entry)) < 1){ + char *functionScope = (char *)malloc(100); + if (getLine(getFunScope(entry)) < 1) { sprintf(functionScope, " Function not defined before runtime"); - }else{ - sprintf(functionScope, " Function Definition that starts at line %d",getLine(getFunScope(entry))); + } else { + sprintf(functionScope, " Function Definition that starts at line %d", getLine(getFunScope(entry))); } if (parentScopeNum == 0) { st_fprint(file_ptr, getName(entry), currentScopeNum, -100, functiontype, functionScope); @@ -1545,7 +1545,13 @@ SymbolTable *getParent(SymbolTable *st) { ListOfTable *getChildren(SymbolTable *st) { return st->Children_Scope; } SymbolTable *getFirstChild(ListOfTable *lt) { return lt->table; } ListOfTable *getRestOfChildren(ListOfTable *lt) { return lt->next; } -TableNode *getFirstEntry(SymbolTable *st) { return st->entries; } +TableNode *getFirstEntry(SymbolTable *st) { + if (st == NULL || st->entries == NULL) { + printdebug("passed a NULL symbol table to getFirstEntry"); + return undefined; + } + return st->entries; +} // Segfaults when passed an invalid table node! TableNode *getNextEntry(TableNode *tn) { diff --git a/src/symbol_table.h b/src/symbol_table.h index f838314..2a8abb5 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -48,7 +48,7 @@ typedef struct { typedef struct { int startlinenumber; bool regularoras; - SymbolTable* scope; + SymbolTable *scope; } function_declaration_info; typedef struct { @@ -122,7 +122,7 @@ int getRecLength(TableNode *definition); SymbolTable *getRecList(TableNode *definition); TableNode *setRecSize(TableNode *tn, int n); int getRecSize(SymbolTable *tn); -AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular,SymbolTable *scope); +AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular, SymbolTable *scope); TableNode *setFunScope(TableNode *tn, SymbolTable *scope); SymbolTable *getFunScope(TableNode *definition); int getStartLine(TableNode *definition); diff --git a/tests/programs/test/fib.alpha b/tests/programs/test/fib.alpha new file mode 100644 index 0000000..2f33e06 --- /dev/null +++ b/tests/programs/test/fib.alpha @@ -0,0 +1 @@ +(* TODO: Prints out fib sequence. *) \ No newline at end of file diff --git a/tests/programs/test/ll.alpha b/tests/programs/test/ll.alpha new file mode 100644 index 0000000..4178a08 --- /dev/null +++ b/tests/programs/test/ll.alpha @@ -0,0 +1 @@ +(* TODO: creates a linked list and prints out the chain. *) \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_add.alpha b/tests/sprint4/test/sp4_cg_add.alpha index e3da55e..0d5fb5a 100644 --- a/tests/sprint4/test/sp4_cg_add.alpha +++ b/tests/sprint4/test/sp4_cg_add.alpha @@ -1,35 +1,14 @@ (* TEST: [-asc -tc -cg -ir] *) -type string: 1 -> character -type BooleanXBoolean: [Boolean: x; Boolean: y] -type characterXcharacter: [character: x; character: y] -type integerXinteger: [integer: x; integer: y] - -type Boolean2Boolean: Boolean -> Boolean -type integer2integer: integer -> integer -type character2integer: character -> integer -type Boolean2integer0: Boolean -> integer -type string2integer: string -> integer -type integerXinteger2integer: integerXinteger -> integer -type integerXinteger2Boolean: integerXinteger -> Boolean -type characterXcharacter2Boolean: characterXcharacter -> Boolean -type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean -type integer2address: integer -> address -type address2integer: address -> integer - -external function printInteger: integer2integer -external function printCharacter: character2integer -external function printBoolean: Boolean2integer - -function entry: string2integer +#include "std.alpha" entry (arg) := { [integer:x; integer:y; integer: result] + y := 1; x := 3; y := x + y; result := printInteger(y); - return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_and.alpha b/tests/sprint4/test/sp4_cg_and.alpha index 97adf47..5d5590b 100644 --- a/tests/sprint4/test/sp4_cg_and.alpha +++ b/tests/sprint4/test/sp4_cg_and.alpha @@ -1,11 +1,13 @@ (* TEST: [-asc -tc -cg -ir] *) -type main: integer -> integer -function test: main -test (a) := { - [Boolean:b; Boolean: c; Boolean: d] - c := true; - d := false; - d := c & d; - return 1; +#include "std.alpha" + +entry (arg) := { + [Boolean:b; Boolean: c; Boolean: d] + + z := true; + d := false; + d := c & d; + + return 1; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_demo.alpha b/tests/sprint4/test/sp4_cg_demo.alpha deleted file mode 100644 index e74c5ad..0000000 --- a/tests/sprint4/test/sp4_cg_demo.alpha +++ /dev/null @@ -1,8 +0,0 @@ -type main: string -> integer -function entry: main - -entry(arg) := { - [integer:x] - x := 3 + 2 * 8; - return x; - } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_demo.cg b/tests/sprint4/test/sp4_cg_demo.cg deleted file mode 100644 index 32d366c..0000000 --- a/tests/sprint4/test/sp4_cg_demo.cg +++ /dev/null @@ -1,9 +0,0 @@ -type main: string -> integer -function entry: main - -entry(arg) := { - [integer:x; Boolean b] - x := 3 + 2 * 8; - b := x < 1; - return 0; - } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_div.alpha b/tests/sprint4/test/sp4_cg_div.alpha index e6f9cbd..4e27b37 100644 --- a/tests/sprint4/test/sp4_cg_div.alpha +++ b/tests/sprint4/test/sp4_cg_div.alpha @@ -1,11 +1,13 @@ (* TEST: [-asc -tc -cg -ir] *) -type main: integer -> integer -function test: main -test (a) := { - [integer:x; integer:y] - y := 1; - x := 3; - y := x / y; - return y; +#include "std.alpha" + +entry (arg) := { + [integer:x; integer:y] + + y := 1; + x := 3; + y := x / y; + + return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_equal_to.alpha b/tests/sprint4/test/sp4_cg_equal_to.alpha index 23ecf91..d7011a0 100644 --- a/tests/sprint4/test/sp4_cg_equal_to.alpha +++ b/tests/sprint4/test/sp4_cg_equal_to.alpha @@ -1,11 +1,13 @@ (* TEST: [-asc -tc -cg -ir] *) -type main: integer -> integer -function test: main -test (a) := { - [Boolean: b; integer: x; integer: y] - x := 1; +#include "std.alpha" + +entry (arg) := { + [Boolean: b; integer: x; integer: y] + + x := 1; y := 2; b := x = y; - return 1; + + return 1; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_fib.alpha b/tests/sprint4/test/sp4_cg_fib.alpha deleted file mode 100644 index 64b1239..0000000 --- a/tests/sprint4/test/sp4_cg_fib.alpha +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/tests/sprint4/test/sp4_cg_less_than.alpha b/tests/sprint4/test/sp4_cg_less_than.alpha index 8b9cbc7..6b13385 100644 --- a/tests/sprint4/test/sp4_cg_less_than.alpha +++ b/tests/sprint4/test/sp4_cg_less_than.alpha @@ -1,11 +1,13 @@ (* TEST: [-asc -tc -cg -ir] *) -type main: integer -> integer -function test: main -test (a) := { - [Boolean: b; integer: x; integer: y] -character x := 1; +#include "std.alpha" + +entry (arg) := { + [Boolean: b; integer: x; integer: y] + + x := 1; y := 2; b := x < y; - return 1; + + return 1; } diff --git a/tests/sprint4/test/sp4_cg_mod.alpha b/tests/sprint4/test/sp4_cg_mod.alpha index ccf0b85..ad6530a 100644 --- a/tests/sprint4/test/sp4_cg_mod.alpha +++ b/tests/sprint4/test/sp4_cg_mod.alpha @@ -1,11 +1,13 @@ (* TEST: [-asc -tc -cg -ir] *) -type main: integer -> integer -function test: main -test (a) := { - [integer:x; integer:y] - y := 1; - x := 3; - y := x % y; - return y; +#include "std.alpha" + +entry (arg) := { + [integer:x; integer:y] + + y := 1; + x := 3; + y := x % y; + + return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_mult.alpha b/tests/sprint4/test/sp4_cg_mult.alpha index 630fa14..dfa8fce 100644 --- a/tests/sprint4/test/sp4_cg_mult.alpha +++ b/tests/sprint4/test/sp4_cg_mult.alpha @@ -1,11 +1,13 @@ (* TEST: [-asc -tc -cg -ir] *) -type main: integer -> integer -function test: main -test (a) := { - [integer:x; integer:y] - y := 1; - x := 3; - y := x * x; - return y; +#include "std.alpha" + +entry (arg) := { + [integer:x; integer:y] + + y := 1; + x := 3; + y := x * x; + + return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_neg.alpha b/tests/sprint4/test/sp4_cg_neg.alpha index 58683a4..4b7fda8 100644 --- a/tests/sprint4/test/sp4_cg_neg.alpha +++ b/tests/sprint4/test/sp4_cg_neg.alpha @@ -1,10 +1,12 @@ (* TEST: [-asc -tc -cg -ir] *) -type main: integer -> integer -function test: main -test (a) := { - [integer:x; integer:y] - x := 3; - y := -x; - return y; +#include "std.alpha" + +entry (arg) := { + [integer:x; integer:y] + + x := 3; + y := -x; + + return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_not.alpha b/tests/sprint4/test/sp4_cg_not.alpha index f7ad95c..803b3de 100644 --- a/tests/sprint4/test/sp4_cg_not.alpha +++ b/tests/sprint4/test/sp4_cg_not.alpha @@ -1,10 +1,12 @@ (* TEST: [-asc -tc -cg -ir] *) -type main: integer -> integer -function test: main -test (a) := { - [Boolean: c; Boolean: d] - c := true; - d := !c; - return 1; +#include "std.alpha" + +entry (arg) := { + [Boolean: c; Boolean: d] + + c := true; + d := !c; + + return 1; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_or.alpha b/tests/sprint4/test/sp4_cg_or.alpha index 0ce14f3..6788796 100644 --- a/tests/sprint4/test/sp4_cg_or.alpha +++ b/tests/sprint4/test/sp4_cg_or.alpha @@ -1,11 +1,13 @@ (* TEST: [-asc -tc -cg -ir] *) -type main: integer -> integer -function test: main -test (a) := { - [Boolean:b; Boolean: c; Boolean: d] - c := true; - d := false; - d := c | d; - return 1; +#include "std.alpha" + +entry (arg) := { + [Boolean:b; Boolean: c; Boolean: d] + + c := true; + d := false; + d := c | d; + return 1; + } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_sub.alpha b/tests/sprint4/test/sp4_cg_sub.alpha index abf6608..9ab6b68 100644 --- a/tests/sprint4/test/sp4_cg_sub.alpha +++ b/tests/sprint4/test/sp4_cg_sub.alpha @@ -1,11 +1,13 @@ (* TEST: [-asc -tc -cg -ir] *) -type main: integer -> integer -function test: main -test (a) := { - [integer:x; integer:y] - y := 1; - x := 3; - y := x - y; - return y; +#include "std.alpha" + +entry (arg) := { + [integer:x; integer:y] + + y := 1; + x := 3; + y := x - y; + + return y; } \ No newline at end of file From 9c25e1e667951624ce1e0833556f73224eab7e28 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 5 May 2025 00:06:27 -0400 Subject: [PATCH 061/109] =?UTF-8?q?=F0=9F=94=A5=F0=9F=94=A5=F0=9F=94=A5=20?= =?UTF-8?q?all=20cg=20tests=20working!!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/sprint4/test/sp4_cg_and.alpha | 5 +++-- tests/sprint4/test/sp4_cg_div.alpha | 9 +++++---- tests/sprint4/test/sp4_cg_equal_to.alpha | 3 ++- tests/sprint4/test/sp4_cg_less_than.alpha | 5 +++-- tests/sprint4/test/sp4_cg_mod.alpha | 9 +++++---- tests/sprint4/test/sp4_cg_mult.alpha | 7 ++++--- tests/sprint4/test/sp4_cg_neg.alpha | 5 +++-- tests/sprint4/test/sp4_cg_not.alpha | 5 +++-- tests/sprint4/test/sp4_cg_or.alpha | 5 +++-- tests/sprint4/test/sp4_cg_sub.alpha | 3 ++- 10 files changed, 33 insertions(+), 23 deletions(-) diff --git a/tests/sprint4/test/sp4_cg_and.alpha b/tests/sprint4/test/sp4_cg_and.alpha index 5d5590b..a42409b 100644 --- a/tests/sprint4/test/sp4_cg_and.alpha +++ b/tests/sprint4/test/sp4_cg_and.alpha @@ -3,11 +3,12 @@ #include "std.alpha" entry (arg) := { - [Boolean:b; Boolean: c; Boolean: d] + [Boolean:b; Boolean: c; Boolean: d; integer: result] z := true; d := false; d := c & d; - + + result := printBoolean(d); return 1; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_div.alpha b/tests/sprint4/test/sp4_cg_div.alpha index 4e27b37..39d5a83 100644 --- a/tests/sprint4/test/sp4_cg_div.alpha +++ b/tests/sprint4/test/sp4_cg_div.alpha @@ -3,11 +3,12 @@ #include "std.alpha" entry (arg) := { - [integer:x; integer:y] + [integer:x; integer:y; integer: result] - y := 1; - x := 3; + x := 24; + y := 3; y := x / y; - + + result := printInteger(y); return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_equal_to.alpha b/tests/sprint4/test/sp4_cg_equal_to.alpha index d7011a0..a2823cc 100644 --- a/tests/sprint4/test/sp4_cg_equal_to.alpha +++ b/tests/sprint4/test/sp4_cg_equal_to.alpha @@ -3,11 +3,12 @@ #include "std.alpha" entry (arg) := { - [Boolean: b; integer: x; integer: y] + [Boolean: b; integer: x; integer: y; integer: result] x := 1; y := 2; b := x = y; + result := printBoolean(b); return 1; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_less_than.alpha b/tests/sprint4/test/sp4_cg_less_than.alpha index 6b13385..77867ab 100644 --- a/tests/sprint4/test/sp4_cg_less_than.alpha +++ b/tests/sprint4/test/sp4_cg_less_than.alpha @@ -3,11 +3,12 @@ #include "std.alpha" entry (arg) := { - [Boolean: b; integer: x; integer: y] + [Boolean: b; integer: x; integer: y; integer: result] x := 1; y := 2; b := x < y; - + + result := printBoolean(b); return 1; } diff --git a/tests/sprint4/test/sp4_cg_mod.alpha b/tests/sprint4/test/sp4_cg_mod.alpha index ad6530a..fbd40d5 100644 --- a/tests/sprint4/test/sp4_cg_mod.alpha +++ b/tests/sprint4/test/sp4_cg_mod.alpha @@ -3,11 +3,12 @@ #include "std.alpha" entry (arg) := { - [integer:x; integer:y] + [integer:x; integer:y; integer: result] - y := 1; - x := 3; - y := x % y; + x := 4; + y := 20; + y := y % x; + result := printInteger(y); return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_mult.alpha b/tests/sprint4/test/sp4_cg_mult.alpha index dfa8fce..28e7ab6 100644 --- a/tests/sprint4/test/sp4_cg_mult.alpha +++ b/tests/sprint4/test/sp4_cg_mult.alpha @@ -3,11 +3,12 @@ #include "std.alpha" entry (arg) := { - [integer:x; integer:y] + [integer:x; integer:y; integer: result] - y := 1; x := 3; - y := x * x; + y := 20; + y := x * y; + result := printInteger(y); return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_neg.alpha b/tests/sprint4/test/sp4_cg_neg.alpha index 4b7fda8..2ffe34a 100644 --- a/tests/sprint4/test/sp4_cg_neg.alpha +++ b/tests/sprint4/test/sp4_cg_neg.alpha @@ -3,10 +3,11 @@ #include "std.alpha" entry (arg) := { - [integer:x; integer:y] + [integer:x; integer:y; integer: result] x := 3; y := -x; - + + result := printInteger(y); return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_not.alpha b/tests/sprint4/test/sp4_cg_not.alpha index 803b3de..6811471 100644 --- a/tests/sprint4/test/sp4_cg_not.alpha +++ b/tests/sprint4/test/sp4_cg_not.alpha @@ -3,10 +3,11 @@ #include "std.alpha" entry (arg) := { - [Boolean: c; Boolean: d] + [Boolean: c; Boolean: d; integer: result] c := true; d := !c; - + + result := printBoolean(d); return 1; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_or.alpha b/tests/sprint4/test/sp4_cg_or.alpha index 6788796..61392c2 100644 --- a/tests/sprint4/test/sp4_cg_or.alpha +++ b/tests/sprint4/test/sp4_cg_or.alpha @@ -3,11 +3,12 @@ #include "std.alpha" entry (arg) := { - [Boolean:b; Boolean: c; Boolean: d] + [Boolean:b; Boolean: c; Boolean: d; integer: result] c := true; d := false; d := c | d; + + result := printBoolean(d); return 1; - } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_sub.alpha b/tests/sprint4/test/sp4_cg_sub.alpha index 9ab6b68..4b60e57 100644 --- a/tests/sprint4/test/sp4_cg_sub.alpha +++ b/tests/sprint4/test/sp4_cg_sub.alpha @@ -3,11 +3,12 @@ #include "std.alpha" entry (arg) := { - [integer:x; integer:y] + [integer:x; integer:y; integer: result] y := 1; x := 3; y := x - y; + result := printInteger(y); return y; } \ No newline at end of file From 6212deee5125a481eaffd382c0f1dac550d00f92 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 5 May 2025 00:51:06 -0400 Subject: [PATCH 062/109] =?UTF-8?q?=F0=9F=91=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/programs/test/helloworld.alpha | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/programs/test/helloworld.alpha diff --git a/tests/programs/test/helloworld.alpha b/tests/programs/test/helloworld.alpha new file mode 100644 index 0000000..109cae8 --- /dev/null +++ b/tests/programs/test/helloworld.alpha @@ -0,0 +1,11 @@ +#include "std.alpha" + +entry (arg) := { + [string: str; character: ch; integer: result] + + ch := 'h'; + str := "Hello World!"; + result := printCharacter(ch); + + return 0; +} \ No newline at end of file From 76f98b93ab9c1545210ce00ff9e6a6b402c316f8 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 5 May 2025 14:28:02 -0400 Subject: [PATCH 063/109] =?UTF-8?q?=F0=9F=92=8E=F0=9F=92=8E=F0=9F=92=8E?= =?UTF-8?q?=F0=9F=92=8E=F0=9F=92=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- genx.sh | 36 ++++++++++++++++++++++-------------- src/grammar.y | 10 +++++++--- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/genx.sh b/genx.sh index 8da7039..b902a82 100755 --- a/genx.sh +++ b/genx.sh @@ -76,31 +76,39 @@ appendStd() { mv "$temp_file" "$1" } +ass() { + gcc "$1" library/alpha_lib_reg.s library/alpha_driver.s -no-pie -o binaries/${2} + if [ $? -eq 0 ]; then + echo -e "${GREEN}[GenX] ${WHITE}Executable file: binaries/${2}" + echo -e "${GREEN}[GenX] ${WHITE}Done!" + else + echo -e "${RED}[GenX] ${YELLOW}Error generating executable file!${WHITE}" + exit 1 + fi +} + if [ $# -eq 1 ]; then if [ -f "$1" ]; then + filename=$(basename -- "$1") if [[ "$1" == *.alpha ]]; then + filename="${filename:0:${#filename}-6}" + s_name="out/${filename}.s" appendStd "$1" - ./alpha -cg "$1" + ./alpha -ir -tc -asc -cg -st "$1" backup_file="${1}.bak" if [ -f "$backup_file" ]; then mv "$backup_file" "$1" - echo -e "${GREEN}[GenX] ${WHITE}Reverted $1 to its original state." fi - filename=$(basename -- "$1") - filename="${filename:0:${#filename}-6}" - s_name="out/${filename}.s" echo -e "${GREEN}[GenX] ${WHITE}Generated .s file." - gcc ${s_name} library/alpha_lib_reg.s library/alpha_driver.s -no-pie -o binaries/${filename} - if [ $? -eq 0 ]; then - echo -e "${GREEN}[GenX] ${WHITE}Generated executable file." - echo -e "${GREEN}[GenX] ${WHITE}Executable file: binaries/${filename}" - echo -e "${GREEN}[GenX] ${WHITE}Done!" - else - echo -e "${RED}[GenX] ${YELLOW}Error generating executable file!${WHITE}" - exit 1 - fi + ass "$s_name" "$filename" + elif [[ "$1" == *.s ]]; then + filename="${filename:0:${#filename}-2}" + s_name="out/${filename}.s" + echo -e "${GREEN}[GenX] ${WHITE}File $1 is a .s file! (Skipping compiler)${WHITE}" + ass "$s_name" "$filename" + exit 1 else echo -e "${RED}[GenX] ${YELLOW}File $1 is not a .alpha file!${WHITE}" exit 1 diff --git a/src/grammar.y b/src/grammar.y index a70ee74..6fd864c 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -306,7 +306,9 @@ function_declaration: if(getAdInfoType(table_lookup(cur, $4))==TYPE_FUNCTION_TYPE){ //printf("%s\n",$2); //printf("%s\n",getName(table_lookup(cur, $4))); - CreateEntry(cur,TYPE_FUNCTION_DECLARATION, table_lookup(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false,NULL)); + if (CreateEntry(cur,TYPE_FUNCTION_DECLARATION, table_lookup(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false,NULL)) == undefined) { + throw_error(ERROR_TYPE, "Duplicate defination of function in function declaration"); + } } else{ throw_error(ERROR_TYPE, "Function declatation (%s) is not a valid function type", $2); @@ -318,7 +320,9 @@ 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,NULL)); + if (CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false,NULL)) == undefined) { + throw_error(ERROR_TYPE, "Duplicate defination of function in function declaration"); + } } else{ throw_error(ERROR_TYPE, "Function declatation (%s) is not a valid function type", $3); @@ -1579,7 +1583,7 @@ void throw_error(ErrorType error_type, const char *format, ...) { } if (asc_flag) { - /* yyerror(""); */ + yyerror(""); int needed = snprintf(NULL, 0, " LINE (%d:%d) ** %s ERROR: ", line, column, error_name); char *error_message = malloc(needed + 1); snprintf(error_message, needed + 1, " LINE (%d:%d) ** %s ERROR: ", line, column, error_name); From 1c5b7de5fd3dab8d48fc3d120d49e5140842d0b0 Mon Sep 17 00:00:00 2001 From: Annie Date: Mon, 5 May 2025 15:26:27 -0400 Subject: [PATCH 064/109] FUNCTION CALLS WORK WITH 6+ ENTRIES YIPPEEgit add . --- src/codegen.c | 70 ++++++++++++++++++++++---- src/codegen.h | 7 +++ tests/sprint4/test/sp4_cg_calls.alpha | 34 +++++++++++++ tests/sprint4/test/sp4_cg_calls.alpha~ | 34 +++++++++++++ 4 files changed, 134 insertions(+), 11 deletions(-) create mode 100644 tests/sprint4/test/sp4_cg_calls.alpha create mode 100644 tests/sprint4/test/sp4_cg_calls.alpha~ diff --git a/src/codegen.c b/src/codegen.c index 6da4ddf..492d3df 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -2,7 +2,7 @@ /* The Translators - Spring 2025 */ #include "codegen.h" - +int paramCount = 0; int generate() { offset = 0; currentsp = 0; @@ -603,6 +603,7 @@ int generateEqualTo(Instruction *inst) { return 0; } int generateCall(Instruction *inst) { + paramCount = 0; TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); if (op1 == NULL) { @@ -670,7 +671,7 @@ int generateAddressOf(Instruction *inst) { int generateParam(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); - + fprintf(stderr, "generate param reached\n"); if (op1 == NULL) { printdebug("generateParam failed, NULL operand"); return -1; @@ -681,8 +682,31 @@ int generateParam(Instruction *inst) { printdebug("generateParam failed, %s is not in CGlist", getName(getTN(op1))); return -1; } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%edi\t#adding param start\n", getAddress(op1CG)); + paramCount += 1; + switch(paramCount) { + case 1: + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %s\t#adding param start\n", getAddress(op1CG), REG1); + break; + case 2: + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %s\t#adding param start\n", getAddress(op1CG), REG2); + break; + case 3: + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %s\t#adding param start\n", getAddress(op1CG), REG3); + break; + case 4: + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %s\t#adding param start\n", getAddress(op1CG), REG4); + break; + case 5: + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %s\t#adding param start\n", getAddress(op1CG), REG5); + break; + case 6: + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %s\t#adding param start\n", getAddress(op1CG), REG6); + break; + default: + offset += getPrimSize(getTypeEntry(getTN(op1))); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#adding param start\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#adding param end\n", offset - getPrimSize(getTypeEntry(getTN(op1)))); + } return 0; } @@ -712,16 +736,40 @@ int generateFunctionStart(Instruction *inst) { int paramOffset = 16; TableNode *tnToAdd = getFirstEntry(st); if (getAdInfoType(paramTN) != TYPE_RECORD_TYPE) { - CGNode *paramCG = addCG(tnToAdd, offset); - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getAddress(paramCG)); + CGNode *paramCG = addCG(tnToAdd, offset); + paramOffset += getPrimSize(tnToAdd); + fprintf(cg_flag, "\tmovl\t%%edi, %d(%%rbp)\t#FunctionStart1param end\n", getAddress(paramCG)); } else { int numParams = getRecLength(paramTN); - for (int i = 0; i < numParams; i++) { + for (int i = numParams; i > 0; i--) { CGNode *paramCG = addCG(tnToAdd, offset); - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getAddress(paramCG)); - paramOffset = getPrimSize(getTypeEntry(tnToAdd)); + switch(i) { + case 1: + fprintf(cg_flag, "\tmovl\t%s, %d(%%rbp)\t#FunctionStart1param end\n", REG1, getAddress(paramCG)); + break; + case 2: + fprintf(cg_flag, "\tmovl\t%s, %d(%%rbp)\t#FunctionStart1param end\n", REG2, getAddress(paramCG)); + break; + case 3: + fprintf(cg_flag, "\tmovl\t%s, %d(%%rbp)\t#FunctionStart1param end\n", REG3, getAddress(paramCG)); + break; + case 4: + fprintf(cg_flag, "\tmovl\t%s, %d(%%rbp)\t#FunctionStart1param end\n", REG4, getAddress(paramCG)); + break; + case 5: + fprintf(cg_flag, "\tmovl\t%s, %d(%%rbp)\t#FunctionStart1param end\n", REG5, getAddress(paramCG)); + break; + case 6: + fprintf(cg_flag, "\tmovl\t%s, %d(%%rbp)\t#FunctionStart1param end\n", REG6, getAddress(paramCG)); + break; + default: + paramOffset += getPrimSize(getTypeEntry(tnToAdd)); + offset += getPrimSize(getTypeEntry(tnToAdd)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getAddress(paramCG)); + + } + tnToAdd = getNextEntry(tnToAdd); } } diff --git a/src/codegen.h b/src/codegen.h index 2d67a6e..bf1d7cd 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -13,6 +13,13 @@ #include "intermediate_code.h" #include "symbol_table.h" +#define REG1 "%edi" +#define REG2 "%esi" +#define REG3 "%edx" +#define REG4 "%ecx" +#define REG5 "%r8d" +#define REG6 "%r9d" + extern FILE *cg_flag; typedef struct CGNode { diff --git a/tests/sprint4/test/sp4_cg_calls.alpha b/tests/sprint4/test/sp4_cg_calls.alpha new file mode 100644 index 0000000..45a1512 --- /dev/null +++ b/tests/sprint4/test/sp4_cg_calls.alpha @@ -0,0 +1,34 @@ +(* TEST: [-asc -tc -cg -ir] *) + +#include "std.alpha" +(* Standard Alpha Library - Provided by Carl *) + +type string: 1 -> character +function entry: string2integer + + +type rec: [integer: x; integer: y; integer: z; integer: a; integer: b; integer: c; integer: d] + +type T2: rec -> integer +type T: integer -> integer +type main: string -> integer +function entry: main +function bar: T2 +function ahh: T + +ahh (a) := { + a := printInteger(a); + return -1; +} + +bar (a, b, c,d,e,f,g) := { + a := printInteger(g); + return b; +} + +entry (arg) := { + [integer:x; integer:y; integer: result] + + result := bar(1,2,3,4,5,6,7); + return 1; +} diff --git a/tests/sprint4/test/sp4_cg_calls.alpha~ b/tests/sprint4/test/sp4_cg_calls.alpha~ new file mode 100644 index 0000000..5a69469 --- /dev/null +++ b/tests/sprint4/test/sp4_cg_calls.alpha~ @@ -0,0 +1,34 @@ +(* TEST: [-asc -tc -cg -ir] *) + +#include "std.alpha" +(* Standard Alpha Library - Provided by Carl *) + +type string: 1 -> character +function entry: string2integer + + +type rec: [integer: x; integer: y; integer: z; integer: a; integer: b; integer: c; integer: d] + +type T2: rec -> integer +type T: integer -> integer +type main: string -> integer +function entry: main +function bar: T2 +function ahh: T + +ahh (a) := { + a := printInteger(a); + return -1; +} + +bar (a, b, c,d,e,f,g) := { + a := printInteger(f); + return b; +} + +entry (arg) := { + [integer:x; integer:y; integer: result] + + result := bar(1,2,3,4,5,6,7); + return 1; +} From 0446b0ae6b692e4943f7d9681e0911fc5458ba45 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Mon, 5 May 2025 17:15:52 -0400 Subject: [PATCH 065/109] Added some notes and fixed the bp --- src/grammar.y | 88 ++++++++++++++++------------ tests/sprint3/test/sp3_if_else.alpha | 13 ++-- tests/sprint4/test/sp4_cg_fib.alpha | 34 +++++++++++ 3 files changed, 88 insertions(+), 47 deletions(-) create mode 100644 tests/sprint4/test/sp4_cg_fib.alpha diff --git a/src/grammar.y b/src/grammar.y index 6fd864c..354f19d 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -133,12 +133,12 @@ prototype: include_list: include_statement include_list | include_statement - ; + ; include_statement: - INCLUDE C_STRING + INCLUDE C_STRING ; @@ -214,17 +214,17 @@ definition: if(type_of_param_type == TYPE_FUNCTION_TYPE){ CreateEntry(cur, TYPE_FUNCTION_DECLARATION, parameter,NULL, getAdInfo(parameter)); // throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); - + } if(type_of_param_type == TYPE_ARRAY_TYPE){ CreateEntry(cur, TYPE_ARRAY, parameter,NULL, getAdInfo(parameter)); //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); - + } if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter))==undefined; // throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition.");} - + } } } else { @@ -248,13 +248,13 @@ definition: printdebug("undefined type of parameter inside record"); CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); - + } else { if(type_of_param_type == TYPE_FUNCTION_DECLARATION){ printdebug("function declaration of parameter inside record"); CreateEntry(cur, TYPE_FUNCTION_DECLARATION, getTypeEntry(entry),NULL, getAdInfo(entry)); //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); - + } if(type_of_param_type == TYPE_ARRAY){ printdebug("array type of parameter inside record"); @@ -271,7 +271,7 @@ definition: printdebug("record type of parameter inside record"); CreateEntry(cur, TYPE_RECORD, getTypeEntry(entry),NULL, getAdInfo(entry)); //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition.");} - } + } /*printdebug("creating entry of type %s for function", getType(entry)); CreateEntry(cur, getTypeEntry(entry), "undefined", NULL);*/ @@ -304,7 +304,7 @@ function_declaration: FUNCTION ID COLON ID { if(getAdInfoType(table_lookup(cur, $4))==TYPE_FUNCTION_TYPE){ - //printf("%s\n",$2); + //printf("%s\n",$1); //printf("%s\n",getName(table_lookup(cur, $4))); if (CreateEntry(cur,TYPE_FUNCTION_DECLARATION, table_lookup(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false,NULL)) == undefined) { throw_error(ERROR_TYPE, "Duplicate defination of function in function declaration"); @@ -489,7 +489,7 @@ declaration: if(CreateEntry(cur,d,(TableNode*)$1,$3,NULL) == undefined){ throw_error(ERROR_TYPE, "Duplicate defination of function in declaration list"); - } + } } else if(d == TYPE_ARRAY_TYPE){ @@ -620,19 +620,27 @@ compound_statement: S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); }expression R_PAREN THEN { - emit_label(label_gen()); + int l = label_gen(); + emit_conditional_jump(E_IF_X_TRUE, l, tn_or_const(NODE, $4)); + Stack * t = S_Peek(TrueList); + S_Push(t, current, 1); + + emit_goto(0); + t = S_Peek(FalseList); + S_Push(t, current, 1); + emit_label(l); 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); + S_Push(stack, S_Init(), 0); emit_goto(0); - S_Push(S_Peek(FalseList), current, 1); + S_Push(S_Peek(stack), current, 1); emit_label(l); } sblock { int l = label_gen(); - emit_backpatch(S_Pop(FalseList), l); + emit_backpatch(S_Pop(stack), l); emit_label(l); if ($8 == undefined && $11 != undefined) { $$ = $11; @@ -665,21 +673,22 @@ compound_statement: simple_statement: - assignable ASSIGN expression + assignable{ + S_Push(TrueList, S_Init(), 0); + S_Push(FalseList, S_Init(), 0); + } ASSIGN expression { // ---------------------------------------------------------------------------- emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_backpatch(S_Pop(FalseList), getLabel(current)); // ---------------------------------------------------------------------------- - 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)))); @@ -689,28 +698,22 @@ simple_statement: //printf("%s\n\n", getType(getTypeEntry((TableNode*)$3))); node = undefined; } - - - if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){ - emit_assignment($1, tn_or_const(NODE, $3)); - printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$3)); - } else if (getTypeEntry(getTypeEntry(node)) == arrayprim && getTypeEntry((TableNode*)$3) == addr) { - emit_assignment($1, tn_or_const(NODE, $3)); - printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$3)); - } else if (getTypeEntry(getTypeEntry(node)) == recprime && getTypeEntry((TableNode*)$3) == addr) { - emit_assignment($1, tn_or_const(NODE, $3)); - printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$3)); - } - - - else { + if(getAdInfoType(node) == getAdInfoType((TableNode*)$4)){ + emit_assignment($1, tn_or_const(NODE, $4)); + printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$4)); + } else if (getTypeEntry(getTypeEntry(node)) == arrayprim && getTypeEntry((TableNode*)$4) == addr) { + emit_assignment($1, tn_or_const(NODE, $4)); + printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$4)); + } else if (getTypeEntry(getTypeEntry(node)) == recprime && getTypeEntry((TableNode*)$4) == addr) { + emit_assignment($1, tn_or_const(NODE, $4)); + printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$4)); + } else { //printf("%d\n",getAdInfoType((TableNode*)$1)); //printf("%d\n",getAdInfoType((TableNode*)$3)); //printf("%d\n",getAdInfoType((TableNode*)$1)); //printf("%d\n",getAdInfoType((TableNode*)$3)); - 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)); + throw_error(ERROR_TYPE, "Assignable Assign Expression - Object %s of type %s != Object %s of type %s", getName(node), getType(node), getName((TableNode*)$4), getType((TableNode*)$4)); } - $$ = undefined; } @@ -1020,9 +1023,10 @@ expression: char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); // ---------------------------------------------------------------------------- - emit_label(label_gen()); - emit_backpatch(S_Pop(TrueList), getLabel(current)); + // emit_label(label_gen()); + // emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_binary_op(E_LESS_THAN, node, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); + /* emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); if(t==NULL){ @@ -1037,6 +1041,7 @@ expression: 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) { @@ -1054,9 +1059,8 @@ expression: char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); // ---------------------------------------------------------------------------- - emit_label(label_gen()); - emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_binary_op(E_EQUAL_TO, node, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); + /* emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); if(t==NULL){ @@ -1071,6 +1075,9 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); + */ + // emit_label(label_gen()); + // emit_backpatch(S_Pop(TrueList), getLabel(current)); // ---------------------------------------------------------------------------- printdebug("equals check expression"); if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1) != undefined) { @@ -1089,6 +1096,7 @@ expression: } | L_PAREN expression R_PAREN + // TODO: We need to check if we need to backpatch here. { printdebug("paren expression. current type is %s",getType((TableNode*)$2)); $$=$2; @@ -1143,7 +1151,7 @@ expression: } cur = getParent(cur); - + /*TableNode * t = getFirstEntry(cur); TableNode * n = look_up(cur, $2); @@ -1419,6 +1427,7 @@ assignable: char* temp = temp_var_gen(); int t = 6; //emission + // arr._1 .... $$ = CreateEntry(cur,t, integ, temp, NULL); } } @@ -1452,6 +1461,7 @@ assignable: } TableNode* node = CreateEntry(cur,t, type, temp, NULL); + // getElementOffset(rec, ID) //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) //emit_field_access(char* node, char* record, $3) $$=node; diff --git a/tests/sprint3/test/sp3_if_else.alpha b/tests/sprint3/test/sp3_if_else.alpha index e8f4bd7..40c2580 100644 --- a/tests/sprint3/test/sp3_if_else.alpha +++ b/tests/sprint3/test/sp3_if_else.alpha @@ -12,15 +12,12 @@ bar (r,s) := { } entry (arg) := { - [ integer: result ; rec: w] - if ( result = result ) then { - if ( result < w.y ) then { - result := 8; - } else { - result := 9; - }(* *) + [ integer: r ; integer: s; Boolean: x] + x := (r < s) & x; + if ( r < s ) then { + r := 5; } else { - result := bar('c', 7); + r := 7; } return 0; } diff --git a/tests/sprint4/test/sp4_cg_fib.alpha b/tests/sprint4/test/sp4_cg_fib.alpha new file mode 100644 index 0000000..df740d1 --- /dev/null +++ b/tests/sprint4/test/sp4_cg_fib.alpha @@ -0,0 +1,34 @@ +(* TEST: [-asc -tc -cg -ir] *) + +#include "std.alpha" + + +type M : string -> integer +function entry : M + +type fib: integer -> integer +function Fib : fib + +Fib(i) := { + [ Boolean: a ; Boolean: b ; Boolean: c] + if( i = 0 ) then { + return 7; + } else { + i := i; + } + b := b | (a & c); + b := 2 < 3; + if(i = 1) then { + return 1; + } else { + return i + Fib(i - 1); + } +} + +entry (arg) := { + [ integer: x; integer: y ] + x := 2; + x := Fib(2); + y := printInteger(Fib(2)); + return 1; +} From 0114e1d65f6499e0d6d1bad19fb8ae3d012626d2 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Mon, 5 May 2025 20:18:23 -0400 Subject: [PATCH 066/109] emission for func dec --- src/grammar.y | 1 + src/intermediate_code.c | 13 +++++++++++++ src/intermediate_code.h | 2 ++ 3 files changed, 16 insertions(+) diff --git a/src/grammar.y b/src/grammar.y index 354f19d..3d7db57 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -315,6 +315,7 @@ function_declaration: CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false,NULL)); } + emit_function_dec(table_lookup(cur, $2)); } | EXTERNAL FUNCTION ID COLON ID diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 73d43df..beccafd 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -167,6 +167,7 @@ TNodeOrConst *tn_or_const(Discriminant d, void *tnc) { return count; } + static void emit_helper(void) { Instruction *inst = calloc(1, sizeof(*inst)); if (begin == NULL) { @@ -179,6 +180,11 @@ static void emit_helper(void) { current = inst; } } +void emit_function_dec(TableNode * name){ + emit_helper(); + current->opcode = E_FUNC_DEC; + current->result = name; +} void emit_binary_op( Op op, @@ -405,6 +411,13 @@ void emit_as_file(FILE *out_file, Instruction *i) { return; } switch (i->opcode) { + case E_FUNC_DEC: + fprintf(out_file, + "%4.d: func_dec : %s\n", + i->index, + getName(i->result)); + + break; case E_FUNC_START: fprintf(out_file, "%4.d: func : %s\n", diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 1e60a91..5f50828 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -44,6 +44,7 @@ typedef struct TNodeOrConst TNodeOrConst; typedef enum { // these are from page 364 E_LABEL = 10000, // this is not in the book E_FUNC_START, + E_FUNC_DEC, E_ADD, // 1 from the list E_SUB, // 1 E_MUL, // 1 @@ -138,6 +139,7 @@ void emit_conditional_jump(Op condition, int label, ...); void emit_function_start(TableNode *name); void emit_parameter(TNodeOrConst *param); void emit_function_call(TableNode *result, int param_count, TNodeOrConst *name); +void emit_function_dec(TableNode * name); void emit_return(TNodeOrConst *value); void emit_reserve(TableNode *result, TNodeOrConst *size); void emit_release(TableNode *pointer); From ddfaeaeab6202478591a6d7db41c995ad80cbcff Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 5 May 2025 23:32:47 -0400 Subject: [PATCH 067/109] rewrite basically --- genx.sh | 218 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 164 insertions(+), 54 deletions(-) diff --git a/genx.sh b/genx.sh index b902a82..5bbb6f9 100755 --- a/genx.sh +++ b/genx.sh @@ -19,23 +19,153 @@ LIGHTPURPLE='\033[1;35m' LIGHTCYAN='\033[1;36m' WHITE='\033[1;37m' -if [ ! -f "./alpha" ]; then - echo -e "${RED}[GenX] ${YELLOW}File ./alpha not found! Generating with 'make'.${WHITE}" - make -fi +alphaToInclude=() +cToInclude=() +sToInclude=() +cToBuild=() +sToInclude+=("library/alpha_lib_reg.s") +sToInclude+=("library/alpha_driver.s") + +filename="" +s_name="" +backup_file="" + +# -{ FUNC }----------------------------------------------------# help() { echo -e "${WHITE}-----{ ${BLUE}GenX.sh Help ${WHITE}}-----\n" echo -e "${YELLOW} Arguments: ${WHITE}" echo -e "${GREEN} -help ${WHITE} Displays this message\n" echo -e "${YELLOW} Usage: ${WHITE}" - echo -e "${GREEN} ./genx.sh ${WHITE} Generates executable file from \n" + echo -e "${GREEN} ./genx.sh ${WHITE} Generates executable file from \n" echo -e "${YELLOW} Notes: ${WHITE}" - echo -e "${ORANGE} Generates .s and links alpha driver and general library." + echo -e "${ORANGE} Generates .s and links alpha driver and general library and other includes.\n" echo -e "${WHITE}-----------------------------------------\n" - exit 1 } +printLists() { + echo -e "${GREEN}[GenX] ${WHITE}Alpha files to include: ${BLUE}${alphaToInclude[@]}${WHITE}" + echo -e "${GREEN}[GenX] ${WHITE}C files to include: ${BLUE}${cToInclude[@]}${WHITE}" + echo -e "${GREEN}[GenX] ${WHITE}C files to build: ${BLUE}${cToBuild[@]}${WHITE}" + echo -e "${GREEN}[GenX] ${WHITE}S files to include: ${BLUE}${sToInclude[@]}${WHITE}" +} + +getIncludes() { + while IFS= read -r line || [ -n "$line" ]; do + if [[ $line =~ ^#include\ \"[^\"]+\" ]]; then + between_quotes=$(echo "$line" | sed -n 's/.*"\([^"]*\)".*/\1/p') + extension="${between_quotes##*.}" + sed -i "\|$line|d" "$1" + + if [[ $between_quotes == *".alpha" ]]; then + path=$(dirname "$1") + alpha_file=${path}"/"${between_quotes} + + if [[ -f "library/$between_quotes" ]]; then + alphaToInclude+=("library/${between_quotes}") + + elif [[ -f $alpha_file ]]; then + alphaToInclude+=("$alpha_file") + + else + echo -e "${RED}[GenX] ${YELLOW}File $between_quotes not found!${WHITE}" + restoreFileFromBackup "$1" + exit 1 + fi + + elif [[ $between_quotes == *".c" ]]; then + path=$(dirname "$1") + c_file=${path}"/"${between_quotes} + if [[ -f $c_file ]]; then + cToBuild+=("$c_file") + else + echo -e "${RED}[GenX] ${YELLOW}File $between_quotes not found!${WHITE}" + restoreFileFromBackup "$1" + exit 1 + fi + + elif [[ $between_quotes == *".s" ]]; then + path=$(dirname "$1") + s_file=${path}"/"${between_quotes} + if [[ -f $s_file ]]; then + sToInclude+=("$s_file") + else + echo -e "${RED}[GenX] ${YELLOW}File $between_quotes not found!${WHITE}" + restoreFileFromBackup "$1" + exit 1 + fi + + else + echo -e "${RED}[GenX] ${YELLOW}Not able to include file type $extension!${WHITE}" + exit 1 + fi + fi + + done < "$1" +} + + +ass_c() { + for c in "${cToBuild[@]}"; do + if [ -f "$c" ]; then + c_file_ass=$(basename "$c" .c) + c_file_ass=out/$c_file_ass.s + cToInclude+=($c_file_ass) + gcc -S $c -o $c_file_ass + else + echo -e "${RED}[GenX] ${YELLOW}File $c not found!${WHITE}" + exit 1 + fi + done +} + + +appendStr() { + for alpha_file in "${alphaToInclude[@]}"; do + if [ -f "$alpha_file" ]; then + temp_file=$(mktemp) + cat "$alpha_file" > "$temp_file" + cat "$1" >> "$temp_file" + mv "$temp_file" "$1" + else + echo -e "${RED}[GenX] ${YELLOW}File $alpha_file not found!${WHITE}" + fi + done +} + +ass() { + sToInclude_string=$(printf "%s " "${sToInclude[@]}") + cToInclude_string=$(printf "%s " "${cToInclude[@]}") + gcc "$1" ${cToInclude_string} ${sToInclude_string} -no-pie -o binaries/${2} + if [ $? -eq 0 ]; then + echo -e "${GREEN}[GenX] ${WHITE}Done!" + else + echo -e "${RED}[GenX] ${YELLOW}Error generating executable file!${WHITE}" + exit 1 + fi +} + +restoreFileFromBackup() { + if [[ -f "$backup_file" ]]; then + cp "$backup_file" "$1" + rm "$backup_file" + else + echo -e "${RED}[GenX] ${YELLOW}Backup file not found!${WHITE}" + fi + +} + +# ----------------------------------------------------{ FUNC }-# + + + +# -{ INIT }----------------------------------------------------# + +if [ ! -f "./alpha" ]; then + echo -e "${RED}[GenX] ${YELLOW}File ./alpha not found! Generating with 'make'.${WHITE}" + make +fi + if [ $# -eq 0 ]; then help fi @@ -44,79 +174,59 @@ if [ ! -d "binaries" ]; then mkdir -p binaries fi +# ----------------------------------------------------{ INIT }-# -appendStd() { - if [ ! -f "$1" ]; then - echo "File not found: $1" - return 1 - fi - backup_file="${1}.bak" - cp "$1" "$backup_file" - - temp_file=$(mktemp) - - while IFS= read -r line || [ -n "$line" ]; do - echo "$line" >> "$temp_file" - if [[ $line =~ ^#include\ \"[^\"]+\" ]]; then - include_file=$(echo "$line" | sed -n 's/.*"\([^"]*\)".*/\1/p') - if [[ $include_file == "std.alpha" ]]; then - echo -e "${GREEN}[GenX] ${WHITE}Including ${BLUE}std.alpha${WHITE}..." - if [ -f "library/std.alpha" ]; then - cat library/std.alpha >> "$temp_file" - else - echo -e "${RED}[GenX] ${YELLOW}File library/std.alpha not found!${WHITE}" - rm "$temp_file" - return 1 - fi - fi - fi - done < "$1" - - mv "$temp_file" "$1" -} - -ass() { - gcc "$1" library/alpha_lib_reg.s library/alpha_driver.s -no-pie -o binaries/${2} - if [ $? -eq 0 ]; then - echo -e "${GREEN}[GenX] ${WHITE}Executable file: binaries/${2}" - echo -e "${GREEN}[GenX] ${WHITE}Done!" - else - echo -e "${RED}[GenX] ${YELLOW}Error generating executable file!${WHITE}" - exit 1 - fi -} +# -{ RUNNER }--------------------------------------------------# if [ $# -eq 1 ]; then if [ -f "$1" ]; then filename=$(basename -- "$1") + backup_file="${1}.bak" + cp "$1" "$backup_file" + if [[ "$1" == *.alpha ]]; then filename="${filename:0:${#filename}-6}" s_name="out/${filename}.s" - appendStd "$1" + + getIncludes "$1" + appendStr "$1" ./alpha -ir -tc -asc -cg -st "$1" - backup_file="${1}.bak" - if [ -f "$backup_file" ]; then - mv "$backup_file" "$1" - fi + + # include a grep here of asc to see if there are any errors echo -e "${GREEN}[GenX] ${WHITE}Generated .s file." + restoreFileFromBackup "$1" + ass_c ass "$s_name" "$filename" + printLists + exit 1 + elif [[ "$1" == *.s ]]; then + echo -e "${GREEN}[GenX] ${WHITE}File $1 is a .s file! (Skipping compiler)${WHITE}" filename="${filename:0:${#filename}-2}" s_name="out/${filename}.s" - echo -e "${GREEN}[GenX] ${WHITE}File $1 is a .s file! (Skipping compiler)${WHITE}" ass "$s_name" "$filename" + restoreFileFromBackup "$1" exit 1 + else echo -e "${RED}[GenX] ${YELLOW}File $1 is not a .alpha file!${WHITE}" + restoreFileFromBackup "$1" exit 1 + fi + else echo -e "${RED}[GenX] ${YELLOW}File $1 not found!${WHITE}" + restoreFileFromBackup "$1" exit 1 fi + else help -fi \ No newline at end of file + exit 1 +fi + +# --------------------------------------------------{ RUNNER }-# From 7b9d6140765eb89ada79e2caa58456e530401bbf Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 5 May 2025 23:34:09 -0400 Subject: [PATCH 068/109] rebase --- tests/sprint4/test/sp4_cg_calls.alpha~ | 34 -------------------------- 1 file changed, 34 deletions(-) delete mode 100644 tests/sprint4/test/sp4_cg_calls.alpha~ diff --git a/tests/sprint4/test/sp4_cg_calls.alpha~ b/tests/sprint4/test/sp4_cg_calls.alpha~ deleted file mode 100644 index 5a69469..0000000 --- a/tests/sprint4/test/sp4_cg_calls.alpha~ +++ /dev/null @@ -1,34 +0,0 @@ -(* TEST: [-asc -tc -cg -ir] *) - -#include "std.alpha" -(* Standard Alpha Library - Provided by Carl *) - -type string: 1 -> character -function entry: string2integer - - -type rec: [integer: x; integer: y; integer: z; integer: a; integer: b; integer: c; integer: d] - -type T2: rec -> integer -type T: integer -> integer -type main: string -> integer -function entry: main -function bar: T2 -function ahh: T - -ahh (a) := { - a := printInteger(a); - return -1; -} - -bar (a, b, c,d,e,f,g) := { - a := printInteger(f); - return b; -} - -entry (arg) := { - [integer:x; integer:y; integer: result] - - result := bar(1,2,3,4,5,6,7); - return 1; -} From cab30dc2c5bb42f1bca34278f34e348f53bc5dc7 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 5 May 2025 23:39:24 -0400 Subject: [PATCH 069/109] =?UTF-8?q?=F0=9F=90=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/programs/{test => }/fib.alpha | 0 tests/programs/{test => }/helloworld.alpha | 0 tests/programs/{test => }/ll.alpha | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename tests/programs/{test => }/fib.alpha (100%) rename tests/programs/{test => }/helloworld.alpha (100%) rename tests/programs/{test => }/ll.alpha (100%) diff --git a/tests/programs/test/fib.alpha b/tests/programs/fib.alpha similarity index 100% rename from tests/programs/test/fib.alpha rename to tests/programs/fib.alpha diff --git a/tests/programs/test/helloworld.alpha b/tests/programs/helloworld.alpha similarity index 100% rename from tests/programs/test/helloworld.alpha rename to tests/programs/helloworld.alpha diff --git a/tests/programs/test/ll.alpha b/tests/programs/ll.alpha similarity index 100% rename from tests/programs/test/ll.alpha rename to tests/programs/ll.alpha From e3081f35a4032949e2ca3b599edf50efc2e719d5 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 6 May 2025 02:45:17 -0400 Subject: [PATCH 070/109] tweaking statement options --- src/grammar.h | 2 ++ src/grammar.y | 10 +++++++++- src/runner.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/grammar.h b/src/grammar.h index ec850a2..a4a9300 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -8,9 +8,11 @@ #include "../src/symbol_table.h" extern FILE *asc_flag; extern bool tc_flag; +extern bool entry_flag; extern void insert_code_line(char *error_message, int line_number); extern bool contains_errors; + typedef enum { ERROR_RUNTIME = 1, ERROR_SYNTAX = 2, diff --git a/src/grammar.y b/src/grammar.y index 3d7db57..4129d38 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -170,6 +170,10 @@ definition: } | ID { + if(strcmp($1, "entry") == 0){ + //seen entry function + entry_flag = true; + } emit_function_start(table_lookup(cur,$1)); //printf("ID: %s\n", $1); //printf("Type: %s\n", getType(table_lookup(getAncestor(cur), $1))); @@ -222,7 +226,7 @@ definition: } if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ - CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter))==undefined; + CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter));//==undefined; // throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition.");} } @@ -309,6 +313,7 @@ function_declaration: if (CreateEntry(cur,TYPE_FUNCTION_DECLARATION, table_lookup(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false,NULL)) == undefined) { throw_error(ERROR_TYPE, "Duplicate defination of function in function declaration"); } + } else{ throw_error(ERROR_TYPE, "Function declatation (%s) is not a valid function type", $2); @@ -722,9 +727,12 @@ simple_statement: | RETURN expression { $$ = getTypeEntry((TableNode*)$2); emit_return(tn_or_const(NODE,(TableNode*)$2));} + + // | assignable ASSIGN RESERVE assignable{ } |simple_statement error {yyerrok; yyclearin; printdebug("error in simple statement");} + ; diff --git a/src/runner.h b/src/runner.h index 37c7bad..5736311 100644 --- a/src/runner.h +++ b/src/runner.h @@ -56,6 +56,7 @@ FILE *ir_flag = NULL; FILE *cg_flag = NULL; bool tc_flag = false; bool DEBUG = false; +bool entry_flag = false; int no_flag = 0; int arg; bool contains_errors = false; From 8b177b2807c4b4c45cbfb3ddbe346e9fe19752eb Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 6 May 2025 04:38:35 -0400 Subject: [PATCH 071/109] tweaking statement options --- src/grammar.h | 4 +- src/grammar.y | 117 +++++++++++---------------------------------- src/runner.h | 2 + src/symbol_table.c | 31 ++++++++++++ src/symbol_table.h | 8 ++++ 5 files changed, 71 insertions(+), 91 deletions(-) diff --git a/src/grammar.h b/src/grammar.h index a4a9300..588ac23 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -11,8 +11,8 @@ extern bool tc_flag; extern bool entry_flag; extern void insert_code_line(char *error_message, int line_number); extern bool contains_errors; - - +extern int context; +extern TableNode* comparator; typedef enum { ERROR_RUNTIME = 1, ERROR_SYNTAX = 2, diff --git a/src/grammar.y b/src/grammar.y index 4129d38..14041ed 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -680,6 +680,14 @@ compound_statement: simple_statement: assignable{ + //updating context for reserve/release + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY){ + context = 1; + } + if(getAdInfoType((TableNode*)$1) == TYPE_RECORD){ + context = 2; + } + comparator = $1; S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); } ASSIGN expression @@ -721,6 +729,8 @@ simple_statement: throw_error(ERROR_TYPE, "Assignable Assign Expression - Object %s of type %s != Object %s of type %s", getName(node), getType(node), getName((TableNode*)$4), getType((TableNode*)$4)); } $$ = undefined; + //resetting context + context = 0; } @@ -768,6 +778,7 @@ ablock: argument_list: expression{ TableNode * arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); + //inside a scope of an array call if line number is -2 if(getLine(cur)==-2){ if(getTypeEntry(arg) != integ){ throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg)); @@ -793,6 +804,7 @@ argument_list: { TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); + //inside a scope of an array call if line number is -2 if(getLine(cur)==-2){ if(getTypeEntry(arg) != integ){ throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg)); @@ -1125,7 +1137,7 @@ expression: emit_reserve(node, tn_or_const(INTEGER, &v)); $$ = node; } - | RELEASE ID { + /*| RELEASE ID { TableNode * n = look_up(cur, $2); if(getAdInfoType(n) != TYPE_RECORD){ throw_error(ERROR_TYPE, "Invalid Release expression with object %s of type %s.", @@ -1136,7 +1148,7 @@ expression: TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); //emit release needed here $$ = node; - } + }*/ | RESERVE ID { cur = CreateScope(cur, -2,-1); } ablock { @@ -1159,50 +1171,8 @@ expression: $$=undefined; } cur = getParent(cur); - - - - /*TableNode * t = getFirstEntry(cur); - TableNode * n = look_up(cur, $2); - if(getAdInfoType(n) == TYPE_ARRAY){ - int array_dims = getNumArrDim(getTypeEntry(n)); - if ($5 != array_dims) { - throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", array_dims, $5); - }else{ - int traverse = 0; - while(t != NULL && t != undefined && getName(t)[0] != '&'){ - t = getNextEntry(t); - } - if(getTypeEntry(t) != integ){ - throw_error(ERROR_TYPE, "Arg for an array is not of type integer"); - $$= undefined; - }else{ - //seen first number - traverse++; - t = getNextEntry(t); - while(traversecon = context; + if (context_head == NULL) { + context_head = cs; + cs->next = NULL; + } else { + cs->next = context_head; + context_head = cs; + } + return cs; +} + +int PopContext() { + if (context_head == NULL) { + printf("cannot pop from an empty stack. Invalid.\n"); + return -1; + } + Context_stack *cs = context_head; + context_head = context_head->next; + printf("Popped context off stack: number %d\n", cs->con); + return cs->con; +} + Constant_Stack *Pop() { if (head == NULL) { printf("cannot pop from an empty stack. Invalid.\n"); diff --git a/src/symbol_table.h b/src/symbol_table.h index 2a8abb5..48419d9 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -29,6 +29,11 @@ typedef struct Constant_Stack { bool isConst; } Constant_Stack; +typedef struct Context_stack { + int con; + struct Context_stack *next; +} Context_stack; + typedef struct { int size; } primitive_info; @@ -107,7 +112,9 @@ void printdebug_impl(char *file, int line, const char *format, ...); char *temp_var_gen(); char *arg_var_gen(); Constant_Stack *Push(TableNode *type, void *value, bool isConst); +Context_stack *PushContext(int context); Constant_Stack *Pop(); +int PopContext(); Constant_Stack *Print_Stack(); AdInfo *CreatePrimitiveInfo(int size); int getPrimSize(TableNode *definition); @@ -184,6 +191,7 @@ extern TableNode *recprime; extern TableNode *funtypeprime; extern TableNode *undefined; extern Constant_Stack *head; +extern Context_stack *context_head; extern char *COLOR_RED; extern char *COLOR_GREEN; From 07255a5193862f225d1059be0114e90edd8c2184 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 6 May 2025 14:16:21 -0400 Subject: [PATCH 072/109] added a lot of new fucntions --- src/grammar.h | 2 +- src/grammar.y | 11 +++--- src/symbol_table.c | 90 +++++++++++++++++++++++++++++++++++++++++++--- src/symbol_table.h | 35 ++++++++++++++++-- 4 files changed, 125 insertions(+), 13 deletions(-) diff --git a/src/grammar.h b/src/grammar.h index 588ac23..2ad23b8 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -12,7 +12,7 @@ extern bool entry_flag; extern void insert_code_line(char *error_message, int line_number); extern bool contains_errors; extern int context; -extern TableNode* comparator; +//extern TableNode* comparator; typedef enum { ERROR_RUNTIME = 1, ERROR_SYNTAX = 2, diff --git a/src/grammar.y b/src/grammar.y index 14041ed..692df0e 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -682,12 +682,15 @@ simple_statement: assignable{ //updating context for reserve/release if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY){ + context = 1; } - if(getAdInfoType((TableNode*)$1) == TYPE_RECORD){ + else if(getAdInfoType((TableNode*)$1) == TYPE_RECORD){ context = 2; + } else{ + context = 0; } - comparator = $1; + //comparator = $1; S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); } ASSIGN expression @@ -1233,7 +1236,7 @@ assignable: //Creating a dummy scope where we create entries for all the arguments of a function call //Must also consider that we might be in an array access if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY){ - PushContext(3); + //PushContext(3); printdebug("%sCreating scope for array access", COLOR_CYAN); //special scope for numbers for array access scope cur = CreateScope(cur, -2,-1); @@ -1243,7 +1246,7 @@ assignable: //we have to consider emmissions in ablocks ablock { - PopContext(); + //PopContext(); //int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); int type = getAdInfoType(getTypeEntry((TableNode*)$1)); printdebug("%stype is %d", COLOR_PURPLE, type); diff --git a/src/symbol_table.c b/src/symbol_table.c index 98e1c0c..73a9b10 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -5,7 +5,9 @@ Constant_Stack *head = NULL; Context_stack *context_head = NULL; -TableNode* comparator = NULL; +//TableNode* comparator = NULL; +Function_Stack *function_head = NULL; + int temp2_count = 0; int temp3_count = 0; @@ -55,14 +57,20 @@ Constant_Stack *Push(TableNode *type, void *value, bool isConst) { return cs; } -Context_stack *PushContext(int context) { +Context_stack *PushContext(int context, TableNode *typeToCompare) { if (context != 1 && context != 2 && context != 3 && context != 0) { printdebug( "invalid context passed in"); return NULL; } - Context_stack *cs = (Context_stack *)malloc(sizeof(Context_stack)); + if(typeToCompare == NULL) { + printdebug( + "passed a NULL reference to PushContext. Invalid."); + return NULL; + } + Context_stack *cs = (Context_stack *)calloc(1,sizeof(Context_stack)); cs->con = context; + cs->typeToCompare = typeToCompare; if (context_head == NULL) { context_head = cs; cs->next = NULL; @@ -73,17 +81,89 @@ Context_stack *PushContext(int context) { return cs; } -int PopContext() { +Function_Stack *PushFunction(int arg, TableNode* FunctionType) { + if (FunctionType == NULL) { + printdebug( + "passed a NULL reference to PushFunction. Invalid."); + return NULL; + } + if(FunctionType == undefined) { + printdebug( + "passed an undefined reference to PushFunction. Invalid."); + return NULL; + } + Function_Stack *fs = (Function_Stack *)calloc(1,sizeof(Function_Stack)); + fs->arg = arg; + fs->FunctionType = FunctionType; + if (function_head == NULL) { + function_head = fs; + fs->next = NULL; + } else { + fs->next = function_head; + function_head = fs; + } + return fs; +} + +Function_Stack *PopFunction() { + if (function_head == NULL) { + printf("cannot pop from an empty stack. Invalid.\n"); + return NULL; + } + Function_Stack *fs = function_head; + function_head = function_head->next; + return fs; +} + +int getArgumentNumber(Function_Stack *fs) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to getArgumentNumber. Invalid."); + return -1; + } + return fs->arg; +} + +TableNode* getFunctionTypeContext(Function_Stack *fs) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to getFunctionTypeContext. Invalid."); + return undefined; + } + TableNode* tn = fs->FunctionType; + return tn; +} + +Context_stack *PopContext() { if (context_head == NULL) { printf("cannot pop from an empty stack. Invalid.\n"); - return -1; + return NULL; } Context_stack *cs = context_head; context_head = context_head->next; printf("Popped context off stack: number %d\n", cs->con); + return cs; +} + +int getContextType(Context_stack *cs) { + if (cs == NULL) { + printdebug( + "passed a NULL reference to getContextType. Invalid."); + return -1; + } return cs->con; } +//should be +TableNode *getContextTypeEntry(Context_stack *cs) { + if (cs == NULL) { + printdebug( + "passed a NULL reference to getContextTypeEntry. Invalid."); + return undefined; + } + TableNode* tn = cs->typeToCompare; + return NULL; +} Constant_Stack *Pop() { if (head == NULL) { printf("cannot pop from an empty stack. Invalid.\n"); diff --git a/src/symbol_table.h b/src/symbol_table.h index 48419d9..b71030b 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -17,10 +17,12 @@ extern FILE *ir_flag; -struct TableNode; +typedef struct TableNode TableNode; typedef struct TFList TFList; typedef struct CGNode CGNode; typedef struct SymbolTable SymbolTable; +typedef struct Function_Stack Function_Stack; +typedef struct Context_stack Context_stack; typedef struct Constant_Stack { struct TableNode *theType; @@ -28,12 +30,33 @@ typedef struct Constant_Stack { struct Constant_Stack *next; bool isConst; } Constant_Stack; +//explanation about context stack +//If we have an array context, it means that we are expecting an array, either on the left side of assignable or as the (one of the) arguments that needs to be passed in for a function +//with the array context, either we are initializing the array OR we are reserving space for an element of the array. Can only reserve a record or an array so that element must be a record or an array. +//if we have a record context, that means we are expecting a record on the left side of the assignable assignment or we are expecting a record passed as an argument for a function call. +//we push and pop these contexts as needed. +//we can also push the table node of the thing that we are trying to look at. If it is supposed to be an array, for example, we can push that array onto the stack +//if it is a record, we can push that record onto the stack so that we can approperiately type check +//0 - no expecting array or record +//1 - expecting an array +//2 - expecting a record +//we also have a function call stack to look at what function call we are inside (what parameters it is expecting) +//This is distinct from the context stack. We don't necessarily add to the function call stack. After every valid argument, we simply add one to what argument we are seeing +//This lets us update the context stack as needed with the next tablenode type that we are comparing against +//we can also simply add to the function call stack if we have functions inside functions and then update as needed typedef struct Context_stack { int con; + TableNode *typeToCompare; struct Context_stack *next; } Context_stack; +typedef struct Function_Stack{ + int arg; + TableNode *FunctionType; + struct Function_Stack *next; +} Function_Stack; + typedef struct { int size; } primitive_info; @@ -112,10 +135,15 @@ void printdebug_impl(char *file, int line, const char *format, ...); char *temp_var_gen(); char *arg_var_gen(); Constant_Stack *Push(TableNode *type, void *value, bool isConst); -Context_stack *PushContext(int context); +Context_stack *PushContext(int context,TableNode *typeToCompare); +Function_Stack *PushFunction(int arg, TableNode* FunctionType); Constant_Stack *Pop(); -int PopContext(); +Context_stack *PopContext(); +Function_Stack *PopFunction(); +TableNode* getFunctionTypeContext(Function_Stack *fs); +int getContextType(Context_stack *cs); Constant_Stack *Print_Stack(); +int getArgumentNumber(Function_Stack *fs); AdInfo *CreatePrimitiveInfo(int size); int getPrimSize(TableNode *definition); AdInfo *CreateArrayInfo(int dim, TableNode *type); @@ -192,6 +220,7 @@ extern TableNode *funtypeprime; extern TableNode *undefined; extern Constant_Stack *head; extern Context_stack *context_head; +extern Function_Stack *function_head; extern char *COLOR_RED; extern char *COLOR_GREEN; From 26b23a68fa76d9b8e6d92391cbc222840c4a8f26 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 6 May 2025 15:20:43 -0400 Subject: [PATCH 073/109] need to update argument list for the right context --- src/grammar.y | 10 +++++++++- src/symbol_table.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/symbol_table.h | 2 ++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/grammar.y b/src/grammar.y index 692df0e..61e9724 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1242,12 +1242,20 @@ assignable: cur = CreateScope(cur, -2,-1); }else{ cur = CreateScope(cur, -1,-1); - }} + } + + if(getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + //the function context is created. Pushing the type of the function since that has the information needed + PushFunction(1, getTypeEntry((TableNode*)$1)); + } + + } //we have to consider emmissions in ablocks ablock { //PopContext(); //int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); + PopFunction(); int type = getAdInfoType(getTypeEntry((TableNode*)$1)); printdebug("%stype is %d", COLOR_PURPLE, type); printdebug("%s", getName((TableNode*)$1)); diff --git a/src/symbol_table.c b/src/symbol_table.c index 73a9b10..50ae956 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -124,6 +124,48 @@ int getArgumentNumber(Function_Stack *fs) { return fs->arg; } +TableNode* getRecordNumberType(TableNode* record, int arg){ + if(record == NULL){ + //case where NULL is being passed in + return undefined; + } + if(getAdInfoType(record) != TYPE_RECORD_TYPE){ + //case where invalid argument number is being passed + return undefined; + } + if(arg Date: Tue, 6 May 2025 15:21:36 -0400 Subject: [PATCH 074/109] shtuff --- genx.sh | 1 + library/alphastdio.c | 61 +++++++++ library/std.alpha | 15 ++- library/std.s | 273 +++++++++++++++++++++++++++++++++++++++ tests/programs/fib.alpha | 2 +- tests/programs/io.alpha | 18 +++ 6 files changed, 367 insertions(+), 3 deletions(-) create mode 100644 library/alphastdio.c create mode 100644 library/std.s create mode 100644 tests/programs/io.alpha diff --git a/genx.sh b/genx.sh index 5bbb6f9..7025bd0 100755 --- a/genx.sh +++ b/genx.sh @@ -25,6 +25,7 @@ sToInclude=() cToBuild=() sToInclude+=("library/alpha_lib_reg.s") sToInclude+=("library/alpha_driver.s") +sToInclude+=("library/std.s") filename="" s_name="" diff --git a/library/alphastdio.c b/library/alphastdio.c new file mode 100644 index 0000000..f4da2ce --- /dev/null +++ b/library/alphastdio.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include + + + +int printS(char *str) { + if (str == NULL) return -1; + printf("%s", str); + return 0; +} + +char *inS() { + char *buffer = malloc(100); + if (buffer == NULL) return NULL; + if (fgets(buffer, 100, stdin) == NULL) { + free(buffer); + return NULL; + } + buffer[strcspn(buffer, "\n")] = 0; + return buffer; +} + + + +int printI(int i) { + printf("%d", i); + return 0; +} + +int inI() { + int i; + char buffer[100]; + if (fgets(buffer, sizeof(buffer), stdin) == NULL) return 0; + if (sscanf(buffer, "%d", &i) != 1) return 0; + return i; +} + + + +int printC(char c) { + printf("%c", c); + return 0; +} + +char inC() { + char c; + if (scanf(" %c", &c) != 1) return 0; + return c; +} + + + +int printB(bool b) { + if (b) + printf("true"); + else + printf("false"); + return 0; +} \ No newline at end of file diff --git a/library/std.alpha b/library/std.alpha index a2fc025..2d0f1a9 100644 --- a/library/std.alpha +++ b/library/std.alpha @@ -1,4 +1,4 @@ -(* Standard Alpha Library - Provided by Carl *) +(* Standard Alpha Library *) type string: 1 -> character type BooleanXBoolean: [Boolean: x; Boolean: y] @@ -16,9 +16,20 @@ type characterXcharacter2Boolean: characterXcharacter -> Boolean type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean type integer2address: integer -> address type address2integer: address -> integer +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + external function printInteger: integer2integer external function printCharacter: character2integer external function printBoolean: Boolean2integer -function entry: string2integer +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character \ No newline at end of file diff --git a/library/std.s b/library/std.s new file mode 100644 index 0000000..6cdcb90 --- /dev/null +++ b/library/std.s @@ -0,0 +1,273 @@ + .file "alphastdio.c" + .text + .section .rodata +.LC0: + .string "%s" + .text + .globl printS + .type printS, @function +printS: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movq %rdi, -8(%rbp) + cmpq $0, -8(%rbp) + jne .L2 + movl $-1, %eax + jmp .L3 +.L2: + movq -8(%rbp), %rax + movq %rax, %rsi + leaq .LC0(%rip), %rax + movq %rax, %rdi + movl $0, %eax + call printf@PLT + movl $0, %eax +.L3: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size printS, .-printS + .section .rodata +.LC1: + .string "\n" + .text + .globl inS + .type inS, @function +inS: +.LFB7: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl $100, %edi + call malloc@PLT + movq %rax, -8(%rbp) + cmpq $0, -8(%rbp) + jne .L5 + movl $0, %eax + jmp .L6 +.L5: + movq stdin(%rip), %rdx + movq -8(%rbp), %rax + movl $100, %esi + movq %rax, %rdi + call fgets@PLT + testq %rax, %rax + jne .L7 + movq -8(%rbp), %rax + movq %rax, %rdi + call free@PLT + movl $0, %eax + jmp .L6 +.L7: + movq -8(%rbp), %rax + leaq .LC1(%rip), %rdx + movq %rdx, %rsi + movq %rax, %rdi + call strcspn@PLT + movq -8(%rbp), %rdx + addq %rdx, %rax + movb $0, (%rax) + movq -8(%rbp), %rax +.L6: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size inS, .-inS + .section .rodata +.LC2: + .string "%d" + .text + .globl printI + .type printI, @function +printI: +.LFB8: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movl -4(%rbp), %eax + movl %eax, %esi + leaq .LC2(%rip), %rax + movq %rax, %rdi + movl $0, %eax + call printf@PLT + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size printI, .-printI + .globl inI + .type inI, @function +inI: +.LFB9: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + addq $-128, %rsp + movq %fs:40, %rax + movq %rax, -8(%rbp) + xorl %eax, %eax + movq stdin(%rip), %rdx + leaq -112(%rbp), %rax + movl $100, %esi + movq %rax, %rdi + call fgets@PLT + testq %rax, %rax + jne .L11 + movl $0, %eax + jmp .L14 +.L11: + leaq -116(%rbp), %rdx + leaq -112(%rbp), %rax + leaq .LC2(%rip), %rcx + movq %rcx, %rsi + movq %rax, %rdi + movl $0, %eax + call __isoc99_sscanf@PLT + cmpl $1, %eax + je .L13 + movl $0, %eax + jmp .L14 +.L13: + movl -116(%rbp), %eax +.L14: + movq -8(%rbp), %rdx + subq %fs:40, %rdx + je .L15 + call __stack_chk_fail@PLT +.L15: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE9: + .size inI, .-inI + .globl printC + .type printC, @function +printC: +.LFB10: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, %eax + movb %al, -4(%rbp) + movsbl -4(%rbp), %eax + movl %eax, %edi + call putchar@PLT + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE10: + .size printC, .-printC + .section .rodata +.LC3: + .string " %c" + .text + .globl inC + .type inC, @function +inC: +.LFB11: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movq %fs:40, %rax + movq %rax, -8(%rbp) + xorl %eax, %eax + leaq -9(%rbp), %rax + movq %rax, %rsi + leaq .LC3(%rip), %rax + movq %rax, %rdi + movl $0, %eax + call __isoc99_scanf@PLT + cmpl $1, %eax + je .L19 + movl $0, %eax + jmp .L21 +.L19: + movzbl -9(%rbp), %eax +.L21: + movq -8(%rbp), %rdx + subq %fs:40, %rdx + je .L22 + call __stack_chk_fail@PLT +.L22: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE11: + .size inC, .-inC + .section .rodata +.LC4: + .string "true" +.LC5: + .string "false" + .text + .globl printB + .type printB, @function +printB: +.LFB12: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, %eax + movb %al, -4(%rbp) + cmpb $0, -4(%rbp) + je .L24 + leaq .LC4(%rip), %rax + movq %rax, %rdi + movl $0, %eax + call printf@PLT + jmp .L25 +.L24: + leaq .LC5(%rip), %rax + movq %rax, %rdi + movl $0, %eax + call printf@PLT +.L25: + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE12: + .size printB, .-printB + .ident "GCC: (GNU) 14.2.1 20250207" + .section .note.GNU-stack,"",@progbits diff --git a/tests/programs/fib.alpha b/tests/programs/fib.alpha index 2f33e06..b136295 100644 --- a/tests/programs/fib.alpha +++ b/tests/programs/fib.alpha @@ -1 +1 @@ -(* TODO: Prints out fib sequence. *) \ No newline at end of file +(* TODO *) \ No newline at end of file diff --git a/tests/programs/io.alpha b/tests/programs/io.alpha new file mode 100644 index 0000000..eac7b03 --- /dev/null +++ b/tests/programs/io.alpha @@ -0,0 +1,18 @@ +#include "std.alpha" + +function entry: string2integer + +entry (arg) := { + [integer: x; string: s; character: c; integer: result] + + s := inS(1); + result := printS(s); + + x := inI(1); + result := printI(x); + + c := inC(1); + result := printC(c); + + return 0; +} \ No newline at end of file From c8491b62e42879d4423084321afc478d78f07d0e Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 15:34:55 -0400 Subject: [PATCH 075/109] psuh --- tests/programs/fib.alpha | 31 ++++++++- tests/programs/io.alpha | 2 + tests/sprint4/expected/sp4_cg_add.asc.exp | 57 ++++++++++++--- tests/sprint4/expected/sp4_cg_add.ir.exp | 24 ++++--- tests/sprint4/expected/sp4_cg_add.s.exp | 36 +++++++--- tests/sprint4/expected/sp4_cg_and.asc.exp | 60 +++++++++++++--- tests/sprint4/expected/sp4_cg_calls.asc.exp | 60 ++++++++++++++++ tests/sprint4/expected/sp4_cg_calls.ir.exp | 37 ++++++++++ tests/sprint4/expected/sp4_cg_calls.s.exp | 69 +++++++++++++++++++ tests/sprint4/expected/sp4_cg_div.asc.exp | 57 ++++++++++++--- tests/sprint4/expected/sp4_cg_div.ir.exp | 24 ++++--- tests/sprint4/expected/sp4_cg_div.s.exp | 34 ++++++--- .../sprint4/expected/sp4_cg_equal_to.asc.exp | 57 ++++++++++++--- tests/sprint4/expected/sp4_cg_equal_to.ir.exp | 27 +++++--- tests/sprint4/expected/sp4_cg_equal_to.s.exp | 36 +++++++--- .../sprint4/expected/sp4_cg_less_than.asc.exp | 57 ++++++++++++--- .../sprint4/expected/sp4_cg_less_than.ir.exp | 27 +++++--- tests/sprint4/expected/sp4_cg_less_than.s.exp | 36 +++++++--- tests/sprint4/expected/sp4_cg_mod.asc.exp | 57 ++++++++++++--- tests/sprint4/expected/sp4_cg_mod.ir.exp | 24 ++++--- tests/sprint4/expected/sp4_cg_mod.s.exp | 36 +++++++--- tests/sprint4/expected/sp4_cg_mult.asc.exp | 57 ++++++++++++--- tests/sprint4/expected/sp4_cg_mult.ir.exp | 24 ++++--- tests/sprint4/expected/sp4_cg_mult.s.exp | 32 +++++++-- tests/sprint4/expected/sp4_cg_neg.asc.exp | 55 ++++++++++++--- tests/sprint4/expected/sp4_cg_neg.ir.exp | 19 +++-- tests/sprint4/expected/sp4_cg_neg.s.exp | 29 ++++++-- tests/sprint4/expected/sp4_cg_not.asc.exp | 55 ++++++++++++--- tests/sprint4/expected/sp4_cg_not.ir.exp | 20 ++++-- tests/sprint4/expected/sp4_cg_not.s.exp | 34 +++++---- tests/sprint4/expected/sp4_cg_or.asc.exp | 57 ++++++++++++--- tests/sprint4/expected/sp4_cg_or.ir.exp | 33 ++++++--- tests/sprint4/expected/sp4_cg_or.s.exp | 52 ++++++++------ tests/sprint4/expected/sp4_cg_sub.asc.exp | 57 ++++++++++++--- tests/sprint4/expected/sp4_cg_sub.ir.exp | 24 ++++--- tests/sprint4/expected/sp4_cg_sub.s.exp | 34 ++++++--- tests/sprint4/test/sp4_cg_add.alpha | 36 +++++++++- tests/sprint4/test/sp4_cg_and.alpha | 36 +++++++++- tests/sprint4/test/sp4_cg_calls.alpha | 39 +++++++++-- tests/sprint4/test/sp4_cg_div.alpha | 36 +++++++++- tests/sprint4/test/sp4_cg_equal_to.alpha | 36 +++++++++- tests/sprint4/test/sp4_cg_fib.alpha | 34 --------- tests/sprint4/test/sp4_cg_less_than.alpha | 36 +++++++++- tests/sprint4/test/sp4_cg_mod.alpha | 36 +++++++++- tests/sprint4/test/sp4_cg_mult.alpha | 36 +++++++++- tests/sprint4/test/sp4_cg_neg.alpha | 36 +++++++++- tests/sprint4/test/sp4_cg_not.alpha | 36 +++++++++- tests/sprint4/test/sp4_cg_or.alpha | 36 +++++++++- tests/sprint4/test/sp4_cg_sub.alpha | 36 +++++++++- 49 files changed, 1560 insertions(+), 339 deletions(-) create mode 100644 tests/sprint4/expected/sp4_cg_calls.asc.exp create mode 100644 tests/sprint4/expected/sp4_cg_calls.ir.exp create mode 100644 tests/sprint4/expected/sp4_cg_calls.s.exp delete mode 100644 tests/sprint4/test/sp4_cg_fib.alpha diff --git a/tests/programs/fib.alpha b/tests/programs/fib.alpha index b136295..9ebef58 100644 --- a/tests/programs/fib.alpha +++ b/tests/programs/fib.alpha @@ -1 +1,30 @@ -(* TODO *) \ No newline at end of file +(* TEST: [-asc -tc -cg -ir] *) + +#include "std.alpha" + +function entry : string2integer +function Fib : integer2integer + +Fib(i) := { + [ Boolean: a ; Boolean: b ; Boolean: c] + if( i = 0 ) then { + return 7; + } else { + i := i; + } + b := b | (a & c); + b := 2 < 3; + if(i = 1) then { + return 1; + } else { + return i + Fib(i - 1); + } +} + +entry (arg) := { + [ integer: x; integer: y ] + x := 2; + x := Fib(2); + y := printInteger(Fib(2)); + return 1; +} diff --git a/tests/programs/io.alpha b/tests/programs/io.alpha index eac7b03..45b387f 100644 --- a/tests/programs/io.alpha +++ b/tests/programs/io.alpha @@ -5,6 +5,8 @@ function entry: string2integer entry (arg) := { [integer: x; string: s; character: c; integer: result] + result := printS("hello world"); + s := inS(1); result := printS(s); diff --git a/tests/sprint4/expected/sp4_cg_add.asc.exp b/tests/sprint4/expected/sp4_cg_add.asc.exp index bff5d97..c234273 100644 --- a/tests/sprint4/expected/sp4_cg_add.asc.exp +++ b/tests/sprint4/expected/sp4_cg_add.asc.exp @@ -1,10 +1,47 @@ -001: type main: integer -> integer -002: function test: main -003: -004: test (a) := { -005: [integer:x; integer:y] -006: y := 1; -007: x := 3; -008: y := x + y; -009: return y; -010: } \ No newline at end of file +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [integer:x; integer:y; integer: result] +040: +041: y := 1; +042: x := 3; +043: y := x + y; +044: +045: result := printInteger(y); +046: return y; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_add.ir.exp b/tests/sprint4/expected/sp4_cg_add.ir.exp index d0a05ab..73beb15 100644 --- a/tests/sprint4/expected/sp4_cg_add.ir.exp +++ b/tests/sprint4/expected/sp4_cg_add.ir.exp @@ -1,8 +1,16 @@ - 1: func : test - 2: $t0 = 1 - 3: y = $t0 - 4: $t1 = 3 - 5: x = $t1 - 6: $t2 = x + y - 7: y = $t2 - 8: return : y + 1: func_dec : entry + 2: func : entry + 3: $t0 = 1 + 4: Label : 1 + 5: y = $t0 + 6: $t1 = 3 + 7: Label : 2 + 8: x = $t1 + 9: $t2 = x + y + 10: Label : 3 + 11: y = $t2 + 12: param y + 13: call : printInteger 1 + 14: Label : 4 + 15: result = $t3 + 16: return : y diff --git a/tests/sprint4/expected/sp4_cg_add.s.exp b/tests/sprint4/expected/sp4_cg_add.s.exp index 4764400..f58dd79 100644 --- a/tests/sprint4/expected/sp4_cg_add.s.exp +++ b/tests/sprint4/expected/sp4_cg_add.s.exp @@ -1,12 +1,30 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $3, -12(%rbp) #constant assign +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $128, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $1, -12(%rbp) #constant assign +.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end - movl -16(%rbp), %eax #addition start - movl -16(%rbp), %eax - addl %edx, %eax - movl %eax, -20(%rbp) #addition end + movl $3, -20(%rbp) #constant assign +.L2: movl -20(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end + movl %eax, -24(%rbp) #assign end + + movl -24(%rbp), %eax #addition start + addl -16(%rbp), %eax + movl %eax, -28(%rbp) #addition end +.L3: + movl -28(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl -16(%rbp), %edi #adding param start + call printInteger + movl %eax, -32(%rbp) #store return from call +.L4: + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl -16(%rbp), %eax #return y + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_and.asc.exp b/tests/sprint4/expected/sp4_cg_and.asc.exp index 8676177..17aa547 100644 --- a/tests/sprint4/expected/sp4_cg_and.asc.exp +++ b/tests/sprint4/expected/sp4_cg_and.asc.exp @@ -1,10 +1,50 @@ -001: type main: integer -> integer -002: function test: main -003: -004: test (a) := { -005: [Boolean:b; Boolean: c; Boolean: d] -006: c := true; -007: d := false; -008: d := c & d; -009: return 1; -010: } \ No newline at end of file +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [Boolean:b; Boolean: c; Boolean: d; integer: result] +040: +041: z := true; + LINE (41:14) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t0 of type Boolean + LINE (41:14) ** TYPE ERROR: Invalid type passed to assignable. + LINE (41:5) ** TYPE ERROR: Undefined variable z +042: d := false; +043: d := c & d; +044: +045: result := printBoolean(d); +046: return 1; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_calls.asc.exp b/tests/sprint4/expected/sp4_cg_calls.asc.exp new file mode 100644 index 0000000..edc0a7a --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_calls.asc.exp @@ -0,0 +1,60 @@ +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: +039: type rec: [integer: x; integer: y; integer: z; integer: a; integer: b; integer: c; integer: d] +040: type T2: rec -> integer +041: type T: integer -> integer +042: function bar: T2 +043: function ahh: T +044: +045: ahh (a) := { +046: a := printInteger(a); +047: return -1; +048: } +049: +050: bar (a, b, c,d,e,f,g) := { +051: a := printInteger(g); +052: return b; +053: } +054: +055: entry (arg) := { +056: [integer:x; integer:y; integer: result] +057: +058: result := bar(1,2,3,4,5,6,7); +059: return 1; +060: } diff --git a/tests/sprint4/expected/sp4_cg_calls.ir.exp b/tests/sprint4/expected/sp4_cg_calls.ir.exp new file mode 100644 index 0000000..2995985 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_calls.ir.exp @@ -0,0 +1,37 @@ + 1: func_dec : entry + 2: func_dec : bar + 3: func_dec : ahh + 4: func : ahh + 5: param a + 6: call : printInteger 1 + 7: Label : 1 + 8: a = $t0 + 9: $t1 = 1 + 10: $t2 = -$t1 + 11: return : $t2 + 12: func : bar + 13: param g + 14: call : printInteger 1 + 15: Label : 2 + 16: a = $t3 + 17: return : b + 18: func : entry + 19: $t4 = 1 + 20: $t5 = 2 + 21: $t6 = 3 + 22: $t7 = 4 + 23: $t8 = 5 + 24: $t9 = 6 + 25: $t10 = 7 + 26: param $t10 + 27: param $t9 + 28: param $t8 + 29: param $t7 + 30: param $t6 + 31: param $t5 + 32: param $t4 + 33: call : bar 7 + 34: Label : 3 + 35: result = $t11 + 36: $t12 = 1 + 37: return : $t12 diff --git a/tests/sprint4/expected/sp4_cg_calls.s.exp b/tests/sprint4/expected/sp4_cg_calls.s.exp new file mode 100644 index 0000000..55b65cb --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_calls.s.exp @@ -0,0 +1,69 @@ +.globl entry +ahh: + pushq %rbp + movq %rsp, %rbp + subq $128, %rsp + movl %edi, -4(%rbp) #FunctionStart1param end + movl -4(%rbp), %edi #adding param start + call printInteger + movl %eax, -8(%rbp) #store return from call +.L1: + movl -8(%rbp), %eax #assign start + movl %eax, -4(%rbp) #assign end + movl $1, -12(%rbp) #constant assign + movl -12(%rbp), %eax #negation start + negl %eax + movl %eax, -16(%rbp) #negation end + movl -16(%rbp), %eax #return $t2 + leave + ret +bar: + pushq %rbp + movq %rsp, %rbp + subq $128, %rsp + movl 20(%rbp), %eax #FunctionStart1Param start + movl %eax, -4(%rbp) #FunctionStart1param end + movl %r9d, -12(%rbp) #FunctionStart1param end + movl %r8d, -16(%rbp) #FunctionStart1param end + movl %ecx, -20(%rbp) #FunctionStart1param end + movl %edx, -24(%rbp) #FunctionStart1param end + movl %esi, -28(%rbp) #FunctionStart1param end + movl %edi, -32(%rbp) #FunctionStart1param end + movl -32(%rbp), %edi #adding param start + call printInteger + movl %eax, -36(%rbp) #store return from call +.L2: + movl -36(%rbp), %eax #assign start + movl %eax, -4(%rbp) #assign end + movl -12(%rbp), %eax #return b + leave + ret +entry: + pushq %rbp + movq %rsp, %rbp + subq $128, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $1, -12(%rbp) #constant assign + movl $2, -16(%rbp) #constant assign + movl $3, -20(%rbp) #constant assign + movl $4, -24(%rbp) #constant assign + movl $5, -28(%rbp) #constant assign + movl $6, -32(%rbp) #constant assign + movl $7, -36(%rbp) #constant assign + movl -36(%rbp), %edi #adding param start + movl -32(%rbp), %esi #adding param start + movl -28(%rbp), %edx #adding param start + movl -24(%rbp), %ecx #adding param start + movl -20(%rbp), %r8d #adding param start + movl -16(%rbp), %r9d #adding param start + movl -12(%rbp), %eax #adding param start + movl %eax, 88(%rbp) #adding param end + call bar + movl %eax, -44(%rbp) #store return from call +.L3: + movl -44(%rbp), %eax #assign start + movl %eax, -48(%rbp) #assign end + movl $1, -52(%rbp) #constant assign + movl -52(%rbp), %eax #return $t12 + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_div.asc.exp b/tests/sprint4/expected/sp4_cg_div.asc.exp index 87b68f2..5e0a832 100644 --- a/tests/sprint4/expected/sp4_cg_div.asc.exp +++ b/tests/sprint4/expected/sp4_cg_div.asc.exp @@ -1,10 +1,47 @@ -001: type main: integer -> integer -002: function test: main -003: -004: test (a) := { -005: [integer:x; integer:y] -006: y := 1; -007: x := 3; -008: y := x / y; -009: return y; -010: } \ No newline at end of file +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [integer:x; integer:y; integer: result] +040: +041: x := 24; +042: y := 3; +043: y := x / y; +044: +045: result := printInteger(y); +046: return y; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_div.ir.exp b/tests/sprint4/expected/sp4_cg_div.ir.exp index 905d038..f316a19 100644 --- a/tests/sprint4/expected/sp4_cg_div.ir.exp +++ b/tests/sprint4/expected/sp4_cg_div.ir.exp @@ -1,8 +1,16 @@ - 1: func : test - 2: $t0 = 1 - 3: y = $t0 - 4: $t1 = 3 - 5: x = $t1 - 6: $t2 = x / y - 7: y = $t2 - 8: return : y + 1: func_dec : entry + 2: func : entry + 3: $t0 = 24 + 4: Label : 1 + 5: x = $t0 + 6: $t1 = 3 + 7: Label : 2 + 8: y = $t1 + 9: $t2 = x / y + 10: Label : 3 + 11: y = $t2 + 12: param y + 13: call : printInteger 1 + 14: Label : 4 + 15: result = $t3 + 16: return : y diff --git a/tests/sprint4/expected/sp4_cg_div.s.exp b/tests/sprint4/expected/sp4_cg_div.s.exp index 1a71c6e..cc51cef 100644 --- a/tests/sprint4/expected/sp4_cg_div.s.exp +++ b/tests/sprint4/expected/sp4_cg_div.s.exp @@ -1,12 +1,30 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $3, -12(%rbp) #constant assign +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $128, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $24, -12(%rbp) #constant assign +.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end + movl $3, -20(%rbp) #constant assign +.L2: + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end movl -16(%rbp), %eax #division start cltd - idivl -8(%rbp) - movl %eax, -20(%rbp) #division end - movl -20(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end + idivl -24(%rbp) + movl %eax, -28(%rbp) #division end +.L3: + movl -28(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -24(%rbp), %edi #adding param start + call printInteger + movl %eax, -32(%rbp) #store return from call +.L4: + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl -24(%rbp), %eax #return y + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_equal_to.asc.exp b/tests/sprint4/expected/sp4_cg_equal_to.asc.exp index df0cbd5..d43e036 100644 --- a/tests/sprint4/expected/sp4_cg_equal_to.asc.exp +++ b/tests/sprint4/expected/sp4_cg_equal_to.asc.exp @@ -1,10 +1,47 @@ -001: type main: integer -> integer -002: function test: main -003: -004: test (a) := { -005: [Boolean: b; integer: x; integer: y] -006: x := 1; -007: y := 2; -008: b := x = y; -009: return 1; -010: } \ No newline at end of file +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [Boolean: b; integer: x; integer: y; integer: result] +040: +041: x := 1; +042: y := 2; +043: b := x = y; +044: +045: result := printBoolean(b); +046: return 1; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_equal_to.ir.exp b/tests/sprint4/expected/sp4_cg_equal_to.ir.exp index 1739814..d0b9e1c 100644 --- a/tests/sprint4/expected/sp4_cg_equal_to.ir.exp +++ b/tests/sprint4/expected/sp4_cg_equal_to.ir.exp @@ -1,10 +1,17 @@ - 1: func : test - 2: $t0 = 1 - 3: x = $t0 - 4: $t1 = 2 - 5: y = $t1 - 6: if ( x = y ) GOTO 0 - 7: GOTO : 0 - 8: b = $t2 - 9: $t3 = 1 - 10: return : $t3 + 1: func_dec : entry + 2: func : entry + 3: $t0 = 1 + 4: Label : 1 + 5: x = $t0 + 6: $t1 = 2 + 7: Label : 2 + 8: y = $t1 + 9: $t2 = x == y + 10: Label : 3 + 11: b = $t2 + 12: param b + 13: call : printBoolean 1 + 14: Label : 4 + 15: result = $t3 + 16: $t4 = 1 + 17: return : $t4 diff --git a/tests/sprint4/expected/sp4_cg_equal_to.s.exp b/tests/sprint4/expected/sp4_cg_equal_to.s.exp index 5f73e0b..374f095 100644 --- a/tests/sprint4/expected/sp4_cg_equal_to.s.exp +++ b/tests/sprint4/expected/sp4_cg_equal_to.s.exp @@ -1,11 +1,31 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $2, -12(%rbp) #constant assign +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $128, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $1, -12(%rbp) #constant assign +.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end - movl -8(%rbp), %eax #equal to start - cmpl -16(%rbp), %eax + movl $2, -20(%rbp) #constant assign +.L2: + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -16(%rbp), %eax #equal to start + cmpl -24(%rbp), %eax sete %al - movb %al, -15(%rbp) #equal to end - movl $1, -20(%rbp) #constant assign + movb %al, -25(%rbp) #equal to end +.L3: + movl -25(%rbp), %eax #assign start + movl %eax, -26(%rbp) #assign end + movl -26(%rbp), %edi #adding param start + call printBoolean + movl %eax, -30(%rbp) #store return from call +.L4: + movl -30(%rbp), %eax #assign start + movl %eax, -34(%rbp) #assign end + movl $1, -38(%rbp) #constant assign + movl -38(%rbp), %eax #return $t4 + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_less_than.asc.exp b/tests/sprint4/expected/sp4_cg_less_than.asc.exp index 63b0136..ab65623 100644 --- a/tests/sprint4/expected/sp4_cg_less_than.asc.exp +++ b/tests/sprint4/expected/sp4_cg_less_than.asc.exp @@ -1,10 +1,47 @@ -001: type main: integer -> integer -002: function test: main -003: -004: test (a) := { -005: [Boolean: b; integer: x; integer: y] -006: x := 1; -007: y := 2; -008: b := x < y; -009: return 1; -010: } \ No newline at end of file +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [Boolean: b; integer: x; integer: y; integer: result] +040: +041: x := 1; +042: y := 2; +043: b := x < y; +044: +045: result := printBoolean(b); +046: return 1; +047: } diff --git a/tests/sprint4/expected/sp4_cg_less_than.ir.exp b/tests/sprint4/expected/sp4_cg_less_than.ir.exp index 5feb329..169347b 100644 --- a/tests/sprint4/expected/sp4_cg_less_than.ir.exp +++ b/tests/sprint4/expected/sp4_cg_less_than.ir.exp @@ -1,10 +1,17 @@ - 1: func : test - 2: $t0 = 1 - 3: x = $t0 - 4: $t1 = 2 - 5: y = $t1 - 6: if ( x < y ) GOTO 0 - 7: GOTO : 0 - 8: b = $t2 - 9: $t3 = 1 - 10: return : $t3 + 1: func_dec : entry + 2: func : entry + 3: $t0 = 1 + 4: Label : 1 + 5: x = $t0 + 6: $t1 = 2 + 7: Label : 2 + 8: y = $t1 + 9: $t2 = x < y + 10: Label : 3 + 11: b = $t2 + 12: param b + 13: call : printBoolean 1 + 14: Label : 4 + 15: result = $t3 + 16: $t4 = 1 + 17: return : $t4 diff --git a/tests/sprint4/expected/sp4_cg_less_than.s.exp b/tests/sprint4/expected/sp4_cg_less_than.s.exp index 4ed5ad1..57c2a33 100644 --- a/tests/sprint4/expected/sp4_cg_less_than.s.exp +++ b/tests/sprint4/expected/sp4_cg_less_than.s.exp @@ -1,11 +1,31 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $2, -12(%rbp) #constant assign +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $128, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $1, -12(%rbp) #constant assign +.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end - movl -8(%rbp), %eax #less than start - cmpl -16(%rbp), %eax + movl $2, -20(%rbp) #constant assign +.L2: + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -16(%rbp), %eax #less than start + cmpl -24(%rbp), %eax setl %al - movb %al, -15(%rbp) #less than end - movl $1, -20(%rbp) #constant assign + movb %al, -25(%rbp) #less than end +.L3: + movl -25(%rbp), %eax #assign start + movl %eax, -26(%rbp) #assign end + movl -26(%rbp), %edi #adding param start + call printBoolean + movl %eax, -30(%rbp) #store return from call +.L4: + movl -30(%rbp), %eax #assign start + movl %eax, -34(%rbp) #assign end + movl $1, -38(%rbp) #constant assign + movl -38(%rbp), %eax #return $t4 + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_mod.asc.exp b/tests/sprint4/expected/sp4_cg_mod.asc.exp index 32294ec..3edad31 100644 --- a/tests/sprint4/expected/sp4_cg_mod.asc.exp +++ b/tests/sprint4/expected/sp4_cg_mod.asc.exp @@ -1,10 +1,47 @@ -001: type main: integer -> integer -002: function test: main -003: -004: test (a) := { -005: [integer:x; integer:y] -006: y := 1; -007: x := 3; -008: y := x % y; -009: return y; -010: } \ No newline at end of file +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [integer:x; integer:y; integer: result] +040: +041: x := 4; +042: y := 20; +043: y := y % x; +044: +045: result := printInteger(y); +046: return y; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_mod.ir.exp b/tests/sprint4/expected/sp4_cg_mod.ir.exp index b16f1de..4c2421e 100644 --- a/tests/sprint4/expected/sp4_cg_mod.ir.exp +++ b/tests/sprint4/expected/sp4_cg_mod.ir.exp @@ -1,8 +1,16 @@ - 1: func : test - 2: $t0 = 1 - 3: y = $t0 - 4: $t1 = 3 - 5: x = $t1 - 6: $t2 = x % y - 7: y = $t2 - 8: return : y + 1: func_dec : entry + 2: func : entry + 3: $t0 = 4 + 4: Label : 1 + 5: x = $t0 + 6: $t1 = 20 + 7: Label : 2 + 8: y = $t1 + 9: $t2 = y % x + 10: Label : 3 + 11: y = $t2 + 12: param y + 13: call : printInteger 1 + 14: Label : 4 + 15: result = $t3 + 16: return : y diff --git a/tests/sprint4/expected/sp4_cg_mod.s.exp b/tests/sprint4/expected/sp4_cg_mod.s.exp index 97d4259..85cd9db 100644 --- a/tests/sprint4/expected/sp4_cg_mod.s.exp +++ b/tests/sprint4/expected/sp4_cg_mod.s.exp @@ -1,12 +1,30 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $3, -12(%rbp) #constant assign +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $128, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $4, -12(%rbp) #constant assign +.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end - movl -16(%rbp), %eax #mod start - cltd - idivl -8(%rbp) - movl %edx, -20(%rbp) #mod end + movl $20, -20(%rbp) #constant assign +.L2: movl -20(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end + movl %eax, -24(%rbp) #assign end + movl -24(%rbp), %eax #mod start + cltd + idivl -16(%rbp) + movl %edx, -28(%rbp) #mod end +.L3: + movl -28(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -24(%rbp), %edi #adding param start + call printInteger + movl %eax, -32(%rbp) #store return from call +.L4: + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl -24(%rbp), %eax #return y + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_mult.asc.exp b/tests/sprint4/expected/sp4_cg_mult.asc.exp index 15138ee..3a66591 100644 --- a/tests/sprint4/expected/sp4_cg_mult.asc.exp +++ b/tests/sprint4/expected/sp4_cg_mult.asc.exp @@ -1,10 +1,47 @@ -001: type main: integer -> integer -002: function test: main -003: -004: test (a) := { -005: [integer:x; integer:y] -006: y := 1; -007: x := 3; -008: y := x * x; -009: return y; -010: } \ No newline at end of file +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [integer:x; integer:y; integer: result] +040: +041: x := 3; +042: y := 20; +043: y := x * y; +044: +045: result := printInteger(y); +046: return y; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_mult.ir.exp b/tests/sprint4/expected/sp4_cg_mult.ir.exp index c125e68..70de136 100644 --- a/tests/sprint4/expected/sp4_cg_mult.ir.exp +++ b/tests/sprint4/expected/sp4_cg_mult.ir.exp @@ -1,8 +1,16 @@ - 1: func : test - 2: $t0 = 1 - 3: y = $t0 - 4: $t1 = 3 - 5: x = $t1 - 6: $t2 = x * x - 7: y = $t2 - 8: return : y + 1: func_dec : entry + 2: func : entry + 3: $t0 = 3 + 4: Label : 1 + 5: x = $t0 + 6: $t1 = 20 + 7: Label : 2 + 8: y = $t1 + 9: $t2 = x * y + 10: Label : 3 + 11: y = $t2 + 12: param y + 13: call : printInteger 1 + 14: Label : 4 + 15: result = $t3 + 16: return : y diff --git a/tests/sprint4/expected/sp4_cg_mult.s.exp b/tests/sprint4/expected/sp4_cg_mult.s.exp index 20b0a57..567acb3 100644 --- a/tests/sprint4/expected/sp4_cg_mult.s.exp +++ b/tests/sprint4/expected/sp4_cg_mult.s.exp @@ -1,11 +1,29 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $128, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end movl $3, -12(%rbp) #constant assign +.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end - movl -16(%rbp), %eax #multiplication start - imull -16(%rbp), %eax - movl %eax, -20(%rbp) #multiplication end + movl $20, -20(%rbp) #constant assign +.L2: movl -20(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end + movl %eax, -24(%rbp) #assign end + movl -16(%rbp), %eax #multiplication start + imull -24(%rbp), %eax + movl %eax, -28(%rbp) #multiplication end +.L3: + movl -28(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -24(%rbp), %edi #adding param start + call printInteger + movl %eax, -32(%rbp) #store return from call +.L4: + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl -24(%rbp), %eax #return y + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_neg.asc.exp b/tests/sprint4/expected/sp4_cg_neg.asc.exp index 647d812..701f487 100644 --- a/tests/sprint4/expected/sp4_cg_neg.asc.exp +++ b/tests/sprint4/expected/sp4_cg_neg.asc.exp @@ -1,9 +1,46 @@ -001: type main: integer -> integer -002: function test: main -003: -004: test (a) := { -005: [integer:x; integer:y] -006: x := 3; -007: y := -x; -008: return y; -009: } \ No newline at end of file +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [integer:x; integer:y; integer: result] +040: +041: x := 3; +042: y := -x; +043: +044: result := printInteger(y); +045: return y; +046: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_neg.ir.exp b/tests/sprint4/expected/sp4_cg_neg.ir.exp index 6a42a7c..9bc3442 100644 --- a/tests/sprint4/expected/sp4_cg_neg.ir.exp +++ b/tests/sprint4/expected/sp4_cg_neg.ir.exp @@ -1,6 +1,13 @@ - 1: func : test - 2: $t0 = 3 - 3: x = $t0 - 4: $t1 = -x - 5: y = $t1 - 6: return : y + 1: func_dec : entry + 2: func : entry + 3: $t0 = 3 + 4: Label : 1 + 5: x = $t0 + 6: $t1 = -x + 7: Label : 2 + 8: y = $t1 + 9: param y + 10: call : printInteger 1 + 11: Label : 3 + 12: result = $t2 + 13: return : y diff --git a/tests/sprint4/expected/sp4_cg_neg.s.exp b/tests/sprint4/expected/sp4_cg_neg.s.exp index 5f61770..ddf2a63 100644 --- a/tests/sprint4/expected/sp4_cg_neg.s.exp +++ b/tests/sprint4/expected/sp4_cg_neg.s.exp @@ -1,8 +1,25 @@ - movl $3, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl -8(%rbp), %eax #negation start - negl %eax - movl %eax, -12(%rbp) #negation end +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $128, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $3, -12(%rbp) #constant assign +.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end + movl -16(%rbp), %eax #negation start + negl %eax + movl %eax, -20(%rbp) #negation end +.L2: + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -24(%rbp), %edi #adding param start + call printInteger + movl %eax, -28(%rbp) #store return from call +.L3: + movl -28(%rbp), %eax #assign start + movl %eax, -32(%rbp) #assign end + movl -24(%rbp), %eax #return y + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_not.asc.exp b/tests/sprint4/expected/sp4_cg_not.asc.exp index ac22520..634b5f6 100644 --- a/tests/sprint4/expected/sp4_cg_not.asc.exp +++ b/tests/sprint4/expected/sp4_cg_not.asc.exp @@ -1,9 +1,46 @@ -001: type main: integer -> integer -002: function test: main -003: -004: test (a) := { -005: [Boolean: c; Boolean: d] -006: c := true; -007: d := !c; -008: return 1; -009: } \ No newline at end of file +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [Boolean: c; Boolean: d; integer: result] +040: +041: c := true; +042: d := !c; +043: +044: result := printBoolean(d); +045: return 1; +046: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_not.ir.exp b/tests/sprint4/expected/sp4_cg_not.ir.exp index f1b6d6b..5a9a503 100644 --- a/tests/sprint4/expected/sp4_cg_not.ir.exp +++ b/tests/sprint4/expected/sp4_cg_not.ir.exp @@ -1,7 +1,13 @@ - 1: func : test - 2: $t0 = true - 3: c = $t0 - 4: $t1 = !c - 5: d = $t1 - 6: $t2 = 1 - 7: return : $t2 + 1: func_dec : entry + 2: func : entry + 3: $t0 = true + 4: Label : 1 + 5: c = $t0 + 6: Label : 2 + 7: d = $t1 + 8: param d + 9: call : printBoolean 1 + 10: Label : 3 + 11: result = $t2 + 12: $t3 = 1 + 13: return : $t3 diff --git a/tests/sprint4/expected/sp4_cg_not.s.exp b/tests/sprint4/expected/sp4_cg_not.s.exp index 39c04ce..63b18a5 100644 --- a/tests/sprint4/expected/sp4_cg_not.s.exp +++ b/tests/sprint4/expected/sp4_cg_not.s.exp @@ -1,13 +1,21 @@ - movl $-1, -1(%rbp) #constant assign - movl -1(%rbp), %eax #assign start - movl %eax, -2(%rbp) #assign end - movzbl -2(%rbp), %eax #not start - testl %eax, %eax - setne %al - xorl $1, %eax - movzbl %al, %eax - movb %al, -3(%rbp) - andb $1, -3(%rbp) #not end - movl -3(%rbp), %eax #assign start - movl %eax, -4(%rbp) #assign end - movl $1, -8(%rbp) #constant assign +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $128, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $-1, -9(%rbp) #constant assign +.L1: + movl -9(%rbp), %eax #assign start + movl %eax, -10(%rbp) #assign end +.L2: + movl -11(%rbp), %edi #adding param start + call printBoolean + movl %eax, -15(%rbp) #store return from call +.L3: + movl -15(%rbp), %eax #assign start + movl %eax, -19(%rbp) #assign end + movl $1, -23(%rbp) #constant assign + movl -23(%rbp), %eax #return $t3 + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_or.asc.exp b/tests/sprint4/expected/sp4_cg_or.asc.exp index 5a99180..44414e0 100644 --- a/tests/sprint4/expected/sp4_cg_or.asc.exp +++ b/tests/sprint4/expected/sp4_cg_or.asc.exp @@ -1,10 +1,47 @@ -001: type main: integer -> integer -002: function test: main -003: -004: test (a) := { -005: [Boolean:b; Boolean: c; Boolean: d] -006: c := true; -007: d := false; -008: d := c | d; -009: return 1; -010: } \ No newline at end of file +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [Boolean:b; Boolean: c; Boolean: d; integer: result] +040: +041: c := true; +042: d := false; +043: d := c | d; +044: +045: result := printBoolean(d); +046: return 1; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_or.ir.exp b/tests/sprint4/expected/sp4_cg_or.ir.exp index 5dfac99..0319c40 100644 --- a/tests/sprint4/expected/sp4_cg_or.ir.exp +++ b/tests/sprint4/expected/sp4_cg_or.ir.exp @@ -1,9 +1,24 @@ - 1: func : test - 2: $t0 = true - 3: c = $t0 - 4: $t1 = false - 5: d = $t1 - 6: $t2 = c | d - 7: d = $t2 - 8: $t3 = 1 - 9: return : $t3 + 1: func_dec : entry + 2: func : entry + 3: $t0 = true + 4: Label : 1 + 5: c = $t0 + 6: $t1 = false + 7: Label : 2 + 8: d = $t1 + 9: $t2 = true + 10: Label : 3 + 11: if c True GOTO 5 + 12: GOTO : 4 + 13: Label : 4 + 14: if d True GOTO 5 + 15: $t2 = false + 16: GOTO : 5 + 17: Label : 5 + 18: d = $t2 + 19: param d + 20: call : printBoolean 1 + 21: Label : 6 + 22: result = $t3 + 23: $t4 = 1 + 24: return : $t4 diff --git a/tests/sprint4/expected/sp4_cg_or.s.exp b/tests/sprint4/expected/sp4_cg_or.s.exp index 7faecdd..0493673 100644 --- a/tests/sprint4/expected/sp4_cg_or.s.exp +++ b/tests/sprint4/expected/sp4_cg_or.s.exp @@ -1,21 +1,31 @@ - movl $-1, -1(%rbp) #constant assign - movl -1(%rbp), %eax #assign start - movl %eax, -2(%rbp) #assign end - movl $-1, -3(%rbp) #constant assign - movl -3(%rbp), %eax #assign start - movl %eax, -4(%rbp) #assign end - cmpl $0, -2(%rbp) #start or - jne .L1or2 - cmpl $0, -4(%rbp) - je .L1or3 -.L1or2: - movl $1, %eax - jmp .L1or4 -.L1or3: - movl $0, %eax -.L1or4: - movb %al, -5(%rbp) - andb $1, -5(%rbp) #or end - movl -5(%rbp), %eax #assign start - movl %eax, -4(%rbp) #assign end - movl $1, -9(%rbp) #constant assign +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $128, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $-1, -9(%rbp) #constant assign +.L1: + movl -9(%rbp), %eax #assign start + movl %eax, -10(%rbp) #assign end + movl $-1, -11(%rbp) #constant assign +.L2: + movl -11(%rbp), %eax #assign start + movl %eax, -12(%rbp) #assign end + movl $-1, -13(%rbp) #constant assign +.L3: +.L4: + movl $-1, -13(%rbp) #constant assign +.L5: + movl -13(%rbp), %eax #assign start + movl %eax, -12(%rbp) #assign end + movl -12(%rbp), %edi #adding param start + call printBoolean + movl %eax, -17(%rbp) #store return from call +.L6: + movl -17(%rbp), %eax #assign start + movl %eax, -21(%rbp) #assign end + movl $1, -25(%rbp) #constant assign + movl -25(%rbp), %eax #return $t4 + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_sub.asc.exp b/tests/sprint4/expected/sp4_cg_sub.asc.exp index 4b4496c..8726fb3 100644 --- a/tests/sprint4/expected/sp4_cg_sub.asc.exp +++ b/tests/sprint4/expected/sp4_cg_sub.asc.exp @@ -1,10 +1,47 @@ -001: type main: integer -> integer -002: function test: main -003: -004: test (a) := { -005: [integer:x; integer:y] -006: y := 1; -007: x := 3; -008: y := x - y; -009: return y; -010: } \ No newline at end of file +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [integer:x; integer:y; integer: result] +040: +041: y := 1; +042: x := 3; +043: y := x - y; +044: +045: result := printInteger(y); +046: return y; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_sub.ir.exp b/tests/sprint4/expected/sp4_cg_sub.ir.exp index c4ef79a..23e60d4 100644 --- a/tests/sprint4/expected/sp4_cg_sub.ir.exp +++ b/tests/sprint4/expected/sp4_cg_sub.ir.exp @@ -1,8 +1,16 @@ - 1: func : test - 2: $t0 = 1 - 3: y = $t0 - 4: $t1 = 3 - 5: x = $t1 - 6: $t2 = x - y - 7: y = $t2 - 8: return : y + 1: func_dec : entry + 2: func : entry + 3: $t0 = 1 + 4: Label : 1 + 5: y = $t0 + 6: $t1 = 3 + 7: Label : 2 + 8: x = $t1 + 9: $t2 = x - y + 10: Label : 3 + 11: y = $t2 + 12: param y + 13: call : printInteger 1 + 14: Label : 4 + 15: result = $t3 + 16: return : y diff --git a/tests/sprint4/expected/sp4_cg_sub.s.exp b/tests/sprint4/expected/sp4_cg_sub.s.exp index 743ef59..bc47b9f 100644 --- a/tests/sprint4/expected/sp4_cg_sub.s.exp +++ b/tests/sprint4/expected/sp4_cg_sub.s.exp @@ -1,11 +1,29 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $3, -12(%rbp) #constant assign +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $128, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $1, -12(%rbp) #constant assign +.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end - movl -16(%rbp), %eax #subtraction start - subl -8(%rbp), %eax - movl %eax, -20(%rbp) #subtraction end + movl $3, -20(%rbp) #constant assign +.L2: movl -20(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end + movl %eax, -24(%rbp) #assign end + movl -24(%rbp), %eax #subtraction start + subl -16(%rbp), %eax + movl %eax, -28(%rbp) #subtraction end +.L3: + movl -28(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl -16(%rbp), %edi #adding param start + call printInteger + movl %eax, -32(%rbp) #store return from call +.L4: + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl -16(%rbp), %eax #return y + leave + ret diff --git a/tests/sprint4/test/sp4_cg_add.alpha b/tests/sprint4/test/sp4_cg_add.alpha index 0d5fb5a..96e2842 100644 --- a/tests/sprint4/test/sp4_cg_add.alpha +++ b/tests/sprint4/test/sp4_cg_add.alpha @@ -1,6 +1,40 @@ (* TEST: [-asc -tc -cg -ir] *) -#include "std.alpha" +type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer entry (arg) := { [integer:x; integer:y; integer: result] diff --git a/tests/sprint4/test/sp4_cg_and.alpha b/tests/sprint4/test/sp4_cg_and.alpha index a42409b..c4a1d47 100644 --- a/tests/sprint4/test/sp4_cg_and.alpha +++ b/tests/sprint4/test/sp4_cg_and.alpha @@ -1,6 +1,40 @@ (* TEST: [-asc -tc -cg -ir] *) -#include "std.alpha" +type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer entry (arg) := { [Boolean:b; Boolean: c; Boolean: d; integer: result] diff --git a/tests/sprint4/test/sp4_cg_calls.alpha b/tests/sprint4/test/sp4_cg_calls.alpha index 45a1512..c7beea1 100644 --- a/tests/sprint4/test/sp4_cg_calls.alpha +++ b/tests/sprint4/test/sp4_cg_calls.alpha @@ -1,18 +1,45 @@ (* TEST: [-asc -tc -cg -ir] *) -#include "std.alpha" -(* Standard Alpha Library - Provided by Carl *) - type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + function entry: string2integer type rec: [integer: x; integer: y; integer: z; integer: a; integer: b; integer: c; integer: d] - type T2: rec -> integer type T: integer -> integer -type main: string -> integer -function entry: main function bar: T2 function ahh: T diff --git a/tests/sprint4/test/sp4_cg_div.alpha b/tests/sprint4/test/sp4_cg_div.alpha index 39d5a83..097b978 100644 --- a/tests/sprint4/test/sp4_cg_div.alpha +++ b/tests/sprint4/test/sp4_cg_div.alpha @@ -1,6 +1,40 @@ (* TEST: [-asc -tc -cg -ir] *) -#include "std.alpha" +type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer entry (arg) := { [integer:x; integer:y; integer: result] diff --git a/tests/sprint4/test/sp4_cg_equal_to.alpha b/tests/sprint4/test/sp4_cg_equal_to.alpha index a2823cc..1baae8e 100644 --- a/tests/sprint4/test/sp4_cg_equal_to.alpha +++ b/tests/sprint4/test/sp4_cg_equal_to.alpha @@ -1,6 +1,40 @@ (* TEST: [-asc -tc -cg -ir] *) -#include "std.alpha" +type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer entry (arg) := { [Boolean: b; integer: x; integer: y; integer: result] diff --git a/tests/sprint4/test/sp4_cg_fib.alpha b/tests/sprint4/test/sp4_cg_fib.alpha deleted file mode 100644 index df740d1..0000000 --- a/tests/sprint4/test/sp4_cg_fib.alpha +++ /dev/null @@ -1,34 +0,0 @@ -(* TEST: [-asc -tc -cg -ir] *) - -#include "std.alpha" - - -type M : string -> integer -function entry : M - -type fib: integer -> integer -function Fib : fib - -Fib(i) := { - [ Boolean: a ; Boolean: b ; Boolean: c] - if( i = 0 ) then { - return 7; - } else { - i := i; - } - b := b | (a & c); - b := 2 < 3; - if(i = 1) then { - return 1; - } else { - return i + Fib(i - 1); - } -} - -entry (arg) := { - [ integer: x; integer: y ] - x := 2; - x := Fib(2); - y := printInteger(Fib(2)); - return 1; -} diff --git a/tests/sprint4/test/sp4_cg_less_than.alpha b/tests/sprint4/test/sp4_cg_less_than.alpha index 77867ab..86ce4b7 100644 --- a/tests/sprint4/test/sp4_cg_less_than.alpha +++ b/tests/sprint4/test/sp4_cg_less_than.alpha @@ -1,6 +1,40 @@ (* TEST: [-asc -tc -cg -ir] *) -#include "std.alpha" +type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer entry (arg) := { [Boolean: b; integer: x; integer: y; integer: result] diff --git a/tests/sprint4/test/sp4_cg_mod.alpha b/tests/sprint4/test/sp4_cg_mod.alpha index fbd40d5..c405ec4 100644 --- a/tests/sprint4/test/sp4_cg_mod.alpha +++ b/tests/sprint4/test/sp4_cg_mod.alpha @@ -1,6 +1,40 @@ (* TEST: [-asc -tc -cg -ir] *) -#include "std.alpha" +type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer entry (arg) := { [integer:x; integer:y; integer: result] diff --git a/tests/sprint4/test/sp4_cg_mult.alpha b/tests/sprint4/test/sp4_cg_mult.alpha index 28e7ab6..157ba35 100644 --- a/tests/sprint4/test/sp4_cg_mult.alpha +++ b/tests/sprint4/test/sp4_cg_mult.alpha @@ -1,6 +1,40 @@ (* TEST: [-asc -tc -cg -ir] *) -#include "std.alpha" +type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer entry (arg) := { [integer:x; integer:y; integer: result] diff --git a/tests/sprint4/test/sp4_cg_neg.alpha b/tests/sprint4/test/sp4_cg_neg.alpha index 2ffe34a..bae60fa 100644 --- a/tests/sprint4/test/sp4_cg_neg.alpha +++ b/tests/sprint4/test/sp4_cg_neg.alpha @@ -1,6 +1,40 @@ (* TEST: [-asc -tc -cg -ir] *) -#include "std.alpha" +type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer entry (arg) := { [integer:x; integer:y; integer: result] diff --git a/tests/sprint4/test/sp4_cg_not.alpha b/tests/sprint4/test/sp4_cg_not.alpha index 6811471..1fd4ca4 100644 --- a/tests/sprint4/test/sp4_cg_not.alpha +++ b/tests/sprint4/test/sp4_cg_not.alpha @@ -1,6 +1,40 @@ (* TEST: [-asc -tc -cg -ir] *) -#include "std.alpha" +type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer entry (arg) := { [Boolean: c; Boolean: d; integer: result] diff --git a/tests/sprint4/test/sp4_cg_or.alpha b/tests/sprint4/test/sp4_cg_or.alpha index 61392c2..6ecac00 100644 --- a/tests/sprint4/test/sp4_cg_or.alpha +++ b/tests/sprint4/test/sp4_cg_or.alpha @@ -1,6 +1,40 @@ (* TEST: [-asc -tc -cg -ir] *) -#include "std.alpha" +type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer entry (arg) := { [Boolean:b; Boolean: c; Boolean: d; integer: result] diff --git a/tests/sprint4/test/sp4_cg_sub.alpha b/tests/sprint4/test/sp4_cg_sub.alpha index 4b60e57..43420bb 100644 --- a/tests/sprint4/test/sp4_cg_sub.alpha +++ b/tests/sprint4/test/sp4_cg_sub.alpha @@ -1,6 +1,40 @@ (* TEST: [-asc -tc -cg -ir] *) -#include "std.alpha" +type string: 1 -> character +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +type integerXinteger2integer: integerXinteger -> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer entry (arg) := { [integer:x; integer:y; integer: result] From bab71df5172626182581f3cc77edbd1c0641e87c Mon Sep 17 00:00:00 2001 From: Annie Date: Tue, 6 May 2025 15:53:24 -0400 Subject: [PATCH 076/109] hopefully fixed merge --- library/std.alpha | 2 +- src/codegen.c | 188 +++++++++++++++----------- src/codegen.h | 9 +- src/grammar.h | 2 +- src/intermediate_code.c | 4 + tests/given/test/functionValue.alpha | 6 +- tests/sprint4/test/sp4_cg_add.alpha | 4 +- tests/sprint4/test/sp4_cg_calls.alpha | 6 +- 8 files changed, 135 insertions(+), 86 deletions(-) diff --git a/library/std.alpha b/library/std.alpha index 2d0f1a9..19b278a 100644 --- a/library/std.alpha +++ b/library/std.alpha @@ -32,4 +32,4 @@ external function printB: Boolean2integer external function inS: integer2string external function inI: integer2integer -external function inC: integer2character \ No newline at end of file +external function inC: integer2character diff --git a/src/codegen.c b/src/codegen.c index 492d3df..9de14e7 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -3,92 +3,99 @@ #include "codegen.h" int paramCount = 0; +int funDec = 0; int generate() { offset = 0; currentsp = 0; Instruction *i = begin; - + funList = NULL; // temporary fprintf(cg_flag, ".globl entry\n"); while (i != NULL) { switch (getOp(i)) { - case E_LABEL: - generateLabel(i); - break; - case E_ADD: - generateAdd(i); - break; - case E_SUB: - generateSub(i); - break; - case E_MUL: - generateMult(i); - break; - case E_DIV: - generateDiv(i); - break; - case E_MOD: - generateMod(i); - break; - case E_OR: - generateOr(i); - break; - case E_AND: - generateAnd(i); - break; - case E_NEG: - generateNeg(i); - break; - case E_NOT: - generateNot(i); - break; - case E_ASSIGN: - generateAssign(i); - break; - case E_GOTO: - generateGoto(i); - break; - case E_IF_X_TRUE: - generateIfTrue(i); - break; - case E_IF_X_FALSE: - generateIfFalse(i); - break; - case E_LESS_THAN: - generateLessThan(i); - break; - case E_EQUAL_TO: - generateEqualTo(i); - break; - case E_CALL: - generateCall(i); - break; - case E_PARAM: - generateParam(i); - break; - case E_RETURN: - generateReturn(i); - break; - case E_INDEX_COPY_RIGHT: - generateCopyRight(i); - break; - case E_INDEX_COPY_LEFT: - generateCopyLeft(i); - break; - case E_ADDRESS_OF: - generateAddressOf(i); - break; - case E_FUNC_START: - generateFunctionStart(i); - break; - default:; + case E_LABEL: + generateLabel(i); + break; + case E_ADD: + generateAdd(i); + break; + case E_SUB: + generateSub(i); + break; + case E_MUL: + generateMult(i); + break; + case E_DIV: + generateDiv(i); + break; + case E_MOD: + generateMod(i); + break; + case E_OR: + generateOr(i); + break; + case E_AND: + generateAnd(i); + break; + case E_NEG: + generateNeg(i); + break; + case E_NOT: + generateNot(i); + break; + case E_ASSIGN: + generateAssign(i); + break; + case E_GOTO: + generateGoto(i); + break; + case E_IF_X_TRUE: + generateIfTrue(i); + break; + case E_IF_X_FALSE: + generateIfFalse(i); + break; + case E_LESS_THAN: + generateLessThan(i); + break; + case E_EQUAL_TO: + generateEqualTo(i); + break; + case E_CALL: + generateCall(i); + break; + case E_PARAM: + generateParam(i); + break; + case E_RETURN: + generateReturn(i); + break; + case E_INDEX_COPY_RIGHT: + generateCopyRight(i); + break; + case E_INDEX_COPY_LEFT: + generateCopyLeft(i); + break; + case E_ADDRESS_OF: + generateAddressOf(i); + break; + case E_FUNC_START: + generateFunctionStart(i); + break; + case E_FUNC_DEC: + generateFunctionDec(i); + default:; } i = i->next; } return -1; } +void align(TableNode *tn) { + int size = getPrimSize(getTypeEntry(tn)); + offset += offset % size; +} CGNode *getNextCG(CGNode *cg) { if (cg == NULL) { return NULL; @@ -125,6 +132,7 @@ CGNode *findCG(TableNode *tn) { CGNode *addCG(TableNode *tn, int sp) { CGNode *cg = calloc(1, sizeof(CGNode)); cg->tn = tn; + align(tn); offset += getPrimSize(getTypeEntry(tn)); cg->address = offset; cg->next = cgList; @@ -132,6 +140,13 @@ CGNode *addCG(TableNode *tn, int sp) { return cg; } +int generateFunctionDec(Instruction *i) { + FunDecList * fd = calloc(1, sizeof(FunDecList)); + fd->tn = getResult(i); + fd->next = funList; + funList = fd; + return 0; +} int generateLabel(Instruction *inst) { if (inst == NULL) { return -1; @@ -511,7 +526,8 @@ int generateAssign(Instruction *inst) { } int generateGoto(Instruction *inst) { - return -1; + fprintf(cg_flag, "\tjmp\t.L%d\n", getLabel(inst)); + return 0; } int generateCondGoto(Instruction *inst) { @@ -520,7 +536,6 @@ int generateCondGoto(Instruction *inst) { int generateIfTrue(Instruction *inst) { return -1; - // might just be a goto for where to go if something is true, or returning if something is true, or checking if true and writing goto if thats the case } int generateIfFalse(Instruction *inst) { @@ -621,13 +636,18 @@ int generateCall(Instruction *inst) { return -1; } + //if (findCG(getTN(op1)) == NULL) { + // printdebug("generateFunctionCall failed, function not in stack"); + // return -1; + //} // if (getTN(op2) == NULL) { // printdebug("generateFunctionCall failed, NULL tablenode2"); // return -1; //} fprintf(cg_flag, "\tcall %s\n", getName(getTN(op1))); - + //fprintf(cg_flag, "\tmovq\t%d(%%rbp), %%rax\t#call %s!\n", getAddress(findCG(getTN(op1))), getName(getTN(op1))); + //fprintf(cg_flag, "\tcall *%%rax\n"); //now for the return CGNode *cg = findCG(getResult(inst)); @@ -703,6 +723,7 @@ int generateParam(Instruction *inst) { fprintf(cg_flag, "\tmovl\t%d(%%rbp), %s\t#adding param start\n", getAddress(op1CG), REG6); break; default: + align(getTN(op1)); offset += getPrimSize(getTypeEntry(getTN(op1))); fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#adding param start\n", getAddress(op1CG)); fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#adding param end\n", offset - getPrimSize(getTypeEntry(getTN(op1)))); @@ -737,7 +758,8 @@ int generateFunctionStart(Instruction *inst) { TableNode *tnToAdd = getFirstEntry(st); if (getAdInfoType(paramTN) != TYPE_RECORD_TYPE) { CGNode *paramCG = addCG(tnToAdd, offset); - paramOffset += getPrimSize(tnToAdd); + int size = getPrimSize(getTypeEntry(tnToAdd)); + paramOffset += getPrimSize(getTypeEntry(tnToAdd)); fprintf(cg_flag, "\tmovl\t%%edi, %d(%%rbp)\t#FunctionStart1param end\n", getAddress(paramCG)); } else { int numParams = getRecLength(paramTN); @@ -763,7 +785,8 @@ int generateFunctionStart(Instruction *inst) { fprintf(cg_flag, "\tmovl\t%s, %d(%%rbp)\t#FunctionStart1param end\n", REG6, getAddress(paramCG)); break; default: - paramOffset += getPrimSize(getTypeEntry(tnToAdd)); + int size = getPrimSize(getTypeEntry(tnToAdd)); + paramOffset += size; offset += getPrimSize(getTypeEntry(tnToAdd)); fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getAddress(paramCG)); @@ -774,5 +797,18 @@ int generateFunctionStart(Instruction *inst) { } } + if (strcmp(getName(funDecTN), "entry") == 0) { + if (funList == NULL) { + return -1; + } + fprintf(stderr, "here\n"); + TableNode *funDec; + while (funList != NULL) { + funDec = funList->tn; + CGNode *cg = addCG(getResult(inst), offset); + fprintf(cg_flag, "\tmovq\t$%s, %d(%%rbp)\t#storing function declaration\n", getName(funDec), getAddress(cg)); + funList = funList->next; + } + } return 0; } diff --git a/src/codegen.h b/src/codegen.h index bf1d7cd..0667445 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -25,15 +25,21 @@ extern FILE *cg_flag; typedef struct CGNode { TableNode *tn; int address; - CGNode *next; + struct CGNode *next; } CGNode; +typedef struct FunDecList { + TableNode *tn; + struct FunDecList *next; +} FunDecList; + int generate(); CGNode *getNextCG(CGNode *cg); int getAddress(CGNode *cg); TableNode *getTNofCG(CGNode *cg); CGNode *findCG(TableNode *tn); CGNode *addCG(TableNode *tn, int sp); +int generateFunctionDec(Instruction *inst); int generateLabel(Instruction *inst); int generateAdd(Instruction *inst); int generateSub(Instruction *instruction); @@ -66,3 +72,4 @@ extern Instruction *current; extern int offset; extern int currentsp; extern CGNode *cgList; +extern FunDecList *funList; diff --git a/src/grammar.h b/src/grammar.h index ec850a2..94384d8 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -31,7 +31,7 @@ Instruction *current; int offset; int currentsp; CGNode *cgList; - +FunDecList *funList; Stack *stack; Stack *TrueList; Stack *FalseList; diff --git a/src/intermediate_code.c b/src/intermediate_code.c index beccafd..f6d4e9b 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -615,6 +615,10 @@ TableNode *getTN(TNodeOrConst *tnc) { int getConst(TNodeOrConst *tnc) { if (tnc->d == INTEGER) { return tnc->tnc_union->integer; + } else if (tnc->d == CHARACTER) { + return tnc->tnc_union->character; + } else if (tnc->d == BOOLEAN) { + return tnc->tnc_union->Boolean; } return -1; } diff --git a/tests/given/test/functionValue.alpha b/tests/given/test/functionValue.alpha index 8216d9e..aa31fde 100644 --- a/tests/given/test/functionValue.alpha +++ b/tests/given/test/functionValue.alpha @@ -30,7 +30,7 @@ function d: iic2b d(x,y,z) := { [string: s] - return 0; + return true; } function entry: string2int @@ -38,6 +38,7 @@ function entry: string2int a(x) := { [string : s] s := x; + return 0; } @@ -50,7 +51,7 @@ b(x) := { c(x) := { [string: s] s := "Hi!"; - return x(s); + return a(s); } @@ -61,6 +62,7 @@ entry(arg) := { [integer: result; string2int: f; integer: temp] temp := a("Hello"); f := b(temp); + result := f("ahhh"); result := c(f); if (d(1,2,'c')) then { diff --git a/tests/sprint4/test/sp4_cg_add.alpha b/tests/sprint4/test/sp4_cg_add.alpha index 96e2842..1b63c8d 100644 --- a/tests/sprint4/test/sp4_cg_add.alpha +++ b/tests/sprint4/test/sp4_cg_add.alpha @@ -1,5 +1,5 @@ (* TEST: [-asc -tc -cg -ir] *) - + type string: 1 -> character type BooleanXBoolean: [Boolean: x; Boolean: y] type characterXcharacter: [character: x; character: y] @@ -35,7 +35,7 @@ external function inI: integer2integer external function inC: integer2character function entry: string2integer - + entry (arg) := { [integer:x; integer:y; integer: result] diff --git a/tests/sprint4/test/sp4_cg_calls.alpha b/tests/sprint4/test/sp4_cg_calls.alpha index c7beea1..ab70dbc 100644 --- a/tests/sprint4/test/sp4_cg_calls.alpha +++ b/tests/sprint4/test/sp4_cg_calls.alpha @@ -36,7 +36,6 @@ external function inC: integer2character function entry: string2integer - type rec: [integer: x; integer: y; integer: z; integer: a; integer: b; integer: c; integer: d] type T2: rec -> integer type T: integer -> integer @@ -54,8 +53,9 @@ bar (a, b, c,d,e,f,g) := { } entry (arg) := { - [integer:x; integer:y; integer: result] - + [integer:x; integer:y; integer: result; character: a] + a := 'a'; + x := printCharacter(a); result := bar(1,2,3,4,5,6,7); return 1; } From a459cb11120300f50ea4b53c932850dc949e4586 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Tue, 6 May 2025 10:07:13 -0400 Subject: [PATCH 077/109] I believe that the backpatching before the and and or are wrong --- src/grammar.y | 13 ++++++++----- tests/sprint3/test/sp3_if_else.alpha | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 3d7db57..104653f 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -617,6 +617,7 @@ compound_statement: emit_goto(*(int*)(S_Pop(stack))); emit_label(l); } + // IF L_PAREN expression R_PAREN THEN sblock ELSE sblock | IF L_PAREN { S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); @@ -680,7 +681,9 @@ simple_statement: } ASSIGN expression { // ---------------------------------------------------------------------------- - emit_label(label_gen()); + if ( getTypeEntry((TableNode*)$4) == boo ) { + emit_label(label_gen()); + } emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_backpatch(S_Pop(FalseList), getLabel(current)); // ---------------------------------------------------------------------------- @@ -921,8 +924,8 @@ expression: // ---------------------------------------------------------------------------- uint_least8_t b = 0; emit_assignment(node, tn_or_const(BOOLEAN,&b)); - emit_label(label_gen()); - emit_backpatch(S_Pop(TrueList), getLabel(current)); + // emit_label(label_gen()); + // emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_conditional_jump(E_IF_X_FALSE, 0, tn_or_const(NODE, $1)); Stack * t1 = S_Peek(FalseList); if(t1==NULL){ @@ -974,8 +977,8 @@ expression: // ---------------------------------------------------------------------------- uint_least8_t b = 1; emit_assignment(node, tn_or_const(BOOLEAN,&b)); - emit_label(label_gen()); - emit_backpatch(S_Pop(TrueList), getLabel(current)); + // emit_label(label_gen()); + // emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $1)); Stack * t1 = S_Peek(TrueList); if(t1==NULL){ diff --git a/tests/sprint3/test/sp3_if_else.alpha b/tests/sprint3/test/sp3_if_else.alpha index 40c2580..6825b77 100644 --- a/tests/sprint3/test/sp3_if_else.alpha +++ b/tests/sprint3/test/sp3_if_else.alpha @@ -13,8 +13,8 @@ bar (r,s) := { entry (arg) := { [ integer: r ; integer: s; Boolean: x] - x := (r < s) & x; - if ( r < s ) then { + (* x := (r < s) & x; *) + if ( ( r < s ) & (s = r) ) then { r := 5; } else { r := 7; From 88511ac0e6b22813014f0f153088ba3c6a3f1ff2 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Tue, 6 May 2025 15:49:31 -0400 Subject: [PATCH 078/109] I added some changes to make offsets work --- src/grammar.y | 8 ++++---- src/intermediate_code.c | 15 +++++++++++---- src/intermediate_code.h | 2 +- src/symbol_table.h | 4 +++- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 104653f..a94f5dd 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1466,8 +1466,10 @@ assignable: TableNode* node = CreateEntry(cur,t, type, temp, NULL); // getElementOffset(rec, ID) - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //emit_field_access(char* node, char* record, $3) + // NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + // emit_field_access(char* node, char* record, $3) + int n = getElementOffset(getTypeEntry((TableNode*)$1), $3); + emit_field_access(node, tn_or_const(NODE, $1), n); $$=node; }else{ throw_error(ERROR_TYPE, "Invalid field access %s", $3); @@ -1475,8 +1477,6 @@ assignable: } printdebug("[ASSIGNABLE - RULE 3] record = name: %s | field = %s", getName((TableNode*)($1)), getName((TableNode*)$3)); } - - ; diff --git a/src/intermediate_code.c b/src/intermediate_code.c index f6d4e9b..e8e065c 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -345,8 +345,12 @@ void emit_address_of(TableNode *x, TNodeOrConst *y) { current->operand1 = y; } -void emit_field_access(char *result, char *record, char *field) { +void emit_field_access(TableNode *result, TNodeOrConst *record, int offset){ emit_helper(); + current->opcode = E_DEREF_RIGHT; + current->result = result; + current->operand1 = record; + current->operand2 = tn_or_const(INTEGER, &offset); } void emit_array_access(Op op, TableNode *result, TNodeOrConst *array, TNodeOrConst *index) { @@ -587,19 +591,22 @@ void emit_as_file(FILE *out_file, Instruction *i) { getName(i->result), get_string(i->operand1)); break; - case E_DEREF_RIGHT: fprintf(out_file, - "%4.d: %s = *%s\n", + "%4.d: %s = *((char * )%s + %s)\n", i->index, getName(i->result), - get_string(i->operand1)); + get_string(i->operand1), + get_string(i->operand2) + ); + break; case E_DEREF_LEFT: fprintf(out_file, "%4.d: *%s = %s\n", i->index, getName(i->result), get_string(i->operand1)); + break; } emit_as_file(out_file, i->next); diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 5f50828..87e3123 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -143,7 +143,7 @@ void emit_function_dec(TableNode * name); void emit_return(TNodeOrConst *value); void emit_reserve(TableNode *result, TNodeOrConst *size); void emit_release(TableNode *pointer); -void emit_field_access(char *result, char *record, char *field); +void emit_field_access(TableNode *result, TNodeOrConst *record, int offset); 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); diff --git a/src/symbol_table.h b/src/symbol_table.h index 2a8abb5..5feb46c 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -161,6 +161,8 @@ ListOfTable *getRestOfChildren(ListOfTable *lt); TableNode *getFirstEntry(SymbolTable *st); TableNode *getNextEntry(TableNode *tn); TableNode *printTableNode(TableNode *tn); +int getElementOffset(TableNode *rec, char* id); +int getRecPosition(TableNode* rec, char* id); extern int yylex(void); extern char *yytext; @@ -199,4 +201,4 @@ extern char *COLOR_YELLOW; extern char *COLOR_LIGHTBLUE; extern char *COLOR_LIGHTPURPLE; extern char *COLOR_LIGHTCYAN; -extern char *COLOR_WHITE; \ No newline at end of file +extern char *COLOR_WHITE; From 5e0d2e3cdff17d331f219b419fa4b03b44710bf8 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Tue, 6 May 2025 16:16:56 -0400 Subject: [PATCH 079/109] Neet --- src/intermediate_code.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/intermediate_code.c b/src/intermediate_code.c index e8e065c..2145ea3 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -190,7 +190,8 @@ void emit_binary_op( Op op, TableNode *result, TNodeOrConst *arg1, - TNodeOrConst *arg2) { + TNodeOrConst *arg2 + ) { emit_helper(); current->opcode = op; // TODO: create temp and remove result from param list From a7e10521d8e6c881f746de0a5d198053af254b8b Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 16:42:22 -0400 Subject: [PATCH 080/109] this --- src/codegen.c | 2 +- src/codegen.h | 1 + src/symbol_table.c | 49 +++++++++++++++++++++++++++++++---------- src/symbol_table.h | 2 ++ tests/programs/io.alpha | 2 -- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 9de14e7..88a2ab1 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -744,7 +744,7 @@ int generateFunctionStart(Instruction *inst) { fprintf(cg_flag, "%s:\n", getName(funDecTN)); fprintf(cg_flag, "\tpushq\t%%rbp\n"); fprintf(cg_flag, "\tmovq\t%%rsp, %%rbp\n"); - fprintf(cg_flag, "\tsubq\t$%d, %%rsp\n", 128); // [CHANGE ME] 128 is a placeholder for the stack size + fprintf(cg_flag, "\tsubq\t$%d, %%rsp\n", getStackSize()); //now we need to add the CGs of nodes to the CG list by doing assign from the // have function declararation node diff --git a/src/codegen.h b/src/codegen.h index 0667445..d790ea9 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -68,6 +68,7 @@ int generateFunctionStart(Instruction *instruction); extern int label_count; extern Instruction *begin; extern Instruction *current; +extern SymbolTable *top; extern int offset; extern int currentsp; diff --git a/src/symbol_table.c b/src/symbol_table.c index 50c2a39..9f81805 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -462,7 +462,7 @@ int getRecSize(SymbolTable *tn) { } return -1; } -int getRecPosition(TableNode* rec, char* id){ +int getRecPosition(TableNode *rec, char *id) { if (rec == NULL) { printdebug( "passed a NULL entry to getRecPosition. Invalid."); @@ -478,25 +478,25 @@ int getRecPosition(TableNode* rec, char* id){ "not checking the position of a record -- invalid op"); return -1; } - TableNode* cur = getFirstEntry(getRecList(rec)); + TableNode *cur = getFirstEntry(getRecList(rec)); int i = 1; - while(cur != NULL){ - if(strcmp(getName(cur), id) == 0){ + while (cur != NULL) { + if (strcmp(getName(cur), id) == 0) { return i; } cur = getNextEntry(cur); i++; } - if (cur == NULL){ + if (cur == NULL) { printdebug( "passed an invalid entry to getRecPosition. Invalid."); return -1; - }else{ - return i; + } else { + return i; } } -int getElementOffset(TableNode *rec, char* id) { +int getElementOffset(TableNode *rec, char *id) { if (rec == NULL) { printdebug( "passed a NULL entry to getElementOffset. Invalid."); @@ -512,7 +512,7 @@ int getElementOffset(TableNode *rec, char* id) { "not checking the offset of a record -- invalid op"); return -1; } - int* offsets = getRecOffsets(rec); + int *offsets = getRecOffsets(rec); int position = getRecPosition(rec, id); if (position == -1) { printdebug( @@ -522,11 +522,11 @@ int getElementOffset(TableNode *rec, char* id) { position = position - 1; int total_offset = 0; int current_position = 1; - while(current_position < position+1){ + while (current_position < position + 1) { //adding current element in struct - total_offset += offsets[2*current_position]; + total_offset += offsets[2 * current_position]; //adding padding between elements - total_offset += offsets[2*current_position+1]; + total_offset += offsets[2 * current_position + 1]; current_position++; } //returning the offset of the start of the element @@ -1739,3 +1739,28 @@ TableNode *printTableNode(TableNode *tn) { return tn; } + +int getStackSize() { + int i = 0; + TableNode *tn = getFirstEntry(top); + while (tn != NULL) { + i++; + tn = getNextEntry(tn); + } + + ListOfTable *lt = getChildren(top); + while (lt != NULL) { + TableNode *first = lt->table->entries; + while (first != NULL) { + i++; + first = getNextEntry(first); + } + + lt = lt->next; + } + + i= i * 8; + if (i % 16 != 0) i += 8; + + return i; +} \ No newline at end of file diff --git a/src/symbol_table.h b/src/symbol_table.h index 5feb46c..e6da226 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -163,12 +163,14 @@ TableNode *getNextEntry(TableNode *tn); TableNode *printTableNode(TableNode *tn); int getElementOffset(TableNode *rec, char* id); int getRecPosition(TableNode* rec, char* id); +int getStackSize(); extern int yylex(void); extern char *yytext; extern int yyleng; extern int yychar; extern SymbolTable *cur; +extern SymbolTable *top; extern int line_number; extern int column_number; extern FILE *yyin; diff --git a/tests/programs/io.alpha b/tests/programs/io.alpha index 45b387f..eac7b03 100644 --- a/tests/programs/io.alpha +++ b/tests/programs/io.alpha @@ -5,8 +5,6 @@ function entry: string2integer entry (arg) := { [integer: x; string: s; character: c; integer: result] - result := printS("hello world"); - s := inS(1); result := printS(s); From 8bba742c99d95435534cce487cecf027d4668cbd Mon Sep 17 00:00:00 2001 From: Annie Date: Tue, 6 May 2025 16:44:26 -0400 Subject: [PATCH 081/109] please dont break --- src/codegen.c | 32 ++++++++++++++++++++++++++++++-- tests/programs/fib.alpha | 5 +++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 88a2ab1..acbf76d 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -535,11 +535,39 @@ int generateCondGoto(Instruction *inst) { } int generateIfTrue(Instruction *inst) { - return -1; + TNodeOrConst *op1 = getOperand1(inst); + + if (op1 == NULL) { + printdebug("%sgenerateIfTrue failed, NULL operand", COLOR_RED); + return -1; + } + + CGNode *cg = findCG(getTN(op1)); + if (cg == NULL) { + printdebug("generateIfTrue failed, operand not on stack"); + return -1; + } + + fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#if true start\n", getAddress(cg)); + fprintf(cg_flag, "\tjne\t.L%d\t\t#if true end\n", getLabel(inst)); } int generateIfFalse(Instruction *inst) { - return -1; + TNodeOrConst *op1 = getOperand1(inst); + + if (op1 == NULL) { + printdebug("%sgenerateIfFalse failed, NULL operand", COLOR_RED); + return -1; + } + + CGNode *cg = findCG(getTN(op1)); + if (cg == NULL) { + printdebug("generateIfFalse failed, operand not on stack"); + return -1; + } + + fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#if false start\n", getAddress(cg)); + fprintf(cg_flag, "\tje\t.L%d\t\t#if false end\n", getLabel(inst)); } int generateLessThan(Instruction *inst) { diff --git a/tests/programs/fib.alpha b/tests/programs/fib.alpha index 9ebef58..37a86c8 100644 --- a/tests/programs/fib.alpha +++ b/tests/programs/fib.alpha @@ -12,9 +12,10 @@ Fib(i) := { } else { i := i; } - b := b | (a & c); - b := 2 < 3; + (*b := b | (a & c); + b := 2 < 3;*) if(i = 1) then { + i := printCharacter('a'); return 1; } else { return i + Fib(i - 1); From 0a5b6ee7fba6bc1ce2b6d0a82817ca19afc2afb3 Mon Sep 17 00:00:00 2001 From: Annie Date: Tue, 6 May 2025 17:34:00 -0400 Subject: [PATCH 082/109] ifs work --- src/codegen.c | 3 ++- src/intermediate_code.c | 2 ++ tests/programs/fib.alpha | 28 ++++++++++++++++++---------- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index acbf76d..3393217 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -548,7 +548,7 @@ int generateIfTrue(Instruction *inst) { return -1; } - fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#if true start\n", getAddress(cg)); + fprintf(cg_flag, "\tcmpb\t$0, %d(%%rbp)\t#if true start\n", getAddress(cg)); fprintf(cg_flag, "\tjne\t.L%d\t\t#if true end\n", getLabel(inst)); } @@ -642,6 +642,7 @@ int generateEqualTo(Instruction *inst) { 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$0, %d(%%rbp)\n", getAddress(cg)); fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#equal to end\n", getAddress(cg)); return 0; } diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 2145ea3..4bbac3e 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -627,6 +627,8 @@ int getConst(TNodeOrConst *tnc) { return tnc->tnc_union->character; } else if (tnc->d == BOOLEAN) { return tnc->tnc_union->Boolean; + } else if (tnc->d == ADDRESS) { + return 0; } return -1; } diff --git a/tests/programs/fib.alpha b/tests/programs/fib.alpha index 37a86c8..9105a9a 100644 --- a/tests/programs/fib.alpha +++ b/tests/programs/fib.alpha @@ -6,26 +6,34 @@ function entry : string2integer function Fib : integer2integer Fib(i) := { - [ Boolean: a ; Boolean: b ; Boolean: c] - if( i = 0 ) then { + [integer: a; integer: b ; Boolean: d ; integer: c] + (*if( i = 0 ) then { return 7; } else { i := i; - } + }*) (*b := b | (a & c); b := 2 < 3;*) - if(i = 1) then { - i := printCharacter('a'); - return 1; - } else { - return i + Fib(i - 1); + + (* `if(i = 1) then { return 1; } else { + return Fib(i - 1) + Fib(i - 2); } +*) + + a := 0; + b := 1; + while(0 < i) { + c := a + b; + a := b; + b := c; + } + return c; } entry (arg) := { [ integer: x; integer: y ] x := 2; - x := Fib(2); - y := printInteger(Fib(2)); +(* x := Fib(2);*) + y := printInteger(Fib(3)); return 1; } From 96cb2d7a0947a1075c65a786838cc80636d95972 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 17:34:10 -0400 Subject: [PATCH 083/109] we fixed this woooo --- genx.sh | 2 +- src/lexicalStructure.lex | 35 ++++++++++++++++++++++++++++++++++- tests/programs/io.alpha | 13 +++++++++++-- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/genx.sh b/genx.sh index 7025bd0..aa11527 100755 --- a/genx.sh +++ b/genx.sh @@ -193,7 +193,7 @@ if [ $# -eq 1 ]; then getIncludes "$1" appendStr "$1" - ./alpha -ir -tc -asc -cg -st "$1" + ./alpha -ir -tc -asc -cg -st -tok "$1" # include a grep here of asc to see if there are any errors diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index a8bd8af..8413ca3 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -58,7 +58,24 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "->" { if(tok_flag != NULL) {print_tok(ARROW);} incr(line_number,column_number,ARROW); return ARROW; } {DIGIT}+ {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.integ = atoi(yytext)/*words = strdup("integer")*/;return C_INTEGER;} -'{CHAR}' {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);char* token = strdup(yytext)/*yylval.tn = chara*/;yylval.letter = token[1];return C_CHARACTER;} + + +'{CHAR}' { + if (tok_flag) print_tok(C_CHARACTER); + incr(line_number, column_number, C_CHARACTER); + + int value; + if (strcmp(yytext, "'\\n'") == 0) value = 0x0A; + else if (strcmp(yytext, "'\\t'") == 0) value = 0x09; + else if (strcmp(yytext, "'\\''") == 0) value = 0x27; + else if (strcmp(yytext, "'\\\\'") == 0) value = 0x5C; + else value = yytext[1]; + + yylval.letter = value; + return C_CHARACTER; +} + + \"{SCHAR}*\" {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);int k = strlen(yytext);yytext[k-1] = '\0';yylval.words = strdup(&yytext[1]);return C_STRING;} {COMMENT} {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/} _{DIGIT}+ {if(tok_flag != NULL){print_tok(ACCESS);}incr(line_number,column_number,ACCESS);yylval.integ = atoi(&yytext[1])/*words = strdup("integer")*/;return ACCESS;} @@ -81,3 +98,19 @@ _{DIGIT}+ {if(tok_flag != NULL){print_tok(ACCESS);}incr(line_number,colum . { incr(line_number,column_number,0); } %% + +int decode_escape_char(const char *t) { + switch (*t) { + case 'n': + return 0x0A; // \n + case 't': + return 0x09; // \t + case '\\': + return 0x5C; // \\\ + case '\'': + return 0x27; // \' + default: + fprintf(stderr, "(%d:%d) ** LEX ERROR: unknown escape \\%c\n", yylineno, yycolumn, *t); + exit(EXIT_FAILURE); + } +} \ No newline at end of file diff --git a/tests/programs/io.alpha b/tests/programs/io.alpha index eac7b03..ddfb00e 100644 --- a/tests/programs/io.alpha +++ b/tests/programs/io.alpha @@ -5,14 +5,23 @@ function entry: string2integer entry (arg) := { [integer: x; string: s; character: c; integer: result] - s := inS(1); + result := printCharacter('\t'); + result := printCharacter('t'); + result := printCharacter('a'); + result := printCharacter('b'); + result := printCharacter('\n'); + result := printCharacter('\\'); + result := printCharacter('"'); + result := printCharacter('\''); + + (*s := inS(1); result := printS(s); x := inI(1); result := printI(x); c := inC(1); - result := printC(c); + result := printC(c);*) return 0; } \ No newline at end of file From 31db445afd9c7a0a0b6d3fbc7252598092c98f3c Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 17:34:35 -0400 Subject: [PATCH 084/109] wooo --- src/lexicalStructure.lex | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index 8413ca3..bbcacd8 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -63,7 +63,7 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] '{CHAR}' { if (tok_flag) print_tok(C_CHARACTER); incr(line_number, column_number, C_CHARACTER); - +0 int value; if (strcmp(yytext, "'\\n'") == 0) value = 0x0A; else if (strcmp(yytext, "'\\t'") == 0) value = 0x09; @@ -97,20 +97,4 @@ _{DIGIT}+ {if(tok_flag != NULL){print_tok(ACCESS);}incr(line_number,colum " " { incr(line_number,column_number,0); } . { incr(line_number,column_number,0); } -%% - -int decode_escape_char(const char *t) { - switch (*t) { - case 'n': - return 0x0A; // \n - case 't': - return 0x09; // \t - case '\\': - return 0x5C; // \\\ - case '\'': - return 0x27; // \' - default: - fprintf(stderr, "(%d:%d) ** LEX ERROR: unknown escape \\%c\n", yylineno, yycolumn, *t); - exit(EXIT_FAILURE); - } -} \ No newline at end of file +%% \ No newline at end of file From d6803874f9ecabc994dfa4bd6b71f356475d0bfa Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 17:35:19 -0400 Subject: [PATCH 085/109] yes --- src/lexicalStructure.lex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index bbcacd8..a8f4474 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -63,7 +63,7 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] '{CHAR}' { if (tok_flag) print_tok(C_CHARACTER); incr(line_number, column_number, C_CHARACTER); -0 + int value; if (strcmp(yytext, "'\\n'") == 0) value = 0x0A; else if (strcmp(yytext, "'\\t'") == 0) value = 0x09; From a57aaf764a744e4139e84ee9dc56ec2c221bd665 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 18:10:06 -0400 Subject: [PATCH 086/109] =?UTF-8?q?factorial=20=F0=9F=A6=96=F0=9F=A6=96?= =?UTF-8?q?=F0=9F=A6=96=F0=9F=A6=96=F0=9F=A6=96=F0=9F=A6=96=F0=9F=A6=96?= =?UTF-8?q?=F0=9F=A6=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/programs/factorial.alpha | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/programs/factorial.alpha diff --git a/tests/programs/factorial.alpha b/tests/programs/factorial.alpha new file mode 100644 index 0000000..4f02932 --- /dev/null +++ b/tests/programs/factorial.alpha @@ -0,0 +1,42 @@ +#include "std.alpha" + +function entry: string2integer +function calc: integerXinteger2integer + +calc(counter, result) := { + + if ( counter = 0 ) then { + return result; + } else { + result := result * counter; + counter := counter - 1; + return calc(counter, result); + } +} + + + +entry (arg) := { + [integer: result; integer: userInput] + + result := printC('E'); + result := printC('n'); + result := printC('t'); + result := printC('e'); + result := printC('r'); + result := printC(' '); + result := printC('N'); + result := printC('u'); + result := printC('m'); + result := printC('b'); + result := printC('e'); + result := printC('r'); + result := printC(':'); + result := printC(' '); + + userInput := inI(1); + userInput := calc(userInput, 1); + result := printI(userInput); + + return 0; +} \ No newline at end of file From 44f0e0f5af4a769eee227b77789d5cd48199e346 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 18:24:43 -0400 Subject: [PATCH 087/109] =?UTF-8?q?=F0=9F=AA=83=F0=9F=AA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- genx.sh | 1 + library/boundscheck.c | 23 +++++++++ library/boundscheck.s | 112 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 library/boundscheck.c create mode 100644 library/boundscheck.s diff --git a/genx.sh b/genx.sh index aa11527..a1a9bd4 100755 --- a/genx.sh +++ b/genx.sh @@ -26,6 +26,7 @@ cToBuild=() sToInclude+=("library/alpha_lib_reg.s") sToInclude+=("library/alpha_driver.s") sToInclude+=("library/std.s") +sToInclude+=("library/boundscheck.s") filename="" s_name="" diff --git a/library/boundscheck.c b/library/boundscheck.c new file mode 100644 index 0000000..5e6081c --- /dev/null +++ b/library/boundscheck.c @@ -0,0 +1,23 @@ +#include +#include +#include + +int BoundsError(int d){ + printf("You are trying to access memory that isn't yours.\n"); + exit(1); +} + +void BoundsCheck(int argc, void * start, ...){ + va_list argptr; + va_start(argptr, start); + int index = 0; + while (argc){ + argc--; + index = va_arg(argptr, int); + if(index > *(int*)start){ + BoundsError(index); + } + start += sizeof(int); + } + va_end(argptr); +} \ No newline at end of file diff --git a/library/boundscheck.s b/library/boundscheck.s new file mode 100644 index 0000000..36fa414 --- /dev/null +++ b/library/boundscheck.s @@ -0,0 +1,112 @@ + .file "boundscheck.c" + .text + .section .rodata + .align 8 +.LC0: + .string "You are trying to access memory that isn't yours." + .text + .globl BoundsError + .type BoundsError, @function +BoundsError: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + leaq .LC0(%rip), %rax + movq %rax, %rdi + call puts@PLT + movl $1, %edi + call exit@PLT + .cfi_endproc +.LFE6: + .size BoundsError, .-BoundsError + .globl BoundsCheck + .type BoundsCheck, @function +BoundsCheck: +.LFB7: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $240, %rsp + movl %edi, -228(%rbp) + movq %rsi, -240(%rbp) + movq %rdx, -160(%rbp) + movq %rcx, -152(%rbp) + movq %r8, -144(%rbp) + movq %r9, -136(%rbp) + testb %al, %al + je .L3 + movaps %xmm0, -128(%rbp) + movaps %xmm1, -112(%rbp) + movaps %xmm2, -96(%rbp) + movaps %xmm3, -80(%rbp) + movaps %xmm4, -64(%rbp) + movaps %xmm5, -48(%rbp) + movaps %xmm6, -32(%rbp) + movaps %xmm7, -16(%rbp) +.L3: + movq %fs:40, %rax + movq %rax, -184(%rbp) + xorl %eax, %eax + movl $16, -208(%rbp) + movl $48, -204(%rbp) + leaq 16(%rbp), %rax + movq %rax, -200(%rbp) + leaq -176(%rbp), %rax + movq %rax, -192(%rbp) + movl $0, -212(%rbp) + jmp .L4 +.L8: + subl $1, -228(%rbp) + movl -208(%rbp), %eax + cmpl $47, %eax + ja .L5 + movq -192(%rbp), %rax + movl -208(%rbp), %edx + movl %edx, %edx + addq %rdx, %rax + movl -208(%rbp), %edx + addl $8, %edx + movl %edx, -208(%rbp) + jmp .L6 +.L5: + movq -200(%rbp), %rax + leaq 8(%rax), %rdx + movq %rdx, -200(%rbp) +.L6: + movl (%rax), %eax + movl %eax, -212(%rbp) + movq -240(%rbp), %rax + movl (%rax), %eax + cmpl %eax, -212(%rbp) + jle .L7 + movl -212(%rbp), %eax + movl %eax, %edi + call BoundsError +.L7: + addq $4, -240(%rbp) +.L4: + cmpl $0, -228(%rbp) + jne .L8 + nop + movq -184(%rbp), %rax + subq %fs:40, %rax + je .L9 + call __stack_chk_fail@PLT +.L9: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size BoundsCheck, .-BoundsCheck + .ident "GCC: (GNU) 14.2.1 20250207" + .section .note.GNU-stack,"",@progbits From 63becc9c1a4ac3b9b283cbc35673c044932a3d4e Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 18:47:18 -0400 Subject: [PATCH 088/109] hello. can u hear me. --- tests/programs/helloworld.alpha | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tests/programs/helloworld.alpha b/tests/programs/helloworld.alpha index 109cae8..c889222 100644 --- a/tests/programs/helloworld.alpha +++ b/tests/programs/helloworld.alpha @@ -1,11 +1,23 @@ #include "std.alpha" -entry (arg) := { - [string: str; character: ch; integer: result] +function entry: string2integer - ch := 'h'; - str := "Hello World!"; - result := printCharacter(ch); +entry (arg) := { + [integer: result] + + result := printCharacter('H'); + result := printCharacter('e'); + result := printCharacter('l'); + result := printCharacter('l'); + result := printCharacter('o'); + result := printCharacter(' '); + result := printCharacter('W'); + result := printCharacter('o'); + result := printCharacter('r'); + result := printCharacter('l'); + result := printCharacter('d'); + result := printCharacter('!'); + result := printCharacter('\n'); return 0; } \ No newline at end of file From d340a05b61b6cfd7f4d5c24eae1f44f7ec862aa0 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 19:10:18 -0400 Subject: [PATCH 089/109] fib --- tests/programs/fib.alpha | 84 ++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/tests/programs/fib.alpha b/tests/programs/fib.alpha index 9105a9a..bbc20f9 100644 --- a/tests/programs/fib.alpha +++ b/tests/programs/fib.alpha @@ -1,39 +1,63 @@ -(* TEST: [-asc -tc -cg -ir] *) - #include "std.alpha" function entry : string2integer -function Fib : integer2integer +function fib : integer2integer -Fib(i) := { - [integer: a; integer: b ; Boolean: d ; integer: c] - (*if( i = 0 ) then { - return 7; - } else { - i := i; - }*) - (*b := b | (a & c); - b := 2 < 3;*) - - (* `if(i = 1) then { return 1; } else { - return Fib(i - 1) + Fib(i - 2); - } -*) +fib(i) := { + [ integer: a; integer: b; integer: count ] + + a := 1; + b := 2; - a := 0; - b := 1; - while(0 < i) { - c := a + b; - a := b; - b := c; - } - return c; + if (i = 0) then { + return 0; + } else { + a := a; + } + + if (i = 1) then { + return 1; + } else { + a := a; + } + + if (i = 2) then { + return 2; + } else { + a := a; + } + + count := 2; + while (count < i) { + + count := count + 1; + } + + return b; } entry (arg) := { - [ integer: x; integer: y ] - x := 2; -(* x := Fib(2);*) - y := printInteger(Fib(3)); - return 1; + [ integer: result; integer: input; integer: fibValue] + + result := printC('E'); + result := printC('n'); + result := printC('t'); + result := printC('e'); + result := printC('r'); + result := printC(' '); + result := printC('N'); + result := printC('u'); + result := printC('m'); + result := printC('b'); + result := printC('e'); + result := printC('r'); + result := printC(':'); + result := printC(' '); + + input := inI(1); + fibValue := fib(input); + + result := printI(fibValue); + + return 0; } From 17d6f50904caf8d1557ad89d69add8dc2945492c Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 19:21:35 -0400 Subject: [PATCH 090/109] fib --- tests/programs/fib.alpha | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/tests/programs/fib.alpha b/tests/programs/fib.alpha index bbc20f9..287614b 100644 --- a/tests/programs/fib.alpha +++ b/tests/programs/fib.alpha @@ -4,36 +4,20 @@ function entry : string2integer function fib : integer2integer fib(i) := { - [ integer: a; integer: b; integer: count ] - - a := 1; - b := 2; - if (i = 0) then { + if (i < 1) then { return 0; } else { - a := a; + i := i; } - if (i = 1) then { - return 1; + if (i < 2) then { + return i; } else { - a := a; + i := i; } - if (i = 2) then { - return 2; - } else { - a := a; - } - - count := 2; - while (count < i) { - - count := count + 1; - } - - return b; + return fib(i-1) + fib(i-2); } entry (arg) := { From 05b347ba6324720f5cbbe419d616ad5dfb7d6f29 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Tue, 6 May 2025 17:34:46 -0400 Subject: [PATCH 091/109] Hello --- src/intermediate_code.c | 2 +- src/intermediate_code.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 4bbac3e..3a473a1 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -316,7 +316,7 @@ void emit_return(TNodeOrConst *value) { void emit_reserve(TableNode *result, TNodeOrConst *size) { // this needs to change // we need to take a int - emit_parameter(size); + emit_binary_op(E_MUL, result, emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); } diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 87e3123..67c6346 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -49,7 +49,7 @@ typedef enum { // these are from page 364 E_SUB, // 1 E_MUL, // 1 E_DIV, // 1 - E_MOD, // 1 TODO: Please change to REM + E_MOD, // 1 E_OR, // 1 E_AND, // 1 E_NEG, // 2 From 8c409561b73593a2de04fbf9ed32f6522a7991d5 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Tue, 6 May 2025 19:35:49 -0400 Subject: [PATCH 092/109] I made a rebase --- src/grammar.y | 7 +++++-- src/intermediate_code.c | 3 +++ src/symbol_table.c | 4 ++-- tests/programs/fib.alpha | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index a94f5dd..ccdd9da 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -608,6 +608,9 @@ compound_statement: emit_label(*l); S_Push(stack, l, 2); } expression R_PAREN { + emit_conditional_jump(E_IF_X_FALSE, 0, tn_or_const(NODE, $4)); + Stack * t = S_Peek(FalseList); + S_Push(t, current, 1); emit_label(label_gen()); emit_backpatch(S_Pop(TrueList), getLabel(current)); } sblock { @@ -1030,7 +1033,6 @@ expression: // emit_label(label_gen()); // emit_backpatch(S_Pop(TrueList), getLabel(current)); emit_binary_op(E_LESS_THAN, node, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); - /* emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); if(t==NULL){ @@ -1045,6 +1047,7 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); + /* */ // ---------------------------------------------------------------------------- printdebug("less than expression"); @@ -1064,7 +1067,6 @@ expression: 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_IF_X_TRUE, 0, tn_or_const(NODE, node)); Stack * t = S_Peek(TrueList); if(t==NULL){ @@ -1079,6 +1081,7 @@ expression: S_Push(FalseList, t, 1); } S_Push(t, current, 1); + /* */ // emit_label(label_gen()); // emit_backpatch(S_Pop(TrueList), getLabel(current)); diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 3a473a1..618fbba 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -316,7 +316,10 @@ void emit_return(TNodeOrConst *value) { void emit_reserve(TableNode *result, TNodeOrConst *size) { // this needs to change // we need to take a int + /* emit_binary_op(E_MUL, result, + */ + emit_parameter(size); emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); } diff --git a/src/symbol_table.c b/src/symbol_table.c index 9f81805..2f2e8ac 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1489,7 +1489,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if ((getFirstChild(node)) == NULL) { print_symbol_table(getFirstChild(node), file_ptr); } else { - if (getLine(getFirstChild(node)) < 0) { + if (getLine(getFirstChild(node)) < -3) { continue; } else { print_symbol_table(getFirstChild(node), file_ptr); @@ -1763,4 +1763,4 @@ int getStackSize() { if (i % 16 != 0) i += 8; return i; -} \ No newline at end of file +} diff --git a/tests/programs/fib.alpha b/tests/programs/fib.alpha index 287614b..1a9d185 100644 --- a/tests/programs/fib.alpha +++ b/tests/programs/fib.alpha @@ -40,7 +40,7 @@ entry (arg) := { input := inI(1); fibValue := fib(input); - + result := printI(fibValue); return 0; From 666d924608c9c9dba3d007035adefd7517d60ee6 Mon Sep 17 00:00:00 2001 From: Annie Date: Tue, 6 May 2025 20:32:57 -0400 Subject: [PATCH 093/109] YIPPEE --- src/codegen.c | 66 +++++++++++++++++++++++++++++++++++---------------- src/codegen.h | 1 + 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 3393217..1784a09 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -92,6 +92,18 @@ int generate() { return -1; } +bool isAnActualFunction(TableNode *tn) { + FunDecList *fdl = funList; + while (fdl != NULL) { + printf("%s %s, %s %s\n", getName(fdl->tn), getType(fdl->tn), getName(tn), getType(tn)); + if (tn == fdl->tn) { + return true; + } + fdl = fdl ->next; + } + return false; +} + void align(TableNode *tn) { int size = getPrimSize(getTypeEntry(tn)); offset += offset % size; @@ -142,6 +154,9 @@ CGNode *addCG(TableNode *tn, int sp) { int generateFunctionDec(Instruction *i) { FunDecList * fd = calloc(1, sizeof(FunDecList)); + CGNode *cg = addCG(getResult(i),offset); +// printf("%d\n", getAddress(cg)+currentsp); + offset += 8; fd->tn = getResult(i); fd->next = funList; funList = fd; @@ -519,9 +534,13 @@ int generateAssign(Instruction *inst) { printdebug("generateAssign failed, %s is not constant but not in CGlist", getName(getTN(op1))); return -1; } - - 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)); + if (getAdInfoType(getTN(op1)) != TYPE_FUNCTION_DECLARATION || !isAnActualFunction(getTN(op1))){ + 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)); + } else { + fprintf(cg_flag, "\tmovl\t$%s,%%eax\t#assign function\n", getName(getTN(op1))); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#assign function end\n", getAddress(cg)); + } return 0; } @@ -665,21 +684,24 @@ int generateCall(Instruction *inst) { return -1; } - //if (findCG(getTN(op1)) == NULL) { - // printdebug("generateFunctionCall failed, function not in stack"); - // return -1; - //} - // if (getTN(op2) == NULL) { - // printdebug("generateFunctionCall failed, NULL tablenode2"); - // return -1; - //} - - fprintf(cg_flag, "\tcall %s\n", getName(getTN(op1))); - //fprintf(cg_flag, "\tmovq\t%d(%%rbp), %%rax\t#call %s!\n", getAddress(findCG(getTN(op1))), getName(getTN(op1))); - //fprintf(cg_flag, "\tcall *%%rax\n"); + if (table_lookup(getAncestor(cur),getName(getTN(op1)))!=undefined) { + fprintf(cg_flag, "\tcall %s\n", getName(getTN(op1))); + } else { + // printf("%s\n", getName(getTN(op1))); + if (findCG(getTN(op1)) == NULL) { + //printf("generateFunctionCall failed, function not in stack"); + return -1; + } + fprintf(cg_flag, "\tmovq\t%d(%%rbp), %%rax\t#call %s!\n", getAddress(findCG(getTN(op1))), getName(getTN(op1))); + fprintf(cg_flag, "\tcall *%%rax\n"); + } + //if (getTN(op2) == NULL) { + //printdebug("generateFunctionCall failed, NULL tablenode2"); + // return -1; + // } //now for the return CGNode *cg = findCG(getResult(inst)); - + if (cg == NULL) { cg = addCG(getResult(inst), offset); } @@ -702,8 +724,11 @@ int generateReturn(Instruction *inst) { printdebug("generateReturn failed, trying to return %s not in CGList", getName(getTN(op1))); return -1; } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#return %s\n", getAddress(cg), getName(getTN(op1))); + if (isAnActualFunction(getTN(op1))) { + fprintf(cg_flag, "\tmovl\t$%s,%%eax\t#return a function\n", getName(getTN(op1))); + } else { + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#return %s\n", getAddress(cg), getName(getTN(op1))); + } fprintf(cg_flag, "\tleave\n"); fprintf(cg_flag, "\tret\n"); return 0; @@ -830,14 +855,13 @@ int generateFunctionStart(Instruction *inst) { if (funList == NULL) { return -1; } - fprintf(stderr, "here\n"); TableNode *funDec; while (funList != NULL) { funDec = funList->tn; - CGNode *cg = addCG(getResult(inst), offset); + CGNode *cg = findCG(getResult(inst)); fprintf(cg_flag, "\tmovq\t$%s, %d(%%rbp)\t#storing function declaration\n", getName(funDec), getAddress(cg)); funList = funList->next; } - } + } return 0; } diff --git a/src/codegen.h b/src/codegen.h index d790ea9..828f16a 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -33,6 +33,7 @@ typedef struct FunDecList { struct FunDecList *next; } FunDecList; +bool isAnActualFunction(TableNode *tn); int generate(); CGNode *getNextCG(CGNode *cg); int getAddress(CGNode *cg); From b1296ddd021b96a6704788eee06841f80ad8a590 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 21:15:09 -0400 Subject: [PATCH 094/109] read --- README.MD | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.MD b/README.MD index 525582f..f8dc6f9 100644 --- a/README.MD +++ b/README.MD @@ -1,6 +1,33 @@ # The Translators α Compiler #### Members: Annie Slenker, Meyer Simon, Partho Bhattacharya, & Scarlett Kadan +## Alpha Compiler Flags & Expected Results +### -tok +Prints the token stream provided by the Lexical Analyzer to a `.tok` file. Output can be found in `/out/.tok`. Tokenization follows the specified format found in the alpha language spec. + +### -st +Prints the symbol table to a file. Follows the format provided in the alpha language spec. if the `-ir` flag is also present, the symbol table will print out temporary variables. Output can be found in `out/.st`. + +### -asc +Prints the annotated alpha source code to a file. Will display any syntax errors that are present below the line they occur on. If more than one error is present, the messages will stack. Output can be found in `out/.asc`. + +### -tc +Throws type check errors to the asc output file. If the `-asc` flag is not present, no errors will be displayed. Output can be found in `out/.asc` + +### -ir +Prints the intermediate code representation stream to a file. Output can be found in `out/.ir`. This flag modifies the `-st` flag, allowing for temporary variables to print out. + +### -cg +Prints the alpha program's unique x86 assembly to a `.s` file. Assembly stream is valid x86 code that can be assembled and linked with other .s files. Output can be found in `out/.s` + +### -debug +Prints debug messages to the console if present. Our debug messages utilizes a wrapper function for `printf()` called `printdebug()`. This allows for us to file names, code lines, and colors! + +### -help +Prints a general help message. (If you read this far, you probably won't need this flag) + + + ## Lexical Analyzer * **Undefined Behavior:** * Spaces are not required between tokens. For instance, an INTEGER and an ID are valid even if there is no space between them From 9633e322817048e16f6566de8348bd6a7a9addb2 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 21:22:39 -0400 Subject: [PATCH 095/109] reading is fun --- README.MD | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.MD b/README.MD index f8dc6f9..953df72 100644 --- a/README.MD +++ b/README.MD @@ -27,6 +27,36 @@ Prints debug messages to the console if present. Our debug messages utilizes a w Prints a general help message. (If you read this far, you probably won't need this flag) +## Testing + + **Arguments:** + -exp Generate expected output files + -diff Compare output files with expected output files + -help Show this help message + + **Usage:** + ./test.sh [flags] Run the test on a single file + ./test.sh [flags] Run the test on all files in a directory + + **Examples:** + - ./test.sh test.alpha + - - Runs test flags in header on test.alpha + - ./test.sh test/ + - - Runs test flags in header on all .alpha files in test/ + - ./test.sh test/ -exp + - - Runs test flags in header on all .alpha files in test/ and generates expected output files + - ./test.sh test/ -diff + - - Runs test flags in header on all .alpha files in test/ and compares output files with expected output files +- ./test.sh test/ -exp -diff +- - Runs test flags in header on all .alpha files in test/ and generates expected output files and compares output files with expected output files + + **Notes:** + To create a test file, on the first line of the .alpha file, add: + (* TEST: [ ] *) + where are the alpha flags to be used. Ex: + (* TEST: [ -debug -asc -tc ] *) + + ## Lexical Analyzer * **Undefined Behavior:** From 63bdb0a47039e837aed78341f6c92ad8379d9ca9 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Tue, 6 May 2025 21:30:04 -0400 Subject: [PATCH 096/109] Tests for annie --- tests/programs/helloworld.alpha | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/programs/helloworld.alpha b/tests/programs/helloworld.alpha index c889222..abc43a3 100644 --- a/tests/programs/helloworld.alpha +++ b/tests/programs/helloworld.alpha @@ -4,7 +4,7 @@ function entry: string2integer entry (arg) := { [integer: result] - + result := printCharacter('H'); result := printCharacter('e'); result := printCharacter('l'); @@ -20,4 +20,4 @@ entry (arg) := { result := printCharacter('\n'); return 0; -} \ No newline at end of file +} From e23e91477aaf4a84cf0c4fe43ff5d399a85b5c10 Mon Sep 17 00:00:00 2001 From: Annie Date: Tue, 6 May 2025 21:45:09 -0400 Subject: [PATCH 097/109] fixed everything breaking i think --- src/codegen.c | 17 +++++++++-------- tests/given/test/functionValue.alpha | 26 +++++++++++++------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 1784a09..52b7b96 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -85,6 +85,7 @@ int generate() { break; case E_FUNC_DEC: generateFunctionDec(i); + break; default:; } i = i->next; @@ -388,10 +389,10 @@ 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, "\tcmpb\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, "\tcmpb\t$0, %d(%%rbp)\n", getAddress(op2CG)); fprintf(cg_flag, "\tje\t.L%dor3\n", label); fprintf(cg_flag, ".L%dor2:\n", label); @@ -439,10 +440,10 @@ 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, "\tcmpb\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, "\tcmpb\t$0, %d(%%rbp)\n", getAddress(op2CG)); fprintf(cg_flag, "\tje\t.L%dor2\n", label); fprintf(cg_flag, "\tmovl\t$1, %%eax\n"); @@ -534,7 +535,7 @@ int generateAssign(Instruction *inst) { printdebug("generateAssign failed, %s is not constant but not in CGlist", getName(getTN(op1))); return -1; } - if (getAdInfoType(getTN(op1)) != TYPE_FUNCTION_DECLARATION || !isAnActualFunction(getTN(op1))){ + if (getAdInfoType(getTN(op1)) != TYPE_FUNCTION_DECLARATION || table_lookup(getAncestor(cur), getName(getTN(op1))) == undefined){ 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)); } else { @@ -724,7 +725,7 @@ int generateReturn(Instruction *inst) { printdebug("generateReturn failed, trying to return %s not in CGList", getName(getTN(op1))); return -1; } - if (isAnActualFunction(getTN(op1))) { + if (table_lookup(getAncestor(cur), getName(getTN(op1))) != undefined) { fprintf(cg_flag, "\tmovl\t$%s,%%eax\t#return a function\n", getName(getTN(op1))); } else { fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#return %s\n", getAddress(cg), getName(getTN(op1))); @@ -851,7 +852,7 @@ int generateFunctionStart(Instruction *inst) { } } - if (strcmp(getName(funDecTN), "entry") == 0) { +/* if (strcmp(getName(funDecTN), "entry") == 0) { if (funList == NULL) { return -1; } @@ -862,6 +863,6 @@ int generateFunctionStart(Instruction *inst) { fprintf(cg_flag, "\tmovq\t$%s, %d(%%rbp)\t#storing function declaration\n", getName(funDec), getAddress(cg)); funList = funList->next; } - } + } */ return 0; } diff --git a/tests/given/test/functionValue.alpha b/tests/given/test/functionValue.alpha index aa31fde..24fce40 100644 --- a/tests/given/test/functionValue.alpha +++ b/tests/given/test/functionValue.alpha @@ -1,6 +1,6 @@ (* TEST: [-asc -tc] *) (* Type definitions *) - +#include "std.alpha" (* mapping type *) type string2int: string -> integer @@ -9,9 +9,9 @@ type funArray: 1 -> string2int (* record of functions *) type funRec: [ string2int: f; string2int: g ] - +type int2int: integer -> integer (* function returning function *) -type integer_2_string2int: integer -> string2int +type integer_2_int2int: integer -> int2int (* function returning function *) type string2int_2_integer: string2int -> integer @@ -22,8 +22,8 @@ type iXiXc: [integer: a; integer: b; character: c] type iic2b: iXiXc -> Boolean (* Function declarations using the above type definitions *) -function a: string2int -function b: integer_2_string2int +function a: int2int +function b: integer_2_int2int function c: string2int_2_integer function d: iic2b @@ -37,8 +37,8 @@ function entry: string2int a(x) := { [string : s] - s := x; - + x:= printInteger(x); + return 0; } @@ -51,7 +51,7 @@ b(x) := { c(x) := { [string: s] s := "Hi!"; - return a(s); + return 3; } @@ -59,11 +59,11 @@ c(x) := { entry is the first function called *) entry(arg) := { - [integer: result; string2int: f; integer: temp] - temp := a("Hello"); + [integer: result; int2int: f; integer: temp] + temp := 7; f := b(temp); - result := f("ahhh"); - result := c(f); + result := f(temp); + (*result := c(f);*) if (d(1,2,'c')) then { result := 0; @@ -72,6 +72,6 @@ entry(arg) := { [ Boolean : b] result := entry("hello"); } - result := c(f); + (*result := c(f);*) return result; } From 0db52f8e8f38135d01ffa725726f791ec8fd85ff Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Tue, 6 May 2025 22:00:55 -0400 Subject: [PATCH 098/109] Test for annie --- tests/programs/sp3_if_else_sse.alpha | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 tests/programs/sp3_if_else_sse.alpha diff --git a/tests/programs/sp3_if_else_sse.alpha b/tests/programs/sp3_if_else_sse.alpha new file mode 100644 index 0000000..49d345f --- /dev/null +++ b/tests/programs/sp3_if_else_sse.alpha @@ -0,0 +1,36 @@ +#include "std.alpha" +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) := { + [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t; integer: c] + x := false; + y := true; + if ( x | y ) then { + + (* + if ( x Date: Tue, 6 May 2025 22:16:58 -0400 Subject: [PATCH 099/109] cool things --- README.MD | 75 ++++++++++++++------------ tests/programs/array.alpha | 20 +++++++ tests/programs/io.alpha | 27 ---------- tests/programs/ll.alpha | 1 - tests/sprint4/test/sp4_tc_arrays.alpha | 27 ---------- 5 files changed, 61 insertions(+), 89 deletions(-) create mode 100644 tests/programs/array.alpha delete mode 100644 tests/programs/io.alpha delete mode 100644 tests/programs/ll.alpha delete mode 100644 tests/sprint4/test/sp4_tc_arrays.alpha diff --git a/README.MD b/README.MD index 953df72..c4ace9a 100644 --- a/README.MD +++ b/README.MD @@ -1,7 +1,7 @@ # The Translators α Compiler #### Members: Annie Slenker, Meyer Simon, Partho Bhattacharya, & Scarlett Kadan -## Alpha Compiler Flags & Expected Results +## Alpha Compiler Flags & Expected Results: ### -tok Prints the token stream provided by the Lexical Analyzer to a `.tok` file. Output can be found in `/out/.tok`. Tokenization follows the specified format found in the alpha language spec. @@ -27,48 +27,55 @@ Prints debug messages to the console if present. Our debug messages utilizes a w Prints a general help message. (If you read this far, you probably won't need this flag) -## Testing +## Alpha Tools: Testing & Building +We have built a few tools to aid in the development processes. These include `./test.sh` and `./genx.sh`. Below you can find information about each. - **Arguments:** - -exp Generate expected output files - -diff Compare output files with expected output files - -help Show this help message +### ./test.sh +All tests under sprint 1, 2, 3, & 4 will work with the testing suite, along with running it directly with the alpha executable. These files do not use the `#include` directive, instead opting to define everything used within the file. +> **Arguments:**
+> `-exp` Generate expected output files
+> `-diff` Compare output files with expected output files
+> `-help` Show this help message
- **Usage:** - ./test.sh [flags] Run the test on a single file - ./test.sh [flags] Run the test on all files in a directory +> **Usage:**
+> `./test.sh [flags]` Run the test on a single file
+> `./test.sh [flags]` Run the test on all files in a directory
- **Examples:** - - ./test.sh test.alpha - - - Runs test flags in header on test.alpha - - ./test.sh test/ - - - Runs test flags in header on all .alpha files in test/ - - ./test.sh test/ -exp - - - Runs test flags in header on all .alpha files in test/ and generates expected output files - - ./test.sh test/ -diff - - - Runs test flags in header on all .alpha files in test/ and compares output files with expected output files -- ./test.sh test/ -exp -diff -- - Runs test flags in header on all .alpha files in test/ and generates expected output files and compares output files with expected output files +> **Examples:**
+> `./test.sh test.alpha` Runs test flags in header on test.alpha
+> `./test.sh test/` Runs test flags in header on all .alpha files in test/
+> `./test.sh test/ -exp` Runs test flags in header on all .alpha files in test/ and generates expected output files
+> `./test.sh test/ -diff` Runs test flags in header on all .alpha files in test/ and compares output files with expected output files
+> `./test.sh test/ -exp -diff` Runs test flags in header on all .alpha files in test/ and generates expected output files and compares output files with expected output files
- **Notes:** - To create a test file, on the first line of the .alpha file, add: - (* TEST: [ ] *) - where are the alpha flags to be used. Ex: - (* TEST: [ -debug -asc -tc ] *) +> **Notes:**
+> To create a test file, on the first line of the .alpha file, add:
+> `(* TEST: [ ] *)`
+> where are the alpha flags to be used. Ex:
+> `(* TEST: [ -debug -asc -tc ] *)`
+### ./genx.sh +GenX is our preprocessor tool. It is able to handle `#include` statements within an alpha file. The tool allows for includes of `.alpha`, `.s`, and `.c` files, given a relative path to them. You can also include our library file `std.alpha` which does not require a relative path.
+**NOTE:** *Due to the nature of include statements, running the alpha compiler on alpha files that use include statements will most likely result in syntax/type errors. When dealing with a file with include statements, it is advised to use GenX.* -## Lexical Analyzer -* **Undefined Behavior:** - * Spaces are not required between tokens. For instance, an INTEGER and an ID are valid even if there is no space between them +> **Arguments:**
+> `-help` Displays this message
+ +> **Usage:**
+> `./genx.sh `
Generates executable file from
+ +> **Notes:**
+> Generates .s and links alpha driver and general library and other includes.
+ +## Other Notes: + +### Lexical Analyzer +**Undefined Behavior:**
+* Spaces are not required between tokens. For instance, an INTEGER and an ID are valid even if there is no space between them ``` Input: *5variable* Output: 2 14 301 "5" 1 1 101 "variable" ``` - -## Syntax Analyzer -* *Incomplete* - -## Symbol Table -* *TODO: Create diagram.* \ No newline at end of file +* Added an `#include` token to stop syntax errors from being reported on certain alpha files. \ No newline at end of file diff --git a/tests/programs/array.alpha b/tests/programs/array.alpha new file mode 100644 index 0000000..9022f19 --- /dev/null +++ b/tests/programs/array.alpha @@ -0,0 +1,20 @@ +#include "std.alpha" + +type main: string -> integer +function entry: main + +(* maybe some other type definitions *) + +entry(arg) := { + [ string: one_name; string: another_name ] + + one_name := "a string literal"; + + another_name := reserve another_name(4); + another_name(0) := 'C'; + another_name(1) := 'a'; + another_name(2) := 'r'; + another_name(3) := 'l'; + + return 0; +} \ No newline at end of file diff --git a/tests/programs/io.alpha b/tests/programs/io.alpha deleted file mode 100644 index ddfb00e..0000000 --- a/tests/programs/io.alpha +++ /dev/null @@ -1,27 +0,0 @@ -#include "std.alpha" - -function entry: string2integer - -entry (arg) := { - [integer: x; string: s; character: c; integer: result] - - result := printCharacter('\t'); - result := printCharacter('t'); - result := printCharacter('a'); - result := printCharacter('b'); - result := printCharacter('\n'); - result := printCharacter('\\'); - result := printCharacter('"'); - result := printCharacter('\''); - - (*s := inS(1); - result := printS(s); - - x := inI(1); - result := printI(x); - - c := inC(1); - result := printC(c);*) - - return 0; -} \ No newline at end of file diff --git a/tests/programs/ll.alpha b/tests/programs/ll.alpha deleted file mode 100644 index 4178a08..0000000 --- a/tests/programs/ll.alpha +++ /dev/null @@ -1 +0,0 @@ -(* TODO: creates a linked list and prints out the chain. *) \ No newline at end of file diff --git a/tests/sprint4/test/sp4_tc_arrays.alpha b/tests/sprint4/test/sp4_tc_arrays.alpha deleted file mode 100644 index 19a31de..0000000 --- a/tests/sprint4/test/sp4_tc_arrays.alpha +++ /dev/null @@ -1,27 +0,0 @@ -type string: 1 -> character -type a_of_s: 1 -> string -type main: integer -> integer -function entry: main - -(* maybe some other type definitions *) - -entry(arg) := { - [ string: one_name; string: another_name; a_of_s: many_names ] - one_name := "a string literal"; - another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *) - another_name(0) := 'C'; - another_name(1) := 'a'; - another_name(2) := 'r'; - another_name(3) := 'l'; - many_names := reserve many_names(3); - many_names(0) := one_name; - many_names(1) := another_name; - many_names(2) := reserve many_names(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *) - many_names(2)(0) := 'P'; - many_names(2)(1) := 'a'; - many_names(2)(2) := 'r'; - many_names(2)(3) := 't'; - many_names(2)(4) := 'h'; - many_names(2)(5) := 'o'; - return 0; -} \ No newline at end of file From 5a01cb8419e38623e3cae98490385571894bf9f4 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 22:35:26 -0400 Subject: [PATCH 100/109] tests update --- tests/given/README.MD | 1 + tests/sprint1/expected/sp1_include.asc.exp | 3 + tests/sprint1/expected/sp1_include.tok.exp | 6 ++ .../sprint2/expected/sp2_carls_mistake.st.exp | 3 + tests/sprint2/expected/sp2_llnode.st.exp | 3 + tests/sprint2/expected/sp2_llnode_bad.st.exp | 4 ++ .../sprint2/expected/sp2_sp2_arrayargs.st.exp | 8 +++ .../sp2_valid_assignable_and_mem.st.exp | 10 ++- .../test/sp2_valid_assignable_and_mem.alpha | 2 +- .../expected/sp3_and_or_type_check.asc.exp | 12 ++-- .../sprint3/expected/sp3_arr_reserve.asc.exp | 10 +++ .../sp3_boolean_binary_op_typecheck.asc.exp | 4 +- .../expected/sp3_carls_second_mistake.asc.exp | 3 - tests/sprint3/expected/sp3_if_else.asc.exp | 21 +++--- .../expected/sp3_if_else_nested_exp.asc.exp | 25 ++++++++ .../sprint3/expected/sp3_if_else_sse.asc.exp | 31 +++++++++ .../sprint3/expected/sp3_if_else_sse2.asc.exp | 34 ++++++++++ .../expected/sp3_while_nested_bools.asc.exp | 29 +++++++++ tests/sprint3/expected/sp3_while_sse.asc.exp | 27 ++++++++ tests/sprint3/test/sp3_arr_reserve.alpha | 2 +- .../sprint3/test/sp3_if_else_nested_exp.alpha | 1 + tests/sprint3/test/sp3_if_else_sse.alpha | 1 + tests/sprint3/test/sp3_if_else_sse2.alpha | 1 + .../sprint3/test/sp3_while_nested_bools.alpha | 1 + tests/sprint3/test/sp3_while_sse.alpha | 1 + tests/sprint4/expected/sp4_cg_add.asc.exp | 4 +- tests/sprint4/expected/sp4_cg_add.ir.exp | 22 +++---- tests/sprint4/expected/sp4_cg_add.s.exp | 6 +- tests/sprint4/expected/sp4_cg_calls.asc.exp | 40 ++++++------ tests/sprint4/expected/sp4_cg_calls.ir.exp | 64 ++++++++++--------- tests/sprint4/expected/sp4_cg_calls.s.exp | 59 +++++++++-------- tests/sprint4/expected/sp4_cg_div.ir.exp | 22 +++---- tests/sprint4/expected/sp4_cg_div.s.exp | 6 +- tests/sprint4/expected/sp4_cg_equal_to.ir.exp | 21 +++--- tests/sprint4/expected/sp4_cg_equal_to.s.exp | 21 +++--- .../sprint4/expected/sp4_cg_less_than.ir.exp | 21 +++--- tests/sprint4/expected/sp4_cg_less_than.s.exp | 20 +++--- tests/sprint4/expected/sp4_cg_mod.ir.exp | 22 +++---- tests/sprint4/expected/sp4_cg_mod.s.exp | 6 +- tests/sprint4/expected/sp4_cg_mult.ir.exp | 22 +++---- tests/sprint4/expected/sp4_cg_mult.s.exp | 6 +- tests/sprint4/expected/sp4_cg_neg.ir.exp | 17 ++--- tests/sprint4/expected/sp4_cg_neg.s.exp | 5 +- tests/sprint4/expected/sp4_cg_not.ir.exp | 7 +- tests/sprint4/expected/sp4_cg_not.s.exp | 15 ++--- tests/sprint4/expected/sp4_cg_or.ir.exp | 28 ++++---- tests/sprint4/expected/sp4_cg_or.s.exp | 28 ++++---- tests/sprint4/expected/sp4_cg_sub.ir.exp | 22 +++---- tests/sprint4/expected/sp4_cg_sub.s.exp | 6 +- 49 files changed, 442 insertions(+), 291 deletions(-) create mode 100644 tests/given/README.MD create mode 100644 tests/sprint1/expected/sp1_include.asc.exp create mode 100644 tests/sprint1/expected/sp1_include.tok.exp create mode 100644 tests/sprint3/expected/sp3_arr_reserve.asc.exp create mode 100644 tests/sprint3/expected/sp3_if_else_nested_exp.asc.exp create mode 100644 tests/sprint3/expected/sp3_if_else_sse.asc.exp create mode 100644 tests/sprint3/expected/sp3_if_else_sse2.asc.exp create mode 100644 tests/sprint3/expected/sp3_while_nested_bools.asc.exp create mode 100644 tests/sprint3/expected/sp3_while_sse.asc.exp diff --git a/tests/given/README.MD b/tests/given/README.MD new file mode 100644 index 0000000..ad2dae4 --- /dev/null +++ b/tests/given/README.MD @@ -0,0 +1 @@ +NOTE: slightly modified from originals, please execute with care. :) \ No newline at end of file diff --git a/tests/sprint1/expected/sp1_include.asc.exp b/tests/sprint1/expected/sp1_include.asc.exp new file mode 100644 index 0000000..d987cea --- /dev/null +++ b/tests/sprint1/expected/sp1_include.asc.exp @@ -0,0 +1,3 @@ +001: #include "alpha.h" +002: #include "alpha.h" +003: #include "alpha.h" \ No newline at end of file diff --git a/tests/sprint1/expected/sp1_include.tok.exp b/tests/sprint1/expected/sp1_include.tok.exp new file mode 100644 index 0000000..086c1ce --- /dev/null +++ b/tests/sprint1/expected/sp1_include.tok.exp @@ -0,0 +1,6 @@ +1 1 901 "#include" +1 10 304 ""alpha.h"" +2 1 901 "#include" +2 10 304 ""alpha.h"" +3 1 901 "#include" +3 10 304 ""alpha.h"" diff --git a/tests/sprint2/expected/sp2_carls_mistake.st.exp b/tests/sprint2/expected/sp2_carls_mistake.st.exp index 7fe89f6..edcf5c5 100644 --- a/tests/sprint2/expected/sp2_carls_mistake.st.exp +++ b/tests/sprint2/expected/sp2_carls_mistake.st.exp @@ -23,6 +23,9 @@ arg : 025000 : 001001 : string result : 025000 : 001001 : integer : Primitive Instance w : 025000 : 001001 : rec : Record Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: r : 021000 : 001001 : integer : Primitive Instance s : 021000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: diff --git a/tests/sprint2/expected/sp2_llnode.st.exp b/tests/sprint2/expected/sp2_llnode.st.exp index 8b78bd3..abbd641 100644 --- a/tests/sprint2/expected/sp2_llnode.st.exp +++ b/tests/sprint2/expected/sp2_llnode.st.exp @@ -26,6 +26,9 @@ result : 068000 : 001001 : integer w : 068000 : 001001 : rec : Record Instance li : 068000 : 001001 : llnode : Record Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: r : 053000 : 001001 : integer : Primitive Instance s : 053000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: diff --git a/tests/sprint2/expected/sp2_llnode_bad.st.exp b/tests/sprint2/expected/sp2_llnode_bad.st.exp index cebad8b..d6e60a4 100644 --- a/tests/sprint2/expected/sp2_llnode_bad.st.exp +++ b/tests/sprint2/expected/sp2_llnode_bad.st.exp @@ -26,6 +26,10 @@ result : 069000 : 001001 : integer w : 069000 : 001001 : rec : Record Instance li : 069000 : 001001 : llnode : Record Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: r : 054000 : 001001 : integer : Primitive Instance s : 054000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: diff --git a/tests/sprint2/expected/sp2_sp2_arrayargs.st.exp b/tests/sprint2/expected/sp2_sp2_arrayargs.st.exp index b76e609..028f8a4 100644 --- a/tests/sprint2/expected/sp2_sp2_arrayargs.st.exp +++ b/tests/sprint2/expected/sp2_sp2_arrayargs.st.exp @@ -14,3 +14,11 @@ a_of_s : 001001 : : 1 -> string one_name : 006000 : 001001 : string : Array Instance another_name : 006000 : 001001 : string : Array Instance many_names : 006000 : 001001 : a_of_s : Array Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: diff --git a/tests/sprint2/expected/sp2_valid_assignable_and_mem.st.exp b/tests/sprint2/expected/sp2_valid_assignable_and_mem.st.exp index e755b52..3714bab 100644 --- a/tests/sprint2/expected/sp2_valid_assignable_and_mem.st.exp +++ b/tests/sprint2/expected/sp2_valid_assignable_and_mem.st.exp @@ -9,5 +9,13 @@ reserve type : 001001 : : integer -> address reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 7 +rec : 001001 : : Record Type : elements-2 size-8 bytes +T2 : 001001 : : rec -> integer : Type of Function ------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 000000 : 001001 : : Empty Scope +arg : 007000 : 001001 : string : Array Instance +w : 007000 : 001001 : rec : Record Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +x : 004000 : 001001 : integer : Primitive Instance +y : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha b/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha index 9fe5655..3fc875e 100644 --- a/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha +++ b/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha @@ -1,5 +1,5 @@ (* TEST: [-st] *) -ype main: string -> integer +type main: string -> integer function entry: main type rec: [integer: x; integer: y] diff --git a/tests/sprint3/expected/sp3_and_or_type_check.asc.exp b/tests/sprint3/expected/sp3_and_or_type_check.asc.exp index fb7fe0c..304d268 100644 --- a/tests/sprint3/expected/sp3_and_or_type_check.asc.exp +++ b/tests/sprint3/expected/sp3_and_or_type_check.asc.exp @@ -57,26 +57,26 @@ LINE (28:2) ** TYPE ERROR: Undefined variable b 029: b := 1 | b; LINE (29:12) ** TYPE ERROR: Invalid type passed to assignable. - LINE (29:12) ** TYPE ERROR: Object $t9 of type integer and Object undefined of type undefined must both be Boolean + LINE (29:12) ** TYPE ERROR: Object $t11 of type integer and Object undefined of type undefined must both be Boolean LINE (29:11) ** TYPE ERROR: Undefined variable b LINE (29:2) ** TYPE ERROR: Undefined variable b 030: b := b | 1; LINE (30:12) ** TYPE ERROR: Invalid type passed to assignable. - LINE (30:12) ** TYPE ERROR: Object undefined of type undefined and Object $t10 of type integer must both be Boolean + LINE (30:12) ** TYPE ERROR: Object undefined of type undefined and Object $t13 of type integer must both be Boolean LINE (30:7) ** TYPE ERROR: Undefined variable b LINE (30:2) ** TYPE ERROR: Undefined variable b 031: b := b & 1; LINE (31:12) ** TYPE ERROR: Invalid type passed to assignable. - LINE (31:12) ** TYPE ERROR: Object undefined of type undefined and Object $t11 of type integer must both be Boolean + LINE (31:12) ** TYPE ERROR: Object undefined of type undefined and Object $t15 of type integer must both be Boolean LINE (31:7) ** TYPE ERROR: Undefined variable b LINE (31:2) ** TYPE ERROR: Undefined variable b 032: b := 1 & b; LINE (32:12) ** TYPE ERROR: Invalid type passed to assignable. - LINE (32:12) ** TYPE ERROR: Object $t12 of type integer and Object undefined of type undefined must both be Boolean + LINE (32:12) ** TYPE ERROR: Object $t17 of type integer and Object undefined of type undefined must both be Boolean LINE (32:11) ** TYPE ERROR: Undefined variable b LINE (32:2) ** TYPE ERROR: Undefined variable b 033: b := 1 = 1; - LINE (33:12) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t15 of type Boolean + LINE (33:12) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t21 of type Boolean LINE (33:12) ** TYPE ERROR: Invalid type passed to assignable. LINE (33:2) ** TYPE ERROR: Undefined variable b 034: @@ -84,7 +84,7 @@ 036: 037: b := 1 = b; LINE (37:12) ** TYPE ERROR: Invalid type passed to assignable. - LINE (37:12) ** TYPE ERROR: Object $t16 of type integer and Object undefined of type undefined must both be the same type + LINE (37:12) ** TYPE ERROR: Object $t22 of type integer and Object undefined of type undefined must both be the same type LINE (37:11) ** TYPE ERROR: Undefined variable b LINE (37:2) ** TYPE ERROR: Undefined variable b 038: diff --git a/tests/sprint3/expected/sp3_arr_reserve.asc.exp b/tests/sprint3/expected/sp3_arr_reserve.asc.exp new file mode 100644 index 0000000..cb1d755 --- /dev/null +++ b/tests/sprint3/expected/sp3_arr_reserve.asc.exp @@ -0,0 +1,10 @@ +001: type main: string -> integer +002: function entry: main +003: type t: 3 -> integer +004: +005: +006: entry (arg) := { +007: [ t:a] +008: a := reserve a(1, 3, 4); +009: return 0; +010: } diff --git a/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.asc.exp b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.asc.exp index b9eabd2..fd029ac 100644 --- a/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.asc.exp +++ b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.asc.exp @@ -10,8 +10,8 @@ LINE (8:18) ** TYPE ERROR: Object arr of type address and Object $t2 of type integer must both be the same type 009: b1 := 6<7 & arr2=7; LINE (9:23) ** TYPE ERROR: Assignable Assign Expression - Object b1 of type Boolean != Object undefined of type undefined - LINE (9:23) ** TYPE ERROR: Object $t5 of type Boolean and Object undefined of type undefined must both be Boolean - LINE (9:23) ** TYPE ERROR: Object arr2 of type address and Object $t6 of type integer must both be the same type + LINE (9:23) ** TYPE ERROR: Object $t6 of type Boolean and Object undefined of type undefined must both be Boolean + LINE (9:23) ** TYPE ERROR: Object arr2 of type address and Object $t7 of type integer must both be the same type 010: 011: return 0; 012: } diff --git a/tests/sprint3/expected/sp3_carls_second_mistake.asc.exp b/tests/sprint3/expected/sp3_carls_second_mistake.asc.exp index 51a366e..c67a27b 100644 --- a/tests/sprint3/expected/sp3_carls_second_mistake.asc.exp +++ b/tests/sprint3/expected/sp3_carls_second_mistake.asc.exp @@ -11,20 +11,17 @@ 011: 012: one_name := "a string literal"; 013: another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *) - LINE (13:44) ** TYPE ERROR: Assignable Assign Expression - Object another_name of type string != Object undefined of type undefined 014: another_name(0) := 'C'; 015: another_name(1) := 'a'; 016: another_name(2) := 'r'; 017: another_name(3) := 'l'; 018: many_names := reserve many_names(3); - LINE (18:40) ** TYPE ERROR: Assignable Assign Expression - Object many_names of type a_of_s != Object undefined of type undefined 019: many_names(0) := one_name; 020: many_names(1) := another_name; 021: many_names(2) := reserve many_names(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *) LINE (21:45) ** SYNTAX ERROR: Incorrect syntax at token ')' LINE (21:44) ** SYNTAX ERROR: Incorrect syntax at token '6' LINE (21:43) ** SYNTAX ERROR: Incorrect syntax at token '(' - LINE (21:43) ** TYPE ERROR: Assignable Assign Expression - Object $t20 of type string != Object undefined of type undefined 022: many_names(2)(0) := 'P'; 023: many_names(2)(1) := 'a'; 024: many_names(2)(2) := 'r'; diff --git a/tests/sprint3/expected/sp3_if_else.asc.exp b/tests/sprint3/expected/sp3_if_else.asc.exp index 9bdc9e7..0bd0f6d 100644 --- a/tests/sprint3/expected/sp3_if_else.asc.exp +++ b/tests/sprint3/expected/sp3_if_else.asc.exp @@ -11,15 +11,12 @@ 011: } 012: 013: entry (arg) := { -014: [ integer: result ; rec: w] -015: if ( result = result ) then { -016: if ( result < w.y ) then { -017: result := 8; -018: } else { -019: result := 9; -020: }(* *) -021: } else { -022: result := bar('c', 7); -023: } -024: return 0; -025: } +014: [ integer: r ; integer: s; Boolean: x] +015: (* x := (r < s) & x; *) +016: if ( ( r < s ) & (s = r) ) then { +017: r := 5; +018: } else { +019: r := 7; +020: } +021: return 0; +022: } diff --git a/tests/sprint3/expected/sp3_if_else_nested_exp.asc.exp b/tests/sprint3/expected/sp3_if_else_nested_exp.asc.exp new file mode 100644 index 0000000..1832760 --- /dev/null +++ b/tests/sprint3/expected/sp3_if_else_nested_exp.asc.exp @@ -0,0 +1,25 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ integer: x ; integer: y; integer: z;integer: t] +015: +016: if ( (x = y) < ( z = t ) ) then { +017: if ( (x < y) = ( z < t ) ) then { +018: x := x; +019: } else { +020: x := 1; (* bar('c', 7); *) +021: } +022: } else { +023: return 0; +024: } +025: } diff --git a/tests/sprint3/expected/sp3_if_else_sse.asc.exp b/tests/sprint3/expected/sp3_if_else_sse.asc.exp new file mode 100644 index 0000000..5cb09f5 --- /dev/null +++ b/tests/sprint3/expected/sp3_if_else_sse.asc.exp @@ -0,0 +1,31 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: (* +010: bar (r,s) := { +011: return 0; +012: } +013: +014: *) +015: entry (arg) := { +016: [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] +017: if ( ( x & y ) ) then { +018: +019: (* +020: if ( x integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] +015: (* if ( y & (z | t) ) then { *) +016: if ( ( x = y ) & ( z < t ) ) then { +017: (* y := z < t; *) +018: t:= 0; +019: } else { +020: (* t := z = t; *) +021: z := 1; +022: } +023: (* +024: if ( x & y ) then { +025: t := true; +026: } else { +027: y := true; +028: } +029: *) +030: (* } else { *) +031: (* } *) +032: (* x := x & y; *) +033: return 0; +034: } diff --git a/tests/sprint3/expected/sp3_while_nested_bools.asc.exp b/tests/sprint3/expected/sp3_while_nested_bools.asc.exp new file mode 100644 index 0000000..a3444d6 --- /dev/null +++ b/tests/sprint3/expected/sp3_while_nested_bools.asc.exp @@ -0,0 +1,29 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ Boolean: x ; Boolean: y; Boolean: z;Boolean: t] +015: while ( ((x = y)) < ( z | t ) ) { +016: while ( (x & y) = ( z < t ) ) { +017: y := y; +018: } +019: (* +020: x := x; +021: *) +022: if ( (x = y) = ( z < t ) ) then { +023: x := 1; +024: } else { +025: x := 1; +026: } +027: } +028: return 0; +029: } diff --git a/tests/sprint3/expected/sp3_while_sse.asc.exp b/tests/sprint3/expected/sp3_while_sse.asc.exp new file mode 100644 index 0000000..fe8e2ae --- /dev/null +++ b/tests/sprint3/expected/sp3_while_sse.asc.exp @@ -0,0 +1,27 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] +015: while ( ( x | y ) (* | ( z | t ) *) ) { +016: (* +017: if ( ( x < y ) & ( z = t ) ) then { +018: y := z < t; +019: } else { +020: t := z = t; +021: } +022: *) +023: y := t < z; (* bar('c', 7); *) +024: } +025: (* x := x & y; *) +026: return 0; +027: } diff --git a/tests/sprint3/test/sp3_arr_reserve.alpha b/tests/sprint3/test/sp3_arr_reserve.alpha index 114da34..e78640f 100644 --- a/tests/sprint3/test/sp3_arr_reserve.alpha +++ b/tests/sprint3/test/sp3_arr_reserve.alpha @@ -1,4 +1,4 @@ - +(* TEST: [-asc -tc] *) type main: string -> integer function entry: main type t: 3 -> integer diff --git a/tests/sprint3/test/sp3_if_else_nested_exp.alpha b/tests/sprint3/test/sp3_if_else_nested_exp.alpha index 08161f2..c89da43 100644 --- a/tests/sprint3/test/sp3_if_else_nested_exp.alpha +++ b/tests/sprint3/test/sp3_if_else_nested_exp.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type rec: [character: x; integer: y] type T2: rec -> integer diff --git a/tests/sprint3/test/sp3_if_else_sse.alpha b/tests/sprint3/test/sp3_if_else_sse.alpha index cbbf116..8cb74e3 100644 --- a/tests/sprint3/test/sp3_if_else_sse.alpha +++ b/tests/sprint3/test/sp3_if_else_sse.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type rec: [character: x; integer: y] type T2: rec -> integer diff --git a/tests/sprint3/test/sp3_if_else_sse2.alpha b/tests/sprint3/test/sp3_if_else_sse2.alpha index e226dd6..c5a1a33 100644 --- a/tests/sprint3/test/sp3_if_else_sse2.alpha +++ b/tests/sprint3/test/sp3_if_else_sse2.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type rec: [character: x; integer: y] type T2: rec -> integer diff --git a/tests/sprint3/test/sp3_while_nested_bools.alpha b/tests/sprint3/test/sp3_while_nested_bools.alpha index 11765c0..e9ac27e 100644 --- a/tests/sprint3/test/sp3_while_nested_bools.alpha +++ b/tests/sprint3/test/sp3_while_nested_bools.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type rec: [character: x; integer: y] type T2: rec -> integer diff --git a/tests/sprint3/test/sp3_while_sse.alpha b/tests/sprint3/test/sp3_while_sse.alpha index 61b1731..58d8f6a 100644 --- a/tests/sprint3/test/sp3_while_sse.alpha +++ b/tests/sprint3/test/sp3_while_sse.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type rec: [character: x; integer: y] type T2: rec -> integer diff --git a/tests/sprint4/expected/sp4_cg_add.asc.exp b/tests/sprint4/expected/sp4_cg_add.asc.exp index c234273..d4499a0 100644 --- a/tests/sprint4/expected/sp4_cg_add.asc.exp +++ b/tests/sprint4/expected/sp4_cg_add.asc.exp @@ -1,4 +1,4 @@ -001: +001: 002: type string: 1 -> character 003: type BooleanXBoolean: [Boolean: x; Boolean: y] 004: type characterXcharacter: [character: x; character: y] @@ -34,7 +34,7 @@ 034: external function inC: integer2character 035: 036: function entry: string2integer -037: +037: 038: entry (arg) := { 039: [integer:x; integer:y; integer: result] 040: diff --git a/tests/sprint4/expected/sp4_cg_add.ir.exp b/tests/sprint4/expected/sp4_cg_add.ir.exp index 73beb15..80451f3 100644 --- a/tests/sprint4/expected/sp4_cg_add.ir.exp +++ b/tests/sprint4/expected/sp4_cg_add.ir.exp @@ -1,16 +1,12 @@ 1: func_dec : entry 2: func : entry 3: $t0 = 1 - 4: Label : 1 - 5: y = $t0 - 6: $t1 = 3 - 7: Label : 2 - 8: x = $t1 - 9: $t2 = x + y - 10: Label : 3 - 11: y = $t2 - 12: param y - 13: call : printInteger 1 - 14: Label : 4 - 15: result = $t3 - 16: return : y + 4: y = $t0 + 5: $t1 = 3 + 6: x = $t1 + 7: $t2 = x + y + 8: y = $t2 + 9: param y + 10: call : printInteger 1 + 11: result = $t3 + 12: return : y diff --git a/tests/sprint4/expected/sp4_cg_add.s.exp b/tests/sprint4/expected/sp4_cg_add.s.exp index f58dd79..c47a3d4 100644 --- a/tests/sprint4/expected/sp4_cg_add.s.exp +++ b/tests/sprint4/expected/sp4_cg_add.s.exp @@ -2,27 +2,23 @@ entry: pushq %rbp movq %rsp, %rbp - subq $128, %rsp + subq $400, %rsp movl %edi, -8(%rbp) #FunctionStart1param end movl $1, -12(%rbp) #constant assign -.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end movl $3, -20(%rbp) #constant assign -.L2: movl -20(%rbp), %eax #assign start movl %eax, -24(%rbp) #assign end movl -24(%rbp), %eax #addition start addl -16(%rbp), %eax movl %eax, -28(%rbp) #addition end -.L3: movl -28(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end movl -16(%rbp), %edi #adding param start call printInteger movl %eax, -32(%rbp) #store return from call -.L4: movl -32(%rbp), %eax #assign start movl %eax, -36(%rbp) #assign end movl -16(%rbp), %eax #return y diff --git a/tests/sprint4/expected/sp4_cg_calls.asc.exp b/tests/sprint4/expected/sp4_cg_calls.asc.exp index edc0a7a..831976b 100644 --- a/tests/sprint4/expected/sp4_cg_calls.asc.exp +++ b/tests/sprint4/expected/sp4_cg_calls.asc.exp @@ -35,26 +35,26 @@ 035: 036: function entry: string2integer 037: -038: -039: type rec: [integer: x; integer: y; integer: z; integer: a; integer: b; integer: c; integer: d] -040: type T2: rec -> integer -041: type T: integer -> integer -042: function bar: T2 -043: function ahh: T -044: -045: ahh (a) := { -046: a := printInteger(a); -047: return -1; -048: } -049: -050: bar (a, b, c,d,e,f,g) := { -051: a := printInteger(g); -052: return b; -053: } -054: -055: entry (arg) := { -056: [integer:x; integer:y; integer: result] -057: +038: type rec: [integer: x; integer: y; integer: z; integer: a; integer: b; integer: c; integer: d] +039: type T2: rec -> integer +040: type T: integer -> integer +041: function bar: T2 +042: function ahh: T +043: +044: ahh (a) := { +045: a := printInteger(a); +046: return -1; +047: } +048: +049: bar (a, b, c,d,e,f,g) := { +050: a := printInteger(g); +051: return b; +052: } +053: +054: entry (arg) := { +055: [integer:x; integer:y; integer: result; character: a] +056: a := 'a'; +057: x := printCharacter(a); 058: result := bar(1,2,3,4,5,6,7); 059: return 1; 060: } diff --git a/tests/sprint4/expected/sp4_cg_calls.ir.exp b/tests/sprint4/expected/sp4_cg_calls.ir.exp index 2995985..cbaa89e 100644 --- a/tests/sprint4/expected/sp4_cg_calls.ir.exp +++ b/tests/sprint4/expected/sp4_cg_calls.ir.exp @@ -4,34 +4,36 @@ 4: func : ahh 5: param a 6: call : printInteger 1 - 7: Label : 1 - 8: a = $t0 - 9: $t1 = 1 - 10: $t2 = -$t1 - 11: return : $t2 - 12: func : bar - 13: param g - 14: call : printInteger 1 - 15: Label : 2 - 16: a = $t3 - 17: return : b - 18: func : entry - 19: $t4 = 1 - 20: $t5 = 2 - 21: $t6 = 3 - 22: $t7 = 4 - 23: $t8 = 5 - 24: $t9 = 6 - 25: $t10 = 7 - 26: param $t10 - 27: param $t9 - 28: param $t8 - 29: param $t7 - 30: param $t6 - 31: param $t5 - 32: param $t4 - 33: call : bar 7 - 34: Label : 3 - 35: result = $t11 - 36: $t12 = 1 - 37: return : $t12 + 7: a = $t0 + 8: $t1 = 1 + 9: $t2 = -$t1 + 10: return : $t2 + 11: func : bar + 12: param g + 13: call : printInteger 1 + 14: a = $t3 + 15: return : b + 16: func : entry + 17: $t4 = a + 18: a = $t4 + 19: param a + 20: call : printCharacter 1 + 21: x = $t5 + 22: $t6 = 1 + 23: $t7 = 2 + 24: $t8 = 3 + 25: $t9 = 4 + 26: $t10 = 5 + 27: $t11 = 6 + 28: $t12 = 7 + 29: param $t12 + 30: param $t11 + 31: param $t10 + 32: param $t9 + 33: param $t8 + 34: param $t7 + 35: param $t6 + 36: call : bar 7 + 37: result = $t13 + 38: $t14 = 1 + 39: return : $t14 diff --git a/tests/sprint4/expected/sp4_cg_calls.s.exp b/tests/sprint4/expected/sp4_cg_calls.s.exp index 55b65cb..0d28c99 100644 --- a/tests/sprint4/expected/sp4_cg_calls.s.exp +++ b/tests/sprint4/expected/sp4_cg_calls.s.exp @@ -2,12 +2,11 @@ ahh: pushq %rbp movq %rsp, %rbp - subq $128, %rsp + subq $576, %rsp movl %edi, -4(%rbp) #FunctionStart1param end movl -4(%rbp), %edi #adding param start call printInteger movl %eax, -8(%rbp) #store return from call -.L1: movl -8(%rbp), %eax #assign start movl %eax, -4(%rbp) #assign end movl $1, -12(%rbp) #constant assign @@ -20,7 +19,7 @@ ahh: bar: pushq %rbp movq %rsp, %rbp - subq $128, %rsp + subq $576, %rsp movl 20(%rbp), %eax #FunctionStart1Param start movl %eax, -4(%rbp) #FunctionStart1param end movl %r9d, -12(%rbp) #FunctionStart1param end @@ -32,7 +31,6 @@ bar: movl -32(%rbp), %edi #adding param start call printInteger movl %eax, -36(%rbp) #store return from call -.L2: movl -36(%rbp), %eax #assign start movl %eax, -4(%rbp) #assign end movl -12(%rbp), %eax #return b @@ -41,29 +39,36 @@ bar: entry: pushq %rbp movq %rsp, %rbp - subq $128, %rsp - movl %edi, -8(%rbp) #FunctionStart1param end - movl $1, -12(%rbp) #constant assign - movl $2, -16(%rbp) #constant assign - movl $3, -20(%rbp) #constant assign - movl $4, -24(%rbp) #constant assign - movl $5, -28(%rbp) #constant assign - movl $6, -32(%rbp) #constant assign - movl $7, -36(%rbp) #constant assign - movl -36(%rbp), %edi #adding param start - movl -32(%rbp), %esi #adding param start - movl -28(%rbp), %edx #adding param start - movl -24(%rbp), %ecx #adding param start - movl -20(%rbp), %r8d #adding param start - movl -16(%rbp), %r9d #adding param start - movl -12(%rbp), %eax #adding param start - movl %eax, 88(%rbp) #adding param end + subq $576, %rsp + movl %edi, -12(%rbp) #FunctionStart1param end + movl $97, -13(%rbp) #constant assign + movl -13(%rbp), %eax #assign start + movl %eax, -14(%rbp) #assign end + movl -14(%rbp), %edi #adding param start + call printCharacter + movl %eax, -20(%rbp) #store return from call + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl $1, -28(%rbp) #constant assign + movl $2, -32(%rbp) #constant assign + movl $3, -36(%rbp) #constant assign + movl $4, -40(%rbp) #constant assign + movl $5, -44(%rbp) #constant assign + movl $6, -48(%rbp) #constant assign + movl $7, -52(%rbp) #constant assign + movl -52(%rbp), %edi #adding param start + movl -48(%rbp), %esi #adding param start + movl -44(%rbp), %edx #adding param start + movl -40(%rbp), %ecx #adding param start + movl -36(%rbp), %r8d #adding param start + movl -32(%rbp), %r9d #adding param start + movl -28(%rbp), %eax #adding param start + movl %eax, 152(%rbp) #adding param end call bar - movl %eax, -44(%rbp) #store return from call -.L3: - movl -44(%rbp), %eax #assign start - movl %eax, -48(%rbp) #assign end - movl $1, -52(%rbp) #constant assign - movl -52(%rbp), %eax #return $t12 + movl %eax, -60(%rbp) #store return from call + movl -60(%rbp), %eax #assign start + movl %eax, -64(%rbp) #assign end + movl $1, -68(%rbp) #constant assign + movl -68(%rbp), %eax #return $t14 leave ret diff --git a/tests/sprint4/expected/sp4_cg_div.ir.exp b/tests/sprint4/expected/sp4_cg_div.ir.exp index f316a19..56f58fd 100644 --- a/tests/sprint4/expected/sp4_cg_div.ir.exp +++ b/tests/sprint4/expected/sp4_cg_div.ir.exp @@ -1,16 +1,12 @@ 1: func_dec : entry 2: func : entry 3: $t0 = 24 - 4: Label : 1 - 5: x = $t0 - 6: $t1 = 3 - 7: Label : 2 - 8: y = $t1 - 9: $t2 = x / y - 10: Label : 3 - 11: y = $t2 - 12: param y - 13: call : printInteger 1 - 14: Label : 4 - 15: result = $t3 - 16: return : y + 4: x = $t0 + 5: $t1 = 3 + 6: y = $t1 + 7: $t2 = x / y + 8: y = $t2 + 9: param y + 10: call : printInteger 1 + 11: result = $t3 + 12: return : y diff --git a/tests/sprint4/expected/sp4_cg_div.s.exp b/tests/sprint4/expected/sp4_cg_div.s.exp index cc51cef..53861da 100644 --- a/tests/sprint4/expected/sp4_cg_div.s.exp +++ b/tests/sprint4/expected/sp4_cg_div.s.exp @@ -2,27 +2,23 @@ entry: pushq %rbp movq %rsp, %rbp - subq $128, %rsp + subq $400, %rsp movl %edi, -8(%rbp) #FunctionStart1param end movl $24, -12(%rbp) #constant assign -.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end movl $3, -20(%rbp) #constant assign -.L2: movl -20(%rbp), %eax #assign start movl %eax, -24(%rbp) #assign end movl -16(%rbp), %eax #division start cltd idivl -24(%rbp) movl %eax, -28(%rbp) #division end -.L3: movl -28(%rbp), %eax #assign start movl %eax, -24(%rbp) #assign end movl -24(%rbp), %edi #adding param start call printInteger movl %eax, -32(%rbp) #store return from call -.L4: movl -32(%rbp), %eax #assign start movl %eax, -36(%rbp) #assign end movl -24(%rbp), %eax #return y diff --git a/tests/sprint4/expected/sp4_cg_equal_to.ir.exp b/tests/sprint4/expected/sp4_cg_equal_to.ir.exp index d0b9e1c..c8ec780 100644 --- a/tests/sprint4/expected/sp4_cg_equal_to.ir.exp +++ b/tests/sprint4/expected/sp4_cg_equal_to.ir.exp @@ -1,17 +1,16 @@ 1: func_dec : entry 2: func : entry 3: $t0 = 1 - 4: Label : 1 - 5: x = $t0 - 6: $t1 = 2 - 7: Label : 2 - 8: y = $t1 - 9: $t2 = x == y - 10: Label : 3 + 4: x = $t0 + 5: $t1 = 2 + 6: y = $t1 + 7: $t2 = x == y + 8: if $t2 True GOTO 1 + 9: GOTO : 1 + 10: Label : 1 11: b = $t2 12: param b 13: call : printBoolean 1 - 14: Label : 4 - 15: result = $t3 - 16: $t4 = 1 - 17: return : $t4 + 14: result = $t3 + 15: $t4 = 1 + 16: return : $t4 diff --git a/tests/sprint4/expected/sp4_cg_equal_to.s.exp b/tests/sprint4/expected/sp4_cg_equal_to.s.exp index 374f095..038d473 100644 --- a/tests/sprint4/expected/sp4_cg_equal_to.s.exp +++ b/tests/sprint4/expected/sp4_cg_equal_to.s.exp @@ -2,30 +2,31 @@ entry: pushq %rbp movq %rsp, %rbp - subq $128, %rsp + subq $416, %rsp movl %edi, -8(%rbp) #FunctionStart1param end movl $1, -12(%rbp) #constant assign -.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end movl $2, -20(%rbp) #constant assign -.L2: movl -20(%rbp), %eax #assign start movl %eax, -24(%rbp) #assign end movl -16(%rbp), %eax #equal to start cmpl -24(%rbp), %eax sete %al + movb $0, -25(%rbp) movb %al, -25(%rbp) #equal to end -.L3: + cmpb $0, -25(%rbp) #if true start + jne .L1 #if true end + jmp .L1 +.L1: movl -25(%rbp), %eax #assign start movl %eax, -26(%rbp) #assign end movl -26(%rbp), %edi #adding param start call printBoolean - movl %eax, -30(%rbp) #store return from call -.L4: - movl -30(%rbp), %eax #assign start - movl %eax, -34(%rbp) #assign end - movl $1, -38(%rbp) #constant assign - movl -38(%rbp), %eax #return $t4 + movl %eax, -32(%rbp) #store return from call + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl $1, -40(%rbp) #constant assign + movl -40(%rbp), %eax #return $t4 leave ret diff --git a/tests/sprint4/expected/sp4_cg_less_than.ir.exp b/tests/sprint4/expected/sp4_cg_less_than.ir.exp index 169347b..ff83dbc 100644 --- a/tests/sprint4/expected/sp4_cg_less_than.ir.exp +++ b/tests/sprint4/expected/sp4_cg_less_than.ir.exp @@ -1,17 +1,16 @@ 1: func_dec : entry 2: func : entry 3: $t0 = 1 - 4: Label : 1 - 5: x = $t0 - 6: $t1 = 2 - 7: Label : 2 - 8: y = $t1 - 9: $t2 = x < y - 10: Label : 3 + 4: x = $t0 + 5: $t1 = 2 + 6: y = $t1 + 7: $t2 = x < y + 8: if $t2 True GOTO 1 + 9: GOTO : 1 + 10: Label : 1 11: b = $t2 12: param b 13: call : printBoolean 1 - 14: Label : 4 - 15: result = $t3 - 16: $t4 = 1 - 17: return : $t4 + 14: result = $t3 + 15: $t4 = 1 + 16: return : $t4 diff --git a/tests/sprint4/expected/sp4_cg_less_than.s.exp b/tests/sprint4/expected/sp4_cg_less_than.s.exp index 57c2a33..a9235cd 100644 --- a/tests/sprint4/expected/sp4_cg_less_than.s.exp +++ b/tests/sprint4/expected/sp4_cg_less_than.s.exp @@ -2,30 +2,30 @@ entry: pushq %rbp movq %rsp, %rbp - subq $128, %rsp + subq $416, %rsp movl %edi, -8(%rbp) #FunctionStart1param end movl $1, -12(%rbp) #constant assign -.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end movl $2, -20(%rbp) #constant assign -.L2: movl -20(%rbp), %eax #assign start movl %eax, -24(%rbp) #assign end movl -16(%rbp), %eax #less than start cmpl -24(%rbp), %eax setl %al movb %al, -25(%rbp) #less than end -.L3: + cmpb $0, -25(%rbp) #if true start + jne .L1 #if true end + jmp .L1 +.L1: movl -25(%rbp), %eax #assign start movl %eax, -26(%rbp) #assign end movl -26(%rbp), %edi #adding param start call printBoolean - movl %eax, -30(%rbp) #store return from call -.L4: - movl -30(%rbp), %eax #assign start - movl %eax, -34(%rbp) #assign end - movl $1, -38(%rbp) #constant assign - movl -38(%rbp), %eax #return $t4 + movl %eax, -32(%rbp) #store return from call + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl $1, -40(%rbp) #constant assign + movl -40(%rbp), %eax #return $t4 leave ret diff --git a/tests/sprint4/expected/sp4_cg_mod.ir.exp b/tests/sprint4/expected/sp4_cg_mod.ir.exp index 4c2421e..1148d7e 100644 --- a/tests/sprint4/expected/sp4_cg_mod.ir.exp +++ b/tests/sprint4/expected/sp4_cg_mod.ir.exp @@ -1,16 +1,12 @@ 1: func_dec : entry 2: func : entry 3: $t0 = 4 - 4: Label : 1 - 5: x = $t0 - 6: $t1 = 20 - 7: Label : 2 - 8: y = $t1 - 9: $t2 = y % x - 10: Label : 3 - 11: y = $t2 - 12: param y - 13: call : printInteger 1 - 14: Label : 4 - 15: result = $t3 - 16: return : y + 4: x = $t0 + 5: $t1 = 20 + 6: y = $t1 + 7: $t2 = y % x + 8: y = $t2 + 9: param y + 10: call : printInteger 1 + 11: result = $t3 + 12: return : y diff --git a/tests/sprint4/expected/sp4_cg_mod.s.exp b/tests/sprint4/expected/sp4_cg_mod.s.exp index 85cd9db..c76ec55 100644 --- a/tests/sprint4/expected/sp4_cg_mod.s.exp +++ b/tests/sprint4/expected/sp4_cg_mod.s.exp @@ -2,27 +2,23 @@ entry: pushq %rbp movq %rsp, %rbp - subq $128, %rsp + subq $400, %rsp movl %edi, -8(%rbp) #FunctionStart1param end movl $4, -12(%rbp) #constant assign -.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end movl $20, -20(%rbp) #constant assign -.L2: movl -20(%rbp), %eax #assign start movl %eax, -24(%rbp) #assign end movl -24(%rbp), %eax #mod start cltd idivl -16(%rbp) movl %edx, -28(%rbp) #mod end -.L3: movl -28(%rbp), %eax #assign start movl %eax, -24(%rbp) #assign end movl -24(%rbp), %edi #adding param start call printInteger movl %eax, -32(%rbp) #store return from call -.L4: movl -32(%rbp), %eax #assign start movl %eax, -36(%rbp) #assign end movl -24(%rbp), %eax #return y diff --git a/tests/sprint4/expected/sp4_cg_mult.ir.exp b/tests/sprint4/expected/sp4_cg_mult.ir.exp index 70de136..12ec01d 100644 --- a/tests/sprint4/expected/sp4_cg_mult.ir.exp +++ b/tests/sprint4/expected/sp4_cg_mult.ir.exp @@ -1,16 +1,12 @@ 1: func_dec : entry 2: func : entry 3: $t0 = 3 - 4: Label : 1 - 5: x = $t0 - 6: $t1 = 20 - 7: Label : 2 - 8: y = $t1 - 9: $t2 = x * y - 10: Label : 3 - 11: y = $t2 - 12: param y - 13: call : printInteger 1 - 14: Label : 4 - 15: result = $t3 - 16: return : y + 4: x = $t0 + 5: $t1 = 20 + 6: y = $t1 + 7: $t2 = x * y + 8: y = $t2 + 9: param y + 10: call : printInteger 1 + 11: result = $t3 + 12: return : y diff --git a/tests/sprint4/expected/sp4_cg_mult.s.exp b/tests/sprint4/expected/sp4_cg_mult.s.exp index 567acb3..019a840 100644 --- a/tests/sprint4/expected/sp4_cg_mult.s.exp +++ b/tests/sprint4/expected/sp4_cg_mult.s.exp @@ -2,26 +2,22 @@ entry: pushq %rbp movq %rsp, %rbp - subq $128, %rsp + subq $400, %rsp movl %edi, -8(%rbp) #FunctionStart1param end movl $3, -12(%rbp) #constant assign -.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end movl $20, -20(%rbp) #constant assign -.L2: movl -20(%rbp), %eax #assign start movl %eax, -24(%rbp) #assign end movl -16(%rbp), %eax #multiplication start imull -24(%rbp), %eax movl %eax, -28(%rbp) #multiplication end -.L3: movl -28(%rbp), %eax #assign start movl %eax, -24(%rbp) #assign end movl -24(%rbp), %edi #adding param start call printInteger movl %eax, -32(%rbp) #store return from call -.L4: movl -32(%rbp), %eax #assign start movl %eax, -36(%rbp) #assign end movl -24(%rbp), %eax #return y diff --git a/tests/sprint4/expected/sp4_cg_neg.ir.exp b/tests/sprint4/expected/sp4_cg_neg.ir.exp index 9bc3442..88e0fc4 100644 --- a/tests/sprint4/expected/sp4_cg_neg.ir.exp +++ b/tests/sprint4/expected/sp4_cg_neg.ir.exp @@ -1,13 +1,10 @@ 1: func_dec : entry 2: func : entry 3: $t0 = 3 - 4: Label : 1 - 5: x = $t0 - 6: $t1 = -x - 7: Label : 2 - 8: y = $t1 - 9: param y - 10: call : printInteger 1 - 11: Label : 3 - 12: result = $t2 - 13: return : y + 4: x = $t0 + 5: $t1 = -x + 6: y = $t1 + 7: param y + 8: call : printInteger 1 + 9: result = $t2 + 10: return : y diff --git a/tests/sprint4/expected/sp4_cg_neg.s.exp b/tests/sprint4/expected/sp4_cg_neg.s.exp index ddf2a63..6e92063 100644 --- a/tests/sprint4/expected/sp4_cg_neg.s.exp +++ b/tests/sprint4/expected/sp4_cg_neg.s.exp @@ -2,22 +2,19 @@ entry: pushq %rbp movq %rsp, %rbp - subq $128, %rsp + subq $400, %rsp movl %edi, -8(%rbp) #FunctionStart1param end movl $3, -12(%rbp) #constant assign -.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end movl -16(%rbp), %eax #negation start negl %eax movl %eax, -20(%rbp) #negation end -.L2: movl -20(%rbp), %eax #assign start movl %eax, -24(%rbp) #assign end movl -24(%rbp), %edi #adding param start call printInteger movl %eax, -28(%rbp) #store return from call -.L3: movl -28(%rbp), %eax #assign start movl %eax, -32(%rbp) #assign end movl -24(%rbp), %eax #return y diff --git a/tests/sprint4/expected/sp4_cg_not.ir.exp b/tests/sprint4/expected/sp4_cg_not.ir.exp index 5a9a503..eb3abe9 100644 --- a/tests/sprint4/expected/sp4_cg_not.ir.exp +++ b/tests/sprint4/expected/sp4_cg_not.ir.exp @@ -7,7 +7,6 @@ 7: d = $t1 8: param d 9: call : printBoolean 1 - 10: Label : 3 - 11: result = $t2 - 12: $t3 = 1 - 13: return : $t3 + 10: result = $t2 + 11: $t3 = 1 + 12: return : $t3 diff --git a/tests/sprint4/expected/sp4_cg_not.s.exp b/tests/sprint4/expected/sp4_cg_not.s.exp index 63b18a5..8739ed0 100644 --- a/tests/sprint4/expected/sp4_cg_not.s.exp +++ b/tests/sprint4/expected/sp4_cg_not.s.exp @@ -2,20 +2,19 @@ entry: pushq %rbp movq %rsp, %rbp - subq $128, %rsp + subq $400, %rsp movl %edi, -8(%rbp) #FunctionStart1param end - movl $-1, -9(%rbp) #constant assign + movl $1, -9(%rbp) #constant assign .L1: movl -9(%rbp), %eax #assign start movl %eax, -10(%rbp) #assign end .L2: movl -11(%rbp), %edi #adding param start call printBoolean - movl %eax, -15(%rbp) #store return from call -.L3: - movl -15(%rbp), %eax #assign start - movl %eax, -19(%rbp) #assign end - movl $1, -23(%rbp) #constant assign - movl -23(%rbp), %eax #return $t3 + movl %eax, -18(%rbp) #store return from call + movl -18(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl $1, -28(%rbp) #constant assign + movl -28(%rbp), %eax #return $t3 leave ret diff --git a/tests/sprint4/expected/sp4_cg_or.ir.exp b/tests/sprint4/expected/sp4_cg_or.ir.exp index 0319c40..4470879 100644 --- a/tests/sprint4/expected/sp4_cg_or.ir.exp +++ b/tests/sprint4/expected/sp4_cg_or.ir.exp @@ -7,18 +7,16 @@ 7: Label : 2 8: d = $t1 9: $t2 = true - 10: Label : 3 - 11: if c True GOTO 5 - 12: GOTO : 4 - 13: Label : 4 - 14: if d True GOTO 5 - 15: $t2 = false - 16: GOTO : 5 - 17: Label : 5 - 18: d = $t2 - 19: param d - 20: call : printBoolean 1 - 21: Label : 6 - 22: result = $t3 - 23: $t4 = 1 - 24: return : $t4 + 10: if c True GOTO 4 + 11: GOTO : 3 + 12: Label : 3 + 13: if d True GOTO 4 + 14: $t2 = false + 15: GOTO : 4 + 16: Label : 4 + 17: d = $t2 + 18: param d + 19: call : printBoolean 1 + 20: result = $t3 + 21: $t4 = 1 + 22: return : $t4 diff --git a/tests/sprint4/expected/sp4_cg_or.s.exp b/tests/sprint4/expected/sp4_cg_or.s.exp index 0493673..1ca0a6a 100644 --- a/tests/sprint4/expected/sp4_cg_or.s.exp +++ b/tests/sprint4/expected/sp4_cg_or.s.exp @@ -2,30 +2,34 @@ entry: pushq %rbp movq %rsp, %rbp - subq $128, %rsp + subq $416, %rsp movl %edi, -8(%rbp) #FunctionStart1param end - movl $-1, -9(%rbp) #constant assign + movl $1, -9(%rbp) #constant assign .L1: movl -9(%rbp), %eax #assign start movl %eax, -10(%rbp) #assign end - movl $-1, -11(%rbp) #constant assign + movl $0, -11(%rbp) #constant assign .L2: movl -11(%rbp), %eax #assign start movl %eax, -12(%rbp) #assign end - movl $-1, -13(%rbp) #constant assign + movl $1, -13(%rbp) #constant assign + cmpb $0, -10(%rbp) #if true start + jne .L4 #if true end + jmp .L3 .L3: + cmpb $0, -12(%rbp) #if true start + jne .L4 #if true end + movl $0, -13(%rbp) #constant assign + jmp .L4 .L4: - movl $-1, -13(%rbp) #constant assign -.L5: movl -13(%rbp), %eax #assign start movl %eax, -12(%rbp) #assign end movl -12(%rbp), %edi #adding param start call printBoolean - movl %eax, -17(%rbp) #store return from call -.L6: - movl -17(%rbp), %eax #assign start - movl %eax, -21(%rbp) #assign end - movl $1, -25(%rbp) #constant assign - movl -25(%rbp), %eax #return $t4 + movl %eax, -18(%rbp) #store return from call + movl -18(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl $1, -28(%rbp) #constant assign + movl -28(%rbp), %eax #return $t4 leave ret diff --git a/tests/sprint4/expected/sp4_cg_sub.ir.exp b/tests/sprint4/expected/sp4_cg_sub.ir.exp index 23e60d4..468b1eb 100644 --- a/tests/sprint4/expected/sp4_cg_sub.ir.exp +++ b/tests/sprint4/expected/sp4_cg_sub.ir.exp @@ -1,16 +1,12 @@ 1: func_dec : entry 2: func : entry 3: $t0 = 1 - 4: Label : 1 - 5: y = $t0 - 6: $t1 = 3 - 7: Label : 2 - 8: x = $t1 - 9: $t2 = x - y - 10: Label : 3 - 11: y = $t2 - 12: param y - 13: call : printInteger 1 - 14: Label : 4 - 15: result = $t3 - 16: return : y + 4: y = $t0 + 5: $t1 = 3 + 6: x = $t1 + 7: $t2 = x - y + 8: y = $t2 + 9: param y + 10: call : printInteger 1 + 11: result = $t3 + 12: return : y diff --git a/tests/sprint4/expected/sp4_cg_sub.s.exp b/tests/sprint4/expected/sp4_cg_sub.s.exp index bc47b9f..8f2c60e 100644 --- a/tests/sprint4/expected/sp4_cg_sub.s.exp +++ b/tests/sprint4/expected/sp4_cg_sub.s.exp @@ -2,26 +2,22 @@ entry: pushq %rbp movq %rsp, %rbp - subq $128, %rsp + subq $400, %rsp movl %edi, -8(%rbp) #FunctionStart1param end movl $1, -12(%rbp) #constant assign -.L1: movl -12(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end movl $3, -20(%rbp) #constant assign -.L2: movl -20(%rbp), %eax #assign start movl %eax, -24(%rbp) #assign end movl -24(%rbp), %eax #subtraction start subl -16(%rbp), %eax movl %eax, -28(%rbp) #subtraction end -.L3: movl -28(%rbp), %eax #assign start movl %eax, -16(%rbp) #assign end movl -16(%rbp), %edi #adding param start call printInteger movl %eax, -32(%rbp) #store return from call -.L4: movl -32(%rbp), %eax #assign start movl %eax, -36(%rbp) #assign end movl -16(%rbp), %eax #return y From fe2c8da7a4b150d57cdf3fdc24c489dd3dc0d0ee Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 22:57:42 -0400 Subject: [PATCH 101/109] reading is fun --- README.MD | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.MD b/README.MD index c4ace9a..74270bf 100644 --- a/README.MD +++ b/README.MD @@ -57,7 +57,9 @@ All tests under sprint 1, 2, 3, & 4 will work with the testing suite, along with ### ./genx.sh GenX is our preprocessor tool. It is able to handle `#include` statements within an alpha file. The tool allows for includes of `.alpha`, `.s`, and `.c` files, given a relative path to them. You can also include our library file `std.alpha` which does not require a relative path.
-**NOTE:** *Due to the nature of include statements, running the alpha compiler on alpha files that use include statements will most likely result in syntax/type errors. When dealing with a file with include statements, it is advised to use GenX.* +**NOTE:** *Due to the nature of include statements, running the alpha compiler on alpha files that use include statements will most likely result in syntax/type errors. When dealing with a file with include statements, it is advised to use GenX.*
+ +*You can also use the following command to preprocess a file:* `cpp -P -x c -o simple.cpp.alpha simple.alpha` > **Arguments:**
> `-help` Displays this message
From 29c1d1fd946b445a8d6753f23bb743f668c52b42 Mon Sep 17 00:00:00 2001 From: Annie Date: Tue, 6 May 2025 22:57:14 -0400 Subject: [PATCH 102/109] updated number of bytes used --- src/codegen.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 52b7b96..44d39df 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -536,8 +536,24 @@ int generateAssign(Instruction *inst) { return -1; } if (getAdInfoType(getTN(op1)) != TYPE_FUNCTION_DECLARATION || table_lookup(getAncestor(cur), getName(getTN(op1))) == undefined){ - 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)); + char *movtype; + char *reg; + TableNode *typetn = getTypeEntry(getTN(op1)); + if (typetn == integ) { + movtype = "movl"; + reg = "%eax"; + } else if (typetn == boo) { + movtype = "movb"; + reg = "%al"; + } else if (typetn == chara) { + movtype = "movb"; + reg = "%al"; + } else { + movtype = "movq"; + reg = "%rax"; + } + fprintf(cg_flag, "\t%s\t%d(%%rbp), %s\t#assign start\n",movtype, getAddress(op1CG), reg); + fprintf(cg_flag, "\t%s\t%s, %d(%%rbp)\t#assign end\n", movtype,reg,getAddress(cg)); } else { fprintf(cg_flag, "\tmovl\t$%s,%%eax\t#assign function\n", getName(getTN(op1))); fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#assign function end\n", getAddress(cg)); @@ -746,7 +762,7 @@ int generateAddressOf(Instruction *inst) { int generateParam(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); - fprintf(stderr, "generate param reached\n"); + //fprintf(stderr, "generate param reached\n"); if (op1 == NULL) { printdebug("generateParam failed, NULL operand"); return -1; From 05a1a671b6bb6adb640bd7fb1f40d5cede491fc3 Mon Sep 17 00:00:00 2001 From: Annie Date: Tue, 6 May 2025 22:59:12 -0400 Subject: [PATCH 103/109] test --- tests/programs/sp3_if_else_sse.alpha | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/programs/sp3_if_else_sse.alpha b/tests/programs/sp3_if_else_sse.alpha index 49d345f..c78ce35 100644 --- a/tests/programs/sp3_if_else_sse.alpha +++ b/tests/programs/sp3_if_else_sse.alpha @@ -15,7 +15,7 @@ bar (r,s) := { *) entry (arg) := { [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t; integer: c] - x := false; + x := true; y := true; if ( x | y ) then { From 0662bea9c35cc3f57eb5190d389997db77c620d8 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 6 May 2025 23:00:50 -0400 Subject: [PATCH 104/109] works? --- src/grammar.y | 105 ++++++++++++++++++++++++++++++++++------ src/intermediate_code.c | 29 ++++++++--- src/intermediate_code.h | 2 +- src/symbol_table.c | 99 +++++++++++++++++++++++++++++++++---- src/symbol_table.h | 12 +++-- 5 files changed, 211 insertions(+), 36 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 61e9724..78f5aa2 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -681,16 +681,10 @@ compound_statement: simple_statement: assignable{ //updating context for reserve/release - if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY){ - - context = 1; + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY || getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + PushContext(getTypeEntry((TableNode*)$1)); + printdebug("pushed %s to context stack in simple statement assignable rule\n",getName(getTypeEntry((TableNode*)$1))); } - else if(getAdInfoType((TableNode*)$1) == TYPE_RECORD){ - context = 2; - } else{ - context = 0; - } - //comparator = $1; S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); } ASSIGN expression @@ -733,7 +727,10 @@ simple_statement: } $$ = undefined; //resetting context - context = 0; + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY || getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + PopContext(); + printdebug("popped a context off in simplestatement assignable rule\n"); + } } @@ -777,9 +774,15 @@ ablock: ; - argument_list: + expression{ + PopContext(); + printdebug("popped a context off in argument list\n"); + incrementArgumentNumber(function_head); + TableNode* typeOfArg = getFunctionNumberType(getFunctionType(function_head), getArgumentNumber(function_head)); + PushContext(typeOfArg); + printdebug("pushed %s to context stack\n",getName(typeOfArg)); TableNode * arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); //inside a scope of an array call if line number is -2 if(getLine(cur)==-2){ @@ -806,6 +809,8 @@ argument_list: | expression { + PopContext(); + printdebug("popped a context off in argument list (single arg rule)\n"); TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); //inside a scope of an array call if line number is -2 if(getLine(cur)==-2){ @@ -1127,7 +1132,7 @@ expression: } // TODO: We need to type check this. - | RESERVE ID { + /*| RESERVE ID { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); TableNode * n = look_up(cur, $2); @@ -1140,7 +1145,7 @@ expression: emit_reserve(node, tn_or_const(INTEGER, &v)); $$ = node; } - /*| RELEASE ID { + | RELEASE ID { TableNode * n = look_up(cur, $2); if(getAdInfoType(n) != TYPE_RECORD){ throw_error(ERROR_TYPE, "Invalid Release expression with object %s of type %s.", @@ -1151,7 +1156,7 @@ expression: TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); //emit release needed here $$ = node; - }*/ + } | RESERVE ID { cur = CreateScope(cur, -2,-1); } ablock { @@ -1174,7 +1179,66 @@ expression: $$=undefined; } cur = getParent(cur); + }*/ + | RESERVE assignable{ + + if(getTypeEntry((TableNode*)$2) == getContextTypeEntry(context_head) + && (/*getAdInfoType((TableNode*)$2)==TYPE_ARRAY ||*/ getAdInfoType(getTypeEntry((TableNode*)$2)) == TYPE_RECORD)){ + char* temp = temp_var_gen(); + //does this have integer? + TableNode* node = CreateEntry(cur,TYPE_RECORD, getContextTypeEntry(context_head), temp, NULL); + emit_reserve(node, tn_or_const(NODE,$2)); + $$ = node; + } + if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head))) + && (getAdInfoType(getContextTypeEntry(context_head)) == TYPE_ARRAY_TYPE)){ + char* temp = temp_var_gen(); + //does this have integer? + TableNode* node = CreateEntry(cur,TYPE_ARRAY, getContextTypeEntry(context_head), temp, NULL); + emit_reserve(node, tn_or_const(NODE,$2)); + $$ = node; + }else{ + $$ = undefined; + } + } + + | RELEASE assignable{ + + if(getTypeEntry((TableNode*)$2) == getContextTypeEntry(context_head) + && (/*getAdInfoType((TableNode*)$2)==TYPE_ARRAY ||*/ getAdInfoType(getTypeEntry((TableNode*)$2)) == TYPE_RECORD)){ + char* temp = temp_var_gen(); + //does this have integer? + TableNode* node = CreateEntry(cur,TYPE_RECORD, getContextTypeEntry(context_head), temp, NULL); + emit_release((TableNode*)$2); + $$ = node; + } + if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head))) + && (getAdInfoType(getContextTypeEntry(context_head)) == TYPE_ARRAY_TYPE)){ + char* temp = temp_var_gen(); + //does this have integer? + TableNode* node = CreateEntry(cur,TYPE_ARRAY, getContextTypeEntry(context_head), temp, NULL); + emit_release((TableNode*)$2); + $$ = node; + }else{ + $$=undefined; + } } + +/* + TableNode* node = CreateEntry(cur,getAdInfoType((TableNode*)$2), getTypeEntry(), temp, NULL); + 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, $2)); + $$ = node; + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) != TYPE_ARRAY){ + throw_error(ERROR_TYPE, "Invalid Reserve expression with object %s of type %s.", + getName(n), getType(n)); + $$=undefined; + } + */ +/* | RELEASE assignable{ char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); @@ -1232,6 +1296,14 @@ assignable: } | assignable { + //TableNode* pass = look_up(cur,$1); + //if(pass == undefined){ + // throw_error(ERROR_TYPE, "Undefined variable %s", $1); + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY|| getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + PushFunction(1,(TableNode*)$1); + PushContext(getFunctionNumberType(getFunctionType(function_head), getArgumentNumber(function_head))); + printdebug("pushed %s to function stack\n",getName((TableNode*)$1)); + } printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); //Creating a dummy scope where we create entries for all the arguments of a function call //Must also consider that we might be in an array access @@ -1246,16 +1318,17 @@ assignable: if(getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ //the function context is created. Pushing the type of the function since that has the information needed - PushFunction(1, getTypeEntry((TableNode*)$1)); } } //we have to consider emmissions in ablocks ablock { + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY|| getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + PopFunction(); + } //PopContext(); //int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); - PopFunction(); int type = getAdInfoType(getTypeEntry((TableNode*)$1)); printdebug("%stype is %d", COLOR_PURPLE, type); printdebug("%s", getName((TableNode*)$1)); diff --git a/src/intermediate_code.c b/src/intermediate_code.c index beccafd..813b51a 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -190,7 +190,8 @@ void emit_binary_op( Op op, TableNode *result, TNodeOrConst *arg1, - TNodeOrConst *arg2) { + TNodeOrConst *arg2 + ) { emit_helper(); current->opcode = op; // TODO: create temp and remove result from param list @@ -315,6 +316,9 @@ void emit_return(TNodeOrConst *value) { void emit_reserve(TableNode *result, TNodeOrConst *size) { // this needs to change // we need to take a int + /* + emit_binary_op(E_MUL, result, + */ emit_parameter(size); emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); } @@ -345,8 +349,12 @@ void emit_address_of(TableNode *x, TNodeOrConst *y) { current->operand1 = y; } -void emit_field_access(char *result, char *record, char *field) { +void emit_field_access(TableNode *result, TNodeOrConst *record, int offset){ emit_helper(); + current->opcode = E_DEREF_RIGHT; + current->result = result; + current->operand1 = record; + current->operand2 = tn_or_const(INTEGER, &offset); } void emit_array_access(Op op, TableNode *result, TNodeOrConst *array, TNodeOrConst *index) { @@ -587,19 +595,22 @@ void emit_as_file(FILE *out_file, Instruction *i) { getName(i->result), get_string(i->operand1)); break; - case E_DEREF_RIGHT: fprintf(out_file, - "%4.d: %s = *%s\n", + "%4.d: %s = *((char * )%s + %s)\n", i->index, getName(i->result), - get_string(i->operand1)); + get_string(i->operand1), + get_string(i->operand2) + ); + break; case E_DEREF_LEFT: fprintf(out_file, "%4.d: *%s = %s\n", i->index, getName(i->result), get_string(i->operand1)); + break; } emit_as_file(out_file, i->next); @@ -615,6 +626,12 @@ TableNode *getTN(TNodeOrConst *tnc) { int getConst(TNodeOrConst *tnc) { if (tnc->d == INTEGER) { return tnc->tnc_union->integer; + } else if (tnc->d == CHARACTER) { + return tnc->tnc_union->character; + } else if (tnc->d == BOOLEAN) { + return tnc->tnc_union->Boolean; + } else if (tnc->d == ADDRESS) { + return 0; } return -1; -} +} \ No newline at end of file diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 5f50828..87e3123 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -143,7 +143,7 @@ void emit_function_dec(TableNode * name); void emit_return(TNodeOrConst *value); void emit_reserve(TableNode *result, TNodeOrConst *size); void emit_release(TableNode *pointer); -void emit_field_access(char *result, char *record, char *field); +void emit_field_access(TableNode *result, TNodeOrConst *record, int offset); 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); diff --git a/src/symbol_table.c b/src/symbol_table.c index 50ae956..d63f23e 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -57,19 +57,19 @@ Constant_Stack *Push(TableNode *type, void *value, bool isConst) { return cs; } -Context_stack *PushContext(int context, TableNode *typeToCompare) { - if (context != 1 && context != 2 && context != 3 && context != 0) { +Context_stack *PushContext(/*int context, */TableNode *typeToCompare) { + /*if (context != 1 && context != 2 && context != 3 && context != 0) { printdebug( "invalid context passed in"); return NULL; - } + }*/ if(typeToCompare == NULL) { printdebug( "passed a NULL reference to PushContext. Invalid."); return NULL; } Context_stack *cs = (Context_stack *)calloc(1,sizeof(Context_stack)); - cs->con = context; + //cs->con = context; cs->typeToCompare = typeToCompare; if (context_head == NULL) { context_head = cs; @@ -107,7 +107,7 @@ Function_Stack *PushFunction(int arg, TableNode* FunctionType) { Function_Stack *PopFunction() { if (function_head == NULL) { - printf("cannot pop from an empty stack. Invalid.\n"); + printf("cannot pop from an empty stack from popfunction. Invalid.\n"); return NULL; } Function_Stack *fs = function_head; @@ -124,6 +124,78 @@ int getArgumentNumber(Function_Stack *fs) { return fs->arg; } +int getTotalNumberArguments(TableNode* function) { + if (function == NULL) { + printdebug( + "passed a NULL reference to getTotalNumberArguments. Invalid."); + return -1; + } + if (getAdInfoType(function) != TYPE_FUNCTION_DECLARATION) { + printdebug( + "passed an invalid reference to getTotalNumberArguments. Invalid."); + return -1; + } + TableNode* functionType = getParameter(getTypeEntry(function)); + if(functionType != undefined){ + return -1; + } + if(getAdInfoType(functionType) != TYPE_RECORD_TYPE){ + return 1; + }else{ + return getRecLength(functionType); + } +} + +Function_Stack* setArgumentNumber(Function_Stack *fs, int arg) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to setArgumentNumber. Invalid."); + return NULL; + } + + if(argFunctionType)){ + //case where invalid argument number is being passed + return NULL; + } + fs->arg = arg; + return fs; +} +Function_Stack* setFunctionType(Function_Stack *fs, TableNode* functionType) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to setFunctionType. Invalid."); + return NULL; + } + if (functionType == NULL) { + printdebug( + "passed a NULL reference to setFunctionType. Invalid."); + return NULL; + } + fs->FunctionType = functionType; + return fs; +} +TableNode* getFunctionType(Function_Stack *fs) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to getFunctionType. Invalid."); + return undefined; + } + TableNode* tn = fs->FunctionType; + return tn; +} + +Function_Stack* incrementArgumentNumber(Function_Stack *fs) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to incrementArgumentNumber. Invalid."); + return NULL; + } + int cur=getArgumentNumber(fs); + setArgumentNumber(fs, cur+1); + //setFunctionType(fs, getFunctionNumberType(getFunctionType(fs), cur+1)); + return fs; +} + TableNode* getRecordNumberType(TableNode* record, int arg){ if(record == NULL){ //case where NULL is being passed in @@ -159,12 +231,20 @@ TableNode* getFunctionNumberType(TableNode* function, int arg){ //case where invalid argument number is being passed return undefined; } + if(getAdInfoType(function) == TYPE_FUNCTION_DECLARATION){ + if(getAdInfoType(getParameter(function)) != TYPE_RECORD_TYPE){ return getParameter(function); }else{ return getRecordNumberType(getParameter(function), arg); } +} else if(getAdInfoType(function) == TYPE_ARRAY_TYPE){ + return getArrType(function); +}else{ + return undefined; } +} + TableNode* getFunctionTypeContext(Function_Stack *fs) { if (fs == NULL) { @@ -178,15 +258,15 @@ TableNode* getFunctionTypeContext(Function_Stack *fs) { Context_stack *PopContext() { if (context_head == NULL) { - printf("cannot pop from an empty stack. Invalid.\n"); + printf("cannot pop from an empty stack from popcontext. Invalid.\n"); return NULL; } Context_stack *cs = context_head; context_head = context_head->next; - printf("Popped context off stack: number %d\n", cs->con); + //printf("Popped context off stack: number %d\n", cs->con); return cs; } - +/* int getContextType(Context_stack *cs) { if (cs == NULL) { printdebug( @@ -195,8 +275,7 @@ int getContextType(Context_stack *cs) { } return cs->con; } - -//should be +*/ TableNode *getContextTypeEntry(Context_stack *cs) { if (cs == NULL) { printdebug( diff --git a/src/symbol_table.h b/src/symbol_table.h index 14ca6e7..82ab464 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -46,7 +46,7 @@ typedef struct Constant_Stack { //we can also simply add to the function call stack if we have functions inside functions and then update as needed typedef struct Context_stack { - int con; + //int con; TableNode *typeToCompare; struct Context_stack *next; } Context_stack; @@ -134,14 +134,19 @@ void printdebug_impl(char *file, int line, const char *format, ...); char *temp_var_gen(); char *arg_var_gen(); +int getTotalNumberArguments(TableNode* function); +Function_Stack* incrementArgumentNumber(Function_Stack *fs); +Function_Stack* setArgumentNumber(Function_Stack *fs, int arg); Constant_Stack *Push(TableNode *type, void *value, bool isConst); -Context_stack *PushContext(int context,TableNode *typeToCompare); +Context_stack *PushContext(/*int context,*/TableNode *typeToCompare); Function_Stack *PushFunction(int arg, TableNode* FunctionType); Constant_Stack *Pop(); Context_stack *PopContext(); +Function_Stack* setFunctionType(Function_Stack *fs, TableNode* functionType); Function_Stack *PopFunction(); TableNode* getFunctionTypeContext(Function_Stack *fs); -int getContextType(Context_stack *cs); +TableNode* getFunctionType(Function_Stack *fs); +//int getContextType(Context_stack *cs); Constant_Stack *Print_Stack(); int getArgumentNumber(Function_Stack *fs); AdInfo *CreatePrimitiveInfo(int size); @@ -198,6 +203,7 @@ ListOfTable *getRestOfChildren(ListOfTable *lt); TableNode *getFirstEntry(SymbolTable *st); TableNode *getNextEntry(TableNode *tn); TableNode *printTableNode(TableNode *tn); +TableNode *getContextTypeEntry(Context_stack *cs); extern int yylex(void); extern char *yytext; From 9d1217993dff44c0d73ab102db5d714dd57a6f92 Mon Sep 17 00:00:00 2001 From: Annie Date: Tue, 6 May 2025 23:14:11 -0400 Subject: [PATCH 105/109] ors seem to work --- src/codegen.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/codegen.c b/src/codegen.c index 44d39df..67a625f 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -527,7 +527,23 @@ int generateAssign(Instruction *inst) { //add option for constant assignment (should be easy) if (isConst(op1) == true) { - fprintf(cg_flag, "\tmovl\t$%d, %d(%%rbp)\t#constant assign\n", getConst(op1), getAddress(cg)); + char *movtype; + char *reg; + TableNode *typetn = getTypeEntry(getResult(inst)); + if (typetn == integ) { + movtype = "movl"; + reg = "%eax"; + } else if (typetn == boo) { + movtype = "movb"; + reg = "%al"; + } else if (typetn == chara) { + movtype = "movb"; + reg = "%al"; + } else { + movtype = "movq"; + reg = "%rax"; + } + fprintf(cg_flag, "\t%s\t$%d, %d(%%rbp)\t#constant assign\n",movtype, getConst(op1), getAddress(cg)); return 0; } From a95930c0e575c80e231512778c0a21d4b6422a56 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 6 May 2025 23:32:43 -0400 Subject: [PATCH 106/109] read --- README.MD | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.MD b/README.MD index 74270bf..365595f 100644 --- a/README.MD +++ b/README.MD @@ -72,7 +72,7 @@ GenX is our preprocessor tool. It is able to handle `#include` statements within ## Other Notes: -### Lexical Analyzer +### Lexical Analyzer: **Undefined Behavior:**
* Spaces are not required between tokens. For instance, an INTEGER and an ID are valid even if there is no space between them ``` @@ -80,4 +80,10 @@ Input: *5variable* Output: 2 14 301 "5" 1 1 101 "variable" ``` -* Added an `#include` token to stop syntax errors from being reported on certain alpha files. \ No newline at end of file +* Added an `#include` token to stop syntax errors from being reported on certain alpha files. + +### CG/IR Not Implemented: +* Arrays +* And conditionals not tested +* While loops may or may not be working (More testing needed) +* *...and other small issues* \ No newline at end of file From cfb3d9d08e46ee1e9e4e5f2adacad0c86313aab8 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Tue, 6 May 2025 23:49:01 -0400 Subject: [PATCH 107/109] final submission --- src/codegen.c | 38 ++++++++++++++++++++++------ tests/programs/sp3_if_else_sse.alpha | 10 ++++---- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 67a625f..9baafd4 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -588,7 +588,7 @@ int generateCondGoto(Instruction *inst) { int generateIfTrue(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); - + if (op1 == NULL) { printdebug("%sgenerateIfTrue failed, NULL operand", COLOR_RED); return -1; @@ -606,7 +606,7 @@ int generateIfTrue(Instruction *inst) { int generateIfFalse(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); - + if (op1 == NULL) { printdebug("%sgenerateIfFalse failed, NULL operand", COLOR_RED); return -1; @@ -618,7 +618,7 @@ int generateIfFalse(Instruction *inst) { return -1; } - fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#if false start\n", getAddress(cg)); + fprintf(cg_flag, "\tcmpb\t$0, %d(%%rbp)\t#if false start\n", getAddress(cg)); fprintf(cg_flag, "\tje\t.L%d\t\t#if false end\n", getLabel(inst)); } @@ -690,9 +690,31 @@ int generateEqualTo(Instruction *inst) { printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2))); return -1; } + char *movtype; + char *reg; + char *cmptype; + TableNode *typetn = getTypeEntry(getTN(op1)); + if (typetn == integ) { + movtype = "movl"; - 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)); + cmptype = "cmpl"; + reg = "%eax"; + } else if (typetn == boo) { + cmptype = "cmpb"; + movtype = "movb"; + reg = "%al"; + } else if (typetn == chara) { + cmptype = "cmpb"; + movtype = "movb"; + reg = "%al"; + } else { + cmptype = "cmpq"; + movtype = "movq"; + reg = "%rax"; + } + + fprintf(cg_flag, "\t%s\t%d(%%rbp), %s\t#equal to start\n", movtype, getAddress(op1CG), reg); + fprintf(cg_flag, "\t%s\t%d(%%rbp), %s\n", cmptype, getAddress(op2CG), reg); fprintf(cg_flag, "\tsete\t%%al\n"); fprintf(cg_flag, "\tmovb\t$0, %d(%%rbp)\n", getAddress(cg)); fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#equal to end\n", getAddress(cg)); @@ -734,7 +756,7 @@ int generateCall(Instruction *inst) { // } //now for the return CGNode *cg = findCG(getResult(inst)); - + if (cg == NULL) { cg = addCG(getResult(inst), offset); } @@ -757,7 +779,7 @@ int generateReturn(Instruction *inst) { printdebug("generateReturn failed, trying to return %s not in CGList", getName(getTN(op1))); return -1; } - if (table_lookup(getAncestor(cur), getName(getTN(op1))) != undefined) { + if (table_lookup(getAncestor(cur), getName(getTN(op1))) != undefined) { fprintf(cg_flag, "\tmovl\t$%s,%%eax\t#return a function\n", getName(getTN(op1))); } else { fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#return %s\n", getAddress(cg), getName(getTN(op1))); @@ -812,7 +834,7 @@ int generateParam(Instruction *inst) { default: align(getTN(op1)); offset += getPrimSize(getTypeEntry(getTN(op1))); - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#adding param start\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#adding param start\n", getAddress(op1CG)); fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#adding param end\n", offset - getPrimSize(getTypeEntry(getTN(op1)))); } return 0; diff --git a/tests/programs/sp3_if_else_sse.alpha b/tests/programs/sp3_if_else_sse.alpha index c78ce35..b55f061 100644 --- a/tests/programs/sp3_if_else_sse.alpha +++ b/tests/programs/sp3_if_else_sse.alpha @@ -15,9 +15,9 @@ bar (r,s) := { *) entry (arg) := { [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t; integer: c] - x := true; - y := true; - if ( x | y ) then { + x := false; + y := false; + if ( (x | y) | !( y = x ) ) then { (* if ( x Date: Wed, 7 May 2025 00:11:41 -0400 Subject: [PATCH 108/109] fixed grammar issues with reserve and release --- src/grammar.y | 18 ++++++++++--- src/symbol_table.c | 52 +++++++++++++++++++------------------- tests/programs/array.alpha | 3 +-- 3 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index fa74029..085afda 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -687,7 +687,8 @@ simple_statement: //updating context for reserve/release if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY || getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ PushContext(getTypeEntry((TableNode*)$1)); - printdebug("pushed %s to context stack in simple statement assignable rule\n",getName(getTypeEntry((TableNode*)$1))); + + printf("pushed %s to context stack in simple statement assignable rule\n",getName(getContextTypeEntry(context_head))); } S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); @@ -1196,14 +1197,23 @@ expression: emit_reserve(node, tn_or_const(NODE,$2)); $$ = node; } - if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head))) + else if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head))) && (getAdInfoType(getContextTypeEntry(context_head)) == TYPE_ARRAY_TYPE)){ char* temp = temp_var_gen(); //does this have integer? TableNode* node = CreateEntry(cur,TYPE_ARRAY, getContextTypeEntry(context_head), temp, NULL); emit_reserve(node, tn_or_const(NODE,$2)); $$ = node; - }else{ + }else if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head))) + && (getAdInfoType(getContextTypeEntry(context_head)) == TYPE_ARRAY_TYPE)){ + char* temp = temp_var_gen(); + //does this have integer? + TableNode* node = CreateEntry(cur,TYPE_ARRAY, getContextTypeEntry(context_head), temp, NULL); + emit_reserve(node, tn_or_const(NODE,$2)); + $$ = node; + }else{ + printf("%s on right %s on left\n",getType((TableNode*)$2),getName(getArrType(getContextTypeEntry(context_head)))); + printf("%s is the name of the left\n",getName(getContextTypeEntry(context_head))); $$ = undefined; } } @@ -1218,7 +1228,7 @@ expression: emit_release((TableNode*)$2); $$ = node; } - if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head))) + else if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head))) && (getAdInfoType(getContextTypeEntry(context_head)) == TYPE_ARRAY_TYPE)){ char* temp = temp_var_gen(); //does this have integer? diff --git a/src/symbol_table.c b/src/symbol_table.c index bdf0c08..a1f457f 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -283,7 +283,7 @@ TableNode *getContextTypeEntry(Context_stack *cs) { return undefined; } TableNode* tn = cs->typeToCompare; - return NULL; + return tn; } Constant_Stack *Pop() { if (head == NULL) { @@ -1056,31 +1056,31 @@ SymbolTable *init(SymbolTable *start) { chara = (TableNode *)calloc(1, sizeof(TableNode)); stri = (TableNode *)calloc(1, sizeof(TableNode)); boo = (TableNode *)calloc(1, sizeof(TableNode)); - TableNode *reservetype = (TableNode *)calloc(1, sizeof(TableNode)); - TableNode *reserve = (TableNode *)calloc(1, sizeof(TableNode)); - TableNode *releasetype = (TableNode *)calloc(1, sizeof(TableNode)); - TableNode *release = (TableNode *)calloc(1, sizeof(TableNode)); + //TableNode *reservetype = (TableNode *)calloc(1, sizeof(TableNode)); + //TableNode *reserve = (TableNode *)calloc(1, sizeof(TableNode)); + //TableNode *releasetype = (TableNode *)calloc(1, sizeof(TableNode)); + //TableNode *release = (TableNode *)calloc(1, sizeof(TableNode)); // TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); start->entries = integ; integ->next = addr; addr->next = chara; chara->next = stri; stri->next = boo; - boo->next = reservetype; - reservetype->next = reserve; - reserve->next = releasetype; - releasetype->next = release; - release->next = NULL; + boo->next = NULL;//reservetype; + //reservetype->next = reserve; + //reserve->next = releasetype; + //releasetype->next = release; + //release->next = NULL; integ->theName = "integer"; addr->theName = "address"; chara->theName = "character"; boo->theName = "Boolean"; stri->theName = "string"; - reserve->theName = "reserve"; - reservetype->theName = "reserve type"; - releasetype->theName = "release type"; - release->theName = "release"; + //reserve->theName = "reserve"; + //reservetype->theName = "reserve type"; + //releasetype->theName = "release type"; + //release->theName = "release"; // arr->theName= "array" // root TableNode that all are pointing to but not in table @@ -1147,10 +1147,10 @@ SymbolTable *init(SymbolTable *start) { chara->theType = prime; stri->theType = arrayprim; boo->theType = prime; - reserve->theType = reservetype; - reservetype->theType = funtypeprime; - releasetype->theType = funtypeprime; - release->theType = releasetype; + //reserve->theType = reservetype; + //reservetype->theType = funtypeprime; + //releasetype->theType = funtypeprime; + //release->theType = releasetype; // arr->theType=arrayprim; @@ -1164,20 +1164,20 @@ SymbolTable *init(SymbolTable *start) { chara->additionalinfo = CreatePrimitiveInfo(SIZE_CHAR); stri->additionalinfo = CreateArrayInfo(1, chara); boo->additionalinfo = CreatePrimitiveInfo(SIZE_BOOL); - reserve->additionalinfo = CreateFunctionDeclarationInfo(0, false, NULL); - reservetype->additionalinfo = CreateFunctionTypeInfo(integ, addr); - releasetype->additionalinfo = CreateFunctionTypeInfo(addr, integ); - release->additionalinfo = CreateFunctionDeclarationInfo(0, false, NULL); + //reserve->additionalinfo = CreateFunctionDeclarationInfo(0, false, NULL); + //reservetype->additionalinfo = CreateFunctionTypeInfo(integ, addr); + //releasetype->additionalinfo = CreateFunctionTypeInfo(addr, integ); + //release->additionalinfo = CreateFunctionDeclarationInfo(0, false, NULL); integ->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for integ addr->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for addr chara->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for chara stri->tag = TYPE_ARRAY_TYPE; // explicitly set the type for stri boo->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for boo - reserve->tag = TYPE_FUNCTION_DECLARATION; - reservetype->tag = TYPE_FUNCTION_TYPE; - releasetype->tag = TYPE_FUNCTION_TYPE; - release->tag = TYPE_FUNCTION_DECLARATION; + //reserve->tag = TYPE_FUNCTION_DECLARATION; + //reservetype->tag = TYPE_FUNCTION_TYPE; + //releasetype->tag = TYPE_FUNCTION_TYPE; + //release->tag = TYPE_FUNCTION_DECLARATION; // addr->additionalinfo = CreatePrimitiveInfo(8); start->Line_Number = 1; diff --git a/tests/programs/array.alpha b/tests/programs/array.alpha index 9022f19..55841e9 100644 --- a/tests/programs/array.alpha +++ b/tests/programs/array.alpha @@ -1,5 +1,4 @@ -#include "std.alpha" - +#include "../../library/std.alpha" type main: string -> integer function entry: main From 0811aa0345c586ed426e6a5deb2d08026fba9bbb Mon Sep 17 00:00:00 2001 From: Partho Date: Wed, 7 May 2025 00:21:23 -0400 Subject: [PATCH 109/109] did a little clean up. Note- I don't think reserve is being linked through the library --- src/grammar.y | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 085afda..c350b72 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -688,7 +688,7 @@ simple_statement: if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY || getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ PushContext(getTypeEntry((TableNode*)$1)); - printf("pushed %s to context stack in simple statement assignable rule\n",getName(getContextTypeEntry(context_head))); + //printf("pushed %s to context stack in simple statement assignable rule\n",getName(getContextTypeEntry(context_head))); } S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); @@ -1204,16 +1204,9 @@ expression: TableNode* node = CreateEntry(cur,TYPE_ARRAY, getContextTypeEntry(context_head), temp, NULL); emit_reserve(node, tn_or_const(NODE,$2)); $$ = node; - }else if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head))) - && (getAdInfoType(getContextTypeEntry(context_head)) == TYPE_ARRAY_TYPE)){ - char* temp = temp_var_gen(); - //does this have integer? - TableNode* node = CreateEntry(cur,TYPE_ARRAY, getContextTypeEntry(context_head), temp, NULL); - emit_reserve(node, tn_or_const(NODE,$2)); - $$ = node; - }else{ - printf("%s on right %s on left\n",getType((TableNode*)$2),getName(getArrType(getContextTypeEntry(context_head)))); - printf("%s is the name of the left\n",getName(getContextTypeEntry(context_head))); + }else{ + //printf("%s on right %s on left\n",getType((TableNode*)$2),getName(getArrType(getContextTypeEntry(context_head)))); + //printf("%s is the name of the left\n",getName(getContextTypeEntry(context_head))); $$ = undefined; } }