From e0c577a7ef2d8fdc779fdb6f784e6a93b12bb046 Mon Sep 17 00:00:00 2001 From: Partho Date: Wed, 23 Apr 2025 18:49:09 -0400 Subject: [PATCH 1/6] updated grammar to pass up instances. Still need IR to compile to properly emit --- src/grammar.y | 327 +++++++++++++++++++--------- src/lexicalStructure.lex | 4 +- src/symbol_table.c | 73 +++++++ src/symbol_table.h | 10 +- tests/sprint2/test/sp2_simple.alpha | 2 +- 5 files changed, 305 insertions(+), 111 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index a7d173e..110ffb4 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -29,6 +29,7 @@ %union { int integ; char* words; + char letter; void* tn; } @@ -538,30 +539,22 @@ WHILE L_PAREN expression R_PAREN sblock { simple_statement: assignable ASSIGN expression - { + { printdebug("simple statement"); TableNode* node; - if((getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE_TYPE|| - getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE|| - getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE|| - getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_TYPE)){ - node = (TableNode*)$1; - }else if((getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION)|| + if((getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION)|| (getAdInfoType((TableNode*)$1) == TYPE_ARRAY)|| (getAdInfoType((TableNode*)$1) == TYPE_RECORD)|| (getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE)){ - - node = getTypeEntry((TableNode*)$1); + + node = ((TableNode*)$1); } else{ error_type(undefined, undefined, "Invalid type passed to assignable."); node = undefined; } - if((getAdInfoType(node) == TYPE_ARRAY_TYPE|| - getAdInfoType(node) == TYPE_RECORD_TYPE) && - (strcmp(getName((TableNode*)$3),"address") == 0)){ - printdebug("%s[☺] Passed array/record type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3)); - } - else if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){ + + if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){ + //EMIT ASSIGN INSTRUCTION HERE printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3)); } else { error_type(node, (TableNode*)$3, ""); @@ -571,7 +564,7 @@ simple_statement: } -| RETURN expression {$$ = $2;} +| RETURN expression {$$ = getTypeEntry((TableNode*)$2);} ; @@ -592,6 +585,7 @@ ablock: 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); @@ -618,160 +612,188 @@ expression: | SUB_OR_NEG expression %prec UMINUS { printdebug("negative expression"); - if((TableNode*)$2 != integ) { - printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column); - $$=undefined; + if(getTypeEntry((TableNode*)$2) == integ) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of unary operation + $$ = node; } else { - $$=(TableNode*)$2; + $$=undefined; + error_type(getTypeEntry((TableNode*)$2), integ, ""); } } | NOT expression { printdebug("not expression"); - if((TableNode*)$2 == boo) { - $$=(TableNode*)$2; + if(getTypeEntry((TableNode*)$2) == boo) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of unary operation + $$ = node; } else { $$=undefined; - error_type((TableNode*)$2, boo, ""); + error_type(getTypeEntry((TableNode*)$2), boo, ""); } } | expression ADD expression { printdebug("add expression"); - if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { - $$=(TableNode*)$1; + if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of binary operation + $$ = node; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression SUB_OR_NEG expression { printdebug("sub or neg expression"); - if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { - $$=(TableNode*)$1; + if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of binary operation + $$ = node; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression MUL expression { printdebug("multiply expression"); - if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { - $$=(TableNode*)$1; - } else{ + if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of binary operation + $$ = node; + } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression DIV expression { printdebug("divide expression"); - if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && ((TableNode*)$1 == integ)) { - $$=(TableNode*)$1; + if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of binary operation + $$ = node; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression REM expression { printdebug("remainder expression"); - if($1 == $3 && $1 == integ) { - $$=$1; + if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of binary operation + $$ = node; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression AND expression { - printdebug("AND expression"); - if($1 == $3 && $1 == boo){ - $$=$1; - } else{ + printdebug("AND"); + 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); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of comparison + $$ = node; + } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression OR expression { printdebug("OR"); - if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && $1 == boo) { - $$=$1; + 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); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of comparison + $$ = node; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression LESS_THAN expression { printdebug("less than expression"); - if($1 == $3 && $1==integ) { - $$=boo; + 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); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of comparison + $$ = node; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression EQUAL_TO expression { printdebug("equals check expression"); - if($1 == $3 && $1 != undefined) { - $$=boo; + 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); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of compariosn + $$ = node; + } else { $$ = undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | assignable { - printdebug("assignable expression. current type is %s",getName((TableNode*)$1)); - if(getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE|| - getAdInfoType((TableNode*)$1) == TYPE_ARRAY || - getAdInfoType((TableNode*)$1) == TYPE_RECORD){ - printdebug("assignable passing up to expression is primitive, array instance, or record instance. Passing up its type"); - $$= getTypeEntry((TableNode*)$1); - } - - else if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE|| - getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE|| - getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_TYPE|| - getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE_TYPE || - getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ - printdebug("assignable passing up to expression is array type, record type, function type, or function declaration"); - $$= ((TableNode*)$1); - } - else { - error_type(undefined, undefined, "Invalid type passed to expression."); - $$= ((TableNode*)$1); - } - + $$ = $1; } | L_PAREN expression R_PAREN { - printdebug("paren expression. current type is %s",getName((TableNode*)$2)); + printdebug("paren expression. current type is %s",getType((TableNode*)$2)); $$=$2; } | memOp assignable { int d = getAdInfoType((TableNode*)$2); - if(d == TYPE_ARRAY_TYPE || d == TYPE_ARRAY || d == TYPE_RECORD_TYPE || d == TYPE_RECORD) { - $$ = addr; + 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 { error_type(undefined, undefined, "Invalid memOp expression (%s).", getName((TableNode*)$2)); $$=undefined; @@ -788,8 +810,9 @@ expression: assignable: ID { - $$ = getTypeEntry(look_up(cur,$1)); - printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getName((TableNode*)$$), $1); + TableNode* pass = look_up(cur,$1); + $$ = pass; + printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getType(pass), getName(pass)); } | assignable @@ -797,22 +820,24 @@ assignable: printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); cur = CreateScope(cur, -1,-1); } + //we have to consider emmissions in ablocks ablock { - int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); + //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); - if (look_up(getParent(cur), getName((TableNode*)$1))->additionalinfo->FunDecAdInfo->regularoras) { + 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)))); + //printdebug("%s", getType(look_up(cur, getName((TableNode*)$1)))); - TableNode * typeNode = $1; + TableNode * typeNode = getTypeEntry((TableNode*)$1); TableNode *param = getParameter(typeNode); printTableNode(param); @@ -853,7 +878,7 @@ assignable: } } } else { - char *expected = getName(getParameter(look_up(getParent(cur), getName((TableNode*)$1)))); + 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); @@ -862,29 +887,99 @@ assignable: printdebug("expected 1 argument but got %d", $3); } } - printTableNode(getReturn($1)); - $$ = getReturn($1); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); + printTableNode(getReturn(getTypeEntry((TableNode*)$1))); + // + char* temp = temp_var_gen(); + TableNode* typeNode2 = getReturn(getTypeEntry($1)); + int t = -1; + if(getAdInfoType(typeNode2) == TYPE_PRIMITIVE_TYPE){ + t = TYPE_PRIMITIVE; + } + else if(getAdInfoType(typeNode2) == TYPE_ARRAY_TYPE){ + t = TYPE_ARRAY; + } + else if(getAdInfoType(typeNode2) == TYPE_RECORD_TYPE){ + t = TYPE_RECORD; + } + else if(getAdInfoType(typeNode2) == TYPE_FUNCTION_TYPE){ + t = TYPE_FUNCTION_DECLARATION; + }else{ + t= TYPE_UNDEFINED; + printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper."); + } + TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL); + $$ = node; + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK for function call) + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName(typeNode2), getName((TableNode*)$1)); } else if (type == TYPE_ARRAY_TYPE) { printdebug("%sEntering array call", COLOR_LIGHTGREEN); - if (getNumArrDim(look_up(getParent(cur), getName((TableNode*)$1))) != $2) { + 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); } - $$ = getArrType(look_up(cur, getName((TableNode*)$1))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); + + char* temp = temp_var_gen(); + TableNode* typeNode2 = getArrType(look_up(getAncestor(cur), getType((TableNode*)$1))); + int t = -1; + if(getAdInfoType(typeNode2) == TYPE_PRIMITIVE_TYPE){ + t = TYPE_PRIMITIVE; + } + else if(getAdInfoType(typeNode2) == TYPE_ARRAY_TYPE){ + t = TYPE_ARRAY; + } + else if(getAdInfoType(typeNode2) == TYPE_RECORD_TYPE){ + t = TYPE_RECORD; + } + else if(getAdInfoType(typeNode2) == TYPE_FUNCTION_TYPE){ + t = TYPE_FUNCTION_DECLARATION; + }else{ + t= TYPE_UNDEFINED; + printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper."); + } + TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL); + //emit assign here + //emit_array_access(char* node, char* array, ...) + $$ = node; + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getType((TableNode*)$1), getName((TableNode*)$1)); } cur = getParent(cur); } | assignable rec_op ID - { - if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName((TableNode*)$1))), $3)) { + { + if(getAdInfoType((TableNode*)$1) != TYPE_RECORD_TYPE){ + printdebug("CHANGE ME [TYPE CHECK]Invalid type passed to record access"); + } + else if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3)) { - $$ = table_lookup(getRecList(table_lookup(getAncestor(cur), getName((TableNode*)$1))), $3); + TableNode* type = 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){ + t = TYPE_PRIMITIVE; + } + else if(getAdInfoType(type) == TYPE_ARRAY_TYPE){ + t = TYPE_ARRAY; + } + else if(getAdInfoType(type) == TYPE_RECORD_TYPE){ + t = TYPE_RECORD; + } + else if(getAdInfoType(type) == TYPE_FUNCTION_TYPE){ + t = TYPE_FUNCTION_DECLARATION; + }else{ + t= TYPE_UNDEFINED; + printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper."); + } + + 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) + $$=node; + }else{ + printdebug("CHANGE ME [TYPE CHECK] undefined type (Field Access Lookup failed)"); + $$=undefined; } - printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", getName((TableNode*)($$)), getName($1)); + printdebug("[ASSIGNABLE - RULE 3] record = name: %s | field = %s", getName((TableNode*)($1)), getName((TableNode*)$3)); } ; @@ -908,38 +1003,56 @@ memOp: constant: C_STRING { - $$ = $1; - printdebug("string of C_STRING in constant is %s",getName((TableNode*)$1)); + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, stri, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + printdebug("string of C_STRING in constant is %s", $1); + $$ = node; } | C_INTEGER { - $$ = integ; - printdebug("string of C_INTEGER in constant is integer"); + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + printdebug("number of C_INTEGER in constant is %d", $1); + $$ = node; } | C_NULL { - $$ = $1; - printdebug("string of C_NULL in constant is %s",getName((TableNode*)$1)); + 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) + printdebug("string of C_NULL in constant is NULL"); + $$ = node; } | C_CHARACTER { - $$ = $1; - printdebug("string of C_CHARACTER in constant is %s",getName((TableNode*)$1)); + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, chara, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + printdebug("string of C_CHARACTER in constant is %s",$1); + $$ = node; } | C_TRUE { - $$ = $1; - printdebug("string of C_TRUE in constant is %s",getName((TableNode*)$1)); + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + printdebug("string of C_TRUE in constant is true"); + $$ = node; } | C_FALSE { - $$ = $1; - printdebug("string of C_FALSE in constant is %s",getName((TableNode*)$1)); + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + printdebug("string of C_FALSE in constant is false"); + $$ = node; } ; diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index e11ef39..5e54f55 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -83,8 +83,8 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "->" {if(DEBUG) {printf( "ARROW: %s (%d)\n", yytext, ARROW);} else {if(tok_flag != NULL){print_tok(ARROW);}incr(line_number,column_number,ARROW);return ARROW;}} {DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {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(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);yylval.tn = chara;return C_CHARACTER;}} -\"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);yylval.tn = stri;return C_STRING;}} +'{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {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(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {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(DEBUG) {printf( "COMMENT: %s (%d)\n", yytext, COMMENT);} else {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/}} "(" {if(DEBUG) {printf( "L_PAREN: %s (%d)\n", yytext, L_PAREN);} else {if(tok_flag != NULL){print_tok(L_PAREN);}incr(line_number,column_number,L_PAREN);return L_PAREN;}} diff --git a/src/symbol_table.c b/src/symbol_table.c index 21669b5..de7d3f6 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -3,6 +3,9 @@ #include "symbol_table.h" +Constant_Stack* head = NULL; +int temp2_count = 0; + void printdebug_impl(char *file, int line, const char *format, ...) { if (DEBUG) { printf("%s<%s> [%d]%s ", COLOR_DARKGRAY, file, line, @@ -15,6 +18,76 @@ void printdebug_impl(char *file, int line, const char *format, ...) { } } +char * temp_var_gen(){ + char * ret = calloc(9, sizeof(*ret)); + sprintf(ret, "$t%d", temp2_count); + temp2_count++; + return ret; +} + +Constant_Stack *Push(TableNode *type, void *value, bool isConst) { + if (type == NULL || type == undefined) { + printdebug( + "passed a NULL reference/undefined reference to " + "CreateConstantStack. Invalid."); + return NULL; + } + Constant_Stack *cs = (Constant_Stack *)malloc(sizeof(Constant_Stack)); + cs->theType = type; + cs->theValue = value; + cs->isConst = isConst; + if(head == NULL){ + head = cs; + cs->next = NULL; + }else{ + cs->next = head; + head = cs; + } + return cs; +} + +Constant_Stack *Pop() { + if (head == NULL) { + printf("cannot pop from an empty stack. Invalid.\n"); + return NULL; + } + Constant_Stack *cs = head; + head = head->next; + printf("Popped something of type %s\n", getName(cs->theType)); + return cs; +} + +Constant_Stack* Print_Stack(){ + if (head == NULL) { + printdebug("cannot print an empty stack. Invalid."); + return NULL; + } + Constant_Stack *cs = head; + while (cs != NULL) { + if(cs->theValue == NULL){ + printf("Type: %s, Value: NULL", getName(cs->theType)); + } + if(cs->theType == stri){ + printf("Type: %s, Value: %s\n", getName(cs->theType), *(char*)(cs->theValue)); + } + if(cs->theType == integ){ + 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); + } + if(cs->theType == boo){ + if(*(bool *)cs->theValue == true){ + printf("Type: %s, Value: true\n", getName(cs->theType));} + else{ + printf("Type: %s, Value: false\n", getName(cs->theType)); + } + } + cs = cs->next; + } + return cs; + } + // primitive additional info only stores the size of that type AdInfo *CreatePrimitiveInfo(int size) { AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); diff --git a/src/symbol_table.h b/src/symbol_table.h index 01d4458..6a41551 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -11,6 +11,13 @@ struct TableNode; +typedef struct Constant_Stack { + struct TableNode *theType; + void *theValue; + struct Constant_Stack *next; + bool isConst; +} Constant_Stack; + typedef struct { int size; } primitive_info; @@ -141,7 +148,7 @@ extern int line_number; extern int column_number; extern FILE *yyin; extern bool DEBUG; - +extern int temp2_count; extern TableNode *funprime; extern TableNode *arrayprim; extern TableNode *integ; @@ -152,6 +159,7 @@ extern TableNode *boo; extern TableNode *recprime; extern TableNode *funtypeprime; extern TableNode *undefined; +extern Constant_Stack *head; extern char *COLOR_RED; extern char *COLOR_GREEN; diff --git a/tests/sprint2/test/sp2_simple.alpha b/tests/sprint2/test/sp2_simple.alpha index 58934e6..4042a5a 100644 --- a/tests/sprint2/test/sp2_simple.alpha +++ b/tests/sprint2/test/sp2_simple.alpha @@ -3,5 +3,5 @@ function entry: main entry(arg) := { [integer : x] - return 0; + return 2; } \ No newline at end of file From f0d81ff5fdedb6ec54b639057755cbf42b1a98cb Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 25 Apr 2025 13:01:31 -0400 Subject: [PATCH 2/6] combined symbol table with IR in this branch --- src/grammar.y | 14 +- src/intermediate_code.c | 5 - src/intermediate_code.h | 3 +- src/runner.c | 3 +- src/runner.h | 1 + src/symbol_table.c | 390 +++++++++++++++++++++++++++++++++++++++- src/symbol_table.h | 152 ++++++++++++++++ 7 files changed, 552 insertions(+), 16 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 110ffb4..74d7e92 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1005,7 +1005,7 @@ constant: { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, stri, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + emit_assignment(node, tn_or_const(STRING,$1)); printdebug("string of C_STRING in constant is %s", $1); $$ = node; } @@ -1014,7 +1014,7 @@ constant: { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + emit_assignment(node, tn_or_const(INTEGER,&$1)); printdebug("number of C_INTEGER in constant is %d", $1); $$ = node; } @@ -1023,7 +1023,7 @@ constant: { 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) + emit_assignment(node, tn_or_const(ADDRESS,$1)); printdebug("string of C_NULL in constant is NULL"); $$ = node; } @@ -1032,7 +1032,7 @@ constant: { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, chara, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + emit_assignment(node, tn_or_const(CHARACTER,&$1)); printdebug("string of C_CHARACTER in constant is %s",$1); $$ = node; } @@ -1041,7 +1041,8 @@ constant: { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + uint_least8_t b = 1; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); printdebug("string of C_TRUE in constant is true"); $$ = node; } @@ -1050,7 +1051,8 @@ constant: { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + uint_least8_t b = 0; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); printdebug("string of C_FALSE in constant is false"); $$ = node; } diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 6ac5429..3ccec2c 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -1,9 +1,4 @@ -#include -#include "intermediate_code.h" -Instruction * begin; -Instruction * current; -char * temp = NULL; // TODO: this is here to bring your attention to the comment bellow. diff --git a/src/intermediate_code.h b/src/intermediate_code.h index fc3cdc4..2bb423a 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -2,8 +2,7 @@ // * Add Bison actions for arithmetic expressions: // - Addition: $$ = new_temp(); emit_binary_op($$, "ADD", $1, $3); // - Subtraction, multiplication, division, modulo -#include "runner.h" -#include + // these are from page 364 typedef enum { diff --git a/src/runner.c b/src/runner.c index 3fa35ca..9ca6cfa 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2,7 +2,7 @@ /* The Translators - Spring 2025 */ #include "runner.h" - +//Constant_Stack *head = NULL; int main(int argc, char *argv[]) { if (argc == 1) { fprintf(stderr, INVALID); @@ -121,6 +121,7 @@ int run(FILE *alpha) { if (st_flag != NULL) { print_symbol_table(top, st_flag); + //emit_as_file(stdout, begin); fclose(st_flag); } diff --git a/src/runner.h b/src/runner.h index 7989473..74a7ecf 100644 --- a/src/runner.h +++ b/src/runner.h @@ -64,6 +64,7 @@ TableNode *boo; TableNode *recprime; TableNode *funtypeprime; TableNode *undefined; +extern Instruction* begin; int main(int argc, char *argv[]); int check_flag(char *arg, char *alpha); diff --git a/src/symbol_table.c b/src/symbol_table.c index de7d3f6..5fe39c3 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -3,8 +3,13 @@ #include "symbol_table.h" -Constant_Stack* head = NULL; +Constant_Stack * head = NULL; int temp2_count = 0; +bool code_gen = true; +char* temp = NULL; +int label_count=0; +Instruction* begin = NULL; +Instruction* current = NULL; void printdebug_impl(char *file, int line, const char *format, ...) { if (DEBUG) { @@ -1143,7 +1148,6 @@ TableNode *look_up(SymbolTable *table, char *x) { x, getLine(table), getColumn(table)); return look_up(table->Parent_Scope, x); } - int col_widths[5] = {30, 8, 8, 35, 35}; void printline(FILE *file_ptr, bool b); void printline(FILE *file_ptr, bool b) { @@ -1556,3 +1560,385 @@ TableNode *printTableNode(TableNode *tn) { return tn; } +//________________________________________________________________________ + + +// 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 * get_result(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; + 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++; + 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){ + return; + } + switch(i->opcode){ + case E_LABEL: + // 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->operand2)); + 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; +} +*/ +char * label_gen(){ + char * ret = calloc( 9, sizeof(*ret)); + sprintf(ret, "L_%d", label_count); + label_count++; + return ret; +} \ No newline at end of file diff --git a/src/symbol_table.h b/src/symbol_table.h index 6a41551..4a9d88b 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -3,6 +3,8 @@ #include #include #include +#include +#include #define SIZE_INT 4 #define SIZE_ADDR 8 @@ -10,6 +12,7 @@ #define SIZE_BOOL 4 //TODO: Ask Carl what this size should be struct TableNode; +typedef struct TFList TFList; typedef struct Constant_Stack { struct TableNode *theType; @@ -176,3 +179,152 @@ extern char *COLOR_LIGHTBLUE; extern char *COLOR_LIGHTPURPLE; extern char *COLOR_LIGHTCYAN; extern char *COLOR_WHITE; +//_____________________________________________________________ +// 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 +} Op; + +typedef enum { + 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; +} TNConstUnion; + +typedef struct { + 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; + + Instruction * prev; + Instruction * next; +} Instruction; + + +typedef struct TFList { + Instruction * i; + TFList * next; +} TFList; + +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 + + +//int temp_count; +//int label_count; +//bool code_gen; +//Instruction * begin; +//Instruction * current; +//char * temp; + + + +TNodeOrConst * tn_or_const(Discriminant d, void * tnc); +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(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); + +// * Implement instruction array storage for backpatching +/* +Track 2: Control Flow & Boolean Expressions +* Implement backpatching infrastructure: +* Create truelist and falselist attributes for Boolean expressions +* Create control flow emission functions: +* Add Bison actions for control structures: +- if-then-else with backpatching +- while loops with backpatching +* Implement short-circuit Boolean operations (&&, ||, !) +* Add marker (M) nonterminal for recording instruction positions +*/ + + +/* +Track 3: Functions & Complex Types +* Implement function-related emission: +* Add Bison actions for the 'as' clause +* Create memory layout calculation functions: +- calculate_record_size(Record_Type* type) → returns bytes needed +- calculate_array_size(Array_Type* type, int dimensions[]) → returns total bytes +- calculate_field_offset(Record_Type* type, char* field_name) → returns offset +* Add Bison actions for arrays and records +*/ + +/* +Track 4: Memory Access & Integration +* Implement array and record access code: +- emit_field_access(char* result, char* record, char* field) +- emit_array_access(char* result, char* array, char* index, char* dimension) +* Add array dimension access (a._1, a._2, etc.) +* Implement bounds checking emission: +- emit_bounds_check(char* index, char* size, char* error_label) +* Create the code generation driver function +* Implement common error handling +* Document the complete intermediate instruction set +* Build integration test suite covering all language features +* Implement row-major/column-major array layout calculation +*/ \ No newline at end of file From 95c37db9ff79e3de1a98c123eda4cc2115b6ff84 Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 25 Apr 2025 13:37:32 -0400 Subject: [PATCH 3/6] fixing still --- src/grammar.y | 2 ++ src/runner.c | 2 +- src/symbol_table.c | 6 +++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 74d7e92..72aa3b3 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -615,6 +615,7 @@ expression: if(getTypeEntry((TableNode*)$2) == integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + emit_unary_op(E_NEG,node,tn_or_const(NODE,$2)); //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) //result of unary operation $$ = node; @@ -630,6 +631,7 @@ 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) //result of unary operation $$ = node; diff --git a/src/runner.c b/src/runner.c index 9ca6cfa..c10cd6a 100644 --- a/src/runner.c +++ b/src/runner.c @@ -121,7 +121,7 @@ int run(FILE *alpha) { if (st_flag != NULL) { print_symbol_table(top, st_flag); - //emit_as_file(stdout, begin); + emit_as_file(stdout, begin); fclose(st_flag); } diff --git a/src/symbol_table.c b/src/symbol_table.c index 5fe39c3..db7523e 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1601,6 +1601,7 @@ bool isConst(TNodeOrConst * tnc) { 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; @@ -1632,7 +1633,7 @@ static void emit_helper(void){ } else { current->next = inst; inst->prev = current; - inst->index = current->index++; + inst->index = current->index+1; current = inst; } } @@ -1661,6 +1662,7 @@ void emit_assignment(TableNode * target, TNodeOrConst * source){ } char * get_string(TNodeOrConst * tc){ + char * s; switch (tc->d) { case NODE: @@ -1670,10 +1672,12 @@ char * get_string(TNodeOrConst * tc){ case STRING: return tc->tnc_union->string; case INTEGER: + return getName(integ); s = calloc(10, sizeof(char)); sprintf(s, "%d", tc->tnc_union->integer); return s; case CHARACTER: + return getName(chara); s = calloc(2, sizeof(char)); sprintf(s, "%c", tc->tnc_union->character); return s; From 46d8a852a64b2cfdf1c59f958379c02f6502f844 Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 25 Apr 2025 15:36:31 -0400 Subject: [PATCH 4/6] trying to get annie's to work --- src/grammar.y | 28 +- src/intermediate_code.c | 1 + src/runner.c | 2 + src/runner.h | 5 +- src/symbol_table.c | 532 +++++++++++++++++- src/symbol_table.h | 39 +- .../sp3_integer_binary_op_typecheck.alpha | 2 +- 7 files changed, 581 insertions(+), 28 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 72aa3b3..00a294f 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -647,8 +647,7 @@ expression: if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of binary operation + emit_binary_op(E_ADD,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -662,8 +661,8 @@ expression: if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of binary operation + emit_binary_op(E_SUB,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); + $$ = node; } else { $$=undefined; @@ -677,8 +676,7 @@ expression: if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of binary operation + emit_binary_op(E_MUL,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -692,8 +690,7 @@ expression: if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of binary operation + emit_binary_op(E_DIV,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -707,8 +704,7 @@ expression: if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of binary operation + emit_binary_op(E_MOD,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -722,8 +718,7 @@ expression: 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); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of comparison + emit_binary_op(E_AND,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -737,8 +732,7 @@ expression: 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); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of comparison + emit_binary_op(E_OR,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -752,8 +746,7 @@ 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); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of comparison + emit_binary_op(E_LESS_THAN,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -767,8 +760,7 @@ 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); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of compariosn + 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 3ccec2c..6349054 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -5,6 +5,7 @@ // 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 * tn_or_const(Op op, void * tnc) { TNodeOrConst * count = calloc(1, sizeof(*count)); count->d = op; diff --git a/src/runner.c b/src/runner.c index c10cd6a..736be1c 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2,6 +2,8 @@ /* The Translators - Spring 2025 */ #include "runner.h" +FILE *ir_flag = NULL; +FILE *cg_flag = NULL; //Constant_Stack *head = NULL; int main(int argc, char *argv[]) { if (argc == 1) { diff --git a/src/runner.h b/src/runner.h index 74a7ecf..7e134f2 100644 --- a/src/runner.h +++ b/src/runner.h @@ -35,7 +35,8 @@ #include "../tmp/grammar.tab.h" #include "symbol_table.h" -extern int line_number, column_number; +extern int line_number; +extern int column_number; extern char *yytext; extern FILE *yyin; extern bool DEBUG; @@ -46,8 +47,6 @@ SymbolTable *cur; FILE *alpha_file; FILE *tok_flag = NULL; FILE *st_flag = NULL; -FILE *ir_flag = NULL; -FILE *cg_flag = NULL; FILE *asc_flag = NULL; bool tc_flag = false; bool DEBUG = false; diff --git a/src/symbol_table.c b/src/symbol_table.c index db7523e..4ec3e70 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -10,6 +10,9 @@ char* temp = NULL; int label_count=0; Instruction* begin = NULL; Instruction* current = NULL; +int offset = 0; +int currentsp = 0; +CGNode *cgList = NULL; void printdebug_impl(char *file, int line, const char *format, ...) { if (DEBUG) { @@ -1574,7 +1577,7 @@ TNodeOrConst * getOperand2(Instruction * i){ return i->operand2; } -TableNode * get_result(Instruction * i){ +TableNode * getResult(Instruction * i){ return i->result; } @@ -1672,12 +1675,10 @@ char * get_string(TNodeOrConst * tc){ case STRING: return tc->tnc_union->string; case INTEGER: - return getName(integ); s = calloc(10, sizeof(char)); sprintf(s, "%d", tc->tnc_union->integer); return s; case CHARACTER: - return getName(chara); s = calloc(2, sizeof(char)); sprintf(s, "%c", tc->tnc_union->character); return s; @@ -1690,11 +1691,12 @@ char * get_string(TNodeOrConst * tc){ } void emit_as_file(FILE * out_file, Instruction * i){ - if(!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: @@ -1752,7 +1754,7 @@ void emit_as_file(FILE * out_file, Instruction * i){ case E_ASSIGN: fprintf(out_file, "%4.d: %s = %s\n", i->index, getName(i->result), - get_string(i->operand2)); + get_string(i->operand1)); break; case E_GOTO: // are we ever going to use this? @@ -1945,4 +1947,524 @@ char * label_gen(){ sprintf(ret, "L_%d", label_count); label_count++; return ret; +} +//------------------------------------------------------------------------------------- +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: + ; + } + } + 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; +} +/* +movl $1, -4(%rbp) +add -4(%rbp), $2 +*/ +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; + cg->address = sp; + offset += getPrimSize(tn); //not sure if this is the correct amount to add to the 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 *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateAdd failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(op2); + 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\n", getAddress(op1CG)); + fprintf(cg_flag, "\taddl\t%d(\%rbp), \%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} + +int generateSub(Instruction *instruction) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateSub failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(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\n", getAddress(op1CG)); + fprintf(cg_flag, "\tsubl\t%d(\%rbp), \%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} + +int generateMult(Instruction *instruction){ + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateMult failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(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\n", getAddress(op1CG)); + fprintf(cg_flag, "\tsubl\t%d(\%rbp), \%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} + +int generateDiv(Instruction *instruction) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateDiv failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(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\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)\n", getAddress(cg)); //stores result + return 0; +} + +int generateMod(Instruction *instruction) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateMod failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(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\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)\n", getAddress(cg)); //stores result from edx (remainder) + return 0; +} + +int generateOr(Instruction *instruction) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateOr failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(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; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\torll\t%d(\%rbp), %eax\n", getAddress(op2CG));//divides edx by value accessed from stack + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); //stores result + return 0; +} + +int generateAnd(Instruction *instruction) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(op2); + if (op1CG == NULL) { + printdebug("generateNeg failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateNeg failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tandl\t%d(\%rbp), %eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} +int generateNeg(Instruction *instruction) { + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateNeg failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(op2); + if (op1CG == NULL) { + printdebug("generateNeg failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateNeg failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tnegl\t%d %eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} +int generateNot(Instruction *instruction) { + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateNot failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(op2); + if (op1CG == NULL) { + printdebug("generateNot failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateNot failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tnotl\t\%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} + +int generateAssign(Instruction *instruction) { + TNodeOrConst *op1 = getOperand1(inst); + CGNode *result = findCG(getResult(inst)); + + + if (op1 == NULL) { + printdebug("generateAssign failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + + //add option for constant assignment (should be easy) + + + CGNode *op1CG = findCG(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\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} + +int generateGoto(Instruction *instruction){ + return -1; +} + +int generateCondGoto(Instruciton *instruction) { + return -1; +} + +int generateIfTrue(Instruction *instruction){ + return -1; +} + +int generateIfFalse(Instruction *instruction){ + return -1; +} + +int generateLessThan(Instruction *instruction){ + return -1; +} +int generateEqualTo(Instruction *instruction){ + return -1; +} +int generateCall(Instruction *instruction){ + return -1; +} +int generateReturn(Instruction *instruction){ + return -1; +} +int generateCopyRight(Instruction *instruction){ + return -1; +} +int generateCopyLeft(Instruction *instruction){ + return -1; +} +int generateAddressOf(Instruction *instruction){ + return -1; +} +int generateParam(Instruction *instruction){ + return -1; } \ No newline at end of file diff --git a/src/symbol_table.h b/src/symbol_table.h index 4a9d88b..41138b8 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -13,6 +13,7 @@ struct TableNode; typedef struct TFList TFList; +typedef struct CGNode CGNode; typedef struct Constant_Stack { struct TableNode *theType; @@ -327,4 +328,40 @@ Track 4: Memory Access & Integration * Document the complete intermediate instruction set * Build integration test suite covering all language features * Implement row-major/column-major array layout calculation -*/ \ No newline at end of file +*/ +//------------------------------------------------------------- +extern FILE *cg_flag; +typedef struct CGNode { + TableNode *tn; + int address; + CGNode *next; +}CGNode; + +int generate(); +CGNode *getNextCG(CGNode *cg); +int getAddress(CGNode *cg); +TableNode *getTNofCG(CGNode *cg); +int generateLabel(Instruction *instruction); +int generateAdd(Instruction *instruction); +int generateSub(Instruction *instruction); +int generateMult(Instruction *instruction); +int generateDiv(Instruction *instruction); +int generateMod(Instruction *instruction); +int generateOr(Instruction *instruction); +int generateAnd(Instruction *instruction); +int generateNeg(Instruction *instruction); +int generateNot(Instruction *instruction); +int generateDiv(Instruction *instruction); +int generateAssign(Instruction *instruction); // is this for something like x = 1? +int generateGoto(Instruction *instruction); +int generateCondGoto(Instruction *instruction); +int generateIfTrue(Instruction *instruction); +int generateIfFalse(Instruction *instruction); +int generateLessThan(Instruction *instruction); +int generateEqualTo(Instruction *instruction); +int generateCall(Instruction *instruction); +int generateReturn(Instruction *instruction); +int generateCopyRight(Instruction *instruction); +int generateCopyLeft(Instruction *instruction); +int generateAddressOf(Instruction *instruction); +int generateParam(Instruction *instruction); \ No newline at end of file diff --git a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha index bc88a72..2adb394 100644 --- a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha @@ -7,7 +7,7 @@ entry (arg) := { [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a; rec : r] x := 3 + 2 * 8; - x := 3 - 2 / 8; + x := 3 - 2 / 8; x := a * 2 % 8; b2 := 3 * 2 % 8; x := 3 % 2 * 8; From 1999230265bac512c9aa8d190af15d77f5e57e8d Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 25 Apr 2025 16:55:27 -0400 Subject: [PATCH 5/6] got compilation to work --- cg.s | 44 +++++++ src/runner.c | 12 +- src/runner.h | 1 + src/symbol_table.c | 289 +++++++++++++++++++++++++++++---------------- 4 files changed, 241 insertions(+), 105 deletions(-) create mode 100644 cg.s diff --git a/cg.s b/cg.s new file mode 100644 index 0000000..47bbe30 --- /dev/null +++ b/cg.s @@ -0,0 +1,44 @@ + movl $3, 0(%rbp) + movl $2, 1(%rbp) + movl $8, 2(%rbp) + movl 1(%rbp), %eax + subl 2(%rbp), %eax + movl %eax, 3(%rbp) + movl 0(%rbp), %eax + addl 0(%rbp), %eax + movl %eax, 4(%rbp) + movl $3, 5(%rbp) + movl $2, 6(%rbp) + movl $8, 7(%rbp) + movl 6(%rbp), %eax + cltd + idivl 7(%rbp) + movl %eax, 8(%rbp) + movl 5(%rbp), %eax + subl 8(%rbp), %eax + movl %eax, 9(%rbp) + movl $2, 10(%rbp) + movl $8, 11(%rbp) + movl $3, 12(%rbp) + movl $2, 13(%rbp) + movl 12(%rbp), %eax + subl 13(%rbp), %eax + movl %eax, 14(%rbp) + movl $8, 15(%rbp) + movl 14(%rbp), %eax + cltd + idivl 15(%rbp) + movl %edx, 16(%rbp) + movl $3, 17(%rbp) + movl $2, 18(%rbp) + movl 17(%rbp), %eax + cltd + idivl 18(%rbp) + movl %edx, 19(%rbp) + movl $8, 20(%rbp) + movl 19(%rbp), %eax + subl 20(%rbp), %eax + movl %eax, 21(%rbp) + movl $3, 22(%rbp) + movl $8, 23(%rbp) + movl $0, 24(%rbp) diff --git a/src/runner.c b/src/runner.c index 736be1c..2253b73 100644 --- a/src/runner.c +++ b/src/runner.c @@ -3,7 +3,6 @@ #include "runner.h" FILE *ir_flag = NULL; -FILE *cg_flag = NULL; //Constant_Stack *head = NULL; int main(int argc, char *argv[]) { if (argc == 1) { @@ -38,6 +37,7 @@ int main(int argc, char *argv[]) { alpha_file = fopen(argv[argc - 1], "r"); } } + cg_flag = fopen("cg.s", "w"); return run(alpha_file); } @@ -125,6 +125,8 @@ int run(FILE *alpha) { print_symbol_table(top, st_flag); emit_as_file(stdout, begin); fclose(st_flag); + generate(); + fclose(cg_flag); } if (asc_flag != NULL) { @@ -141,10 +143,10 @@ int run(FILE *alpha) { fclose(ir_flag); } - if (cg_flag != NULL) { - printf("Flag -cg is not implemented yet\n"); - fclose(cg_flag); - } + //if (cg_flag != NULL) { + // printf("Flag -cg is not implemented yet\n"); + //fclose(cg_flag); + //} if (yyin != NULL) { fclose(yyin); diff --git a/src/runner.h b/src/runner.h index 7e134f2..503b319 100644 --- a/src/runner.h +++ b/src/runner.h @@ -48,6 +48,7 @@ FILE *alpha_file; FILE *tok_flag = NULL; FILE *st_flag = NULL; FILE *asc_flag = NULL; +FILE *cg_flag = NULL; bool tc_flag = false; bool DEBUG = false; int no_flag = 0; diff --git a/src/symbol_table.c b/src/symbol_table.c index 4ec3e70..441eb5c 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1948,10 +1948,24 @@ char * label_gen(){ label_count++; return ret; } + +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; +} //------------------------------------------------------------------------------------- int generate(){ offset = 0; - Instruction* i = begin; + Instruction *i = begin; while (i != NULL) { switch(getOp(i)) { case E_LABEL: @@ -2023,6 +2037,7 @@ int generate(){ default: ; } + i = i->next; } return -1; } @@ -2038,6 +2053,7 @@ int getAddress(CGNode *cg) { if (cg == NULL) { return -1; } + return currentsp - cg->address; } @@ -2047,10 +2063,7 @@ TableNode *getTNofCG(CGNode *cg) { } return cg->tn; } -/* -movl $1, -4(%rbp) -add -4(%rbp), $2 -*/ + CGNode *findCG(TableNode *tn) { CGNode *cg = cgList; while (cg != NULL) { @@ -2085,20 +2098,20 @@ int generateAdd(Instruction *inst) { */ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateAdd failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + 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; @@ -2109,9 +2122,9 @@ int generateAdd(Instruction *inst) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\taddl\t%d(\%rbp), \%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\taddl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } @@ -2121,21 +2134,21 @@ int generateSub(Instruction *instruction) { One immediate: Neither immediate: */ - TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + 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 (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(instruction), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + 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; @@ -2146,13 +2159,13 @@ int generateSub(Instruction *instruction) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tsubl\t%d(\%rbp), \%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } -int generateMult(Instruction *instruction){ +int generateMult(Instruction *inst){ /* Both immediate: One immediate: @@ -2160,18 +2173,18 @@ int generateMult(Instruction *instruction){ */ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateMult failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + 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; @@ -2182,13 +2195,13 @@ int generateMult(Instruction *instruction){ return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tsubl\t%d(\%rbp), \%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } -int generateDiv(Instruction *instruction) { +int generateDiv(Instruction *inst) { /* Both immediate: One immediate: @@ -2196,19 +2209,19 @@ int generateDiv(Instruction *instruction) { */ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateDiv failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + 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; @@ -2219,14 +2232,14 @@ int generateDiv(Instruction *instruction) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); //moves dividend into eax + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\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)\n", getAddress(cg)); //stores result + 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)\n", getAddress(cg)); //stores result return 0; } -int generateMod(Instruction *instruction) { +int generateMod(Instruction *inst) { /* Both immediate: One immediate: @@ -2234,18 +2247,18 @@ int generateMod(Instruction *instruction) { */ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateMod failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + 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; @@ -2256,14 +2269,14 @@ int generateMod(Instruction *instruction) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); //moves dividend into eax + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\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)\n", getAddress(cg)); //stores result from edx (remainder) + 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)\n", getAddress(cg)); //stores result from edx (remainder) return 0; } -int generateOr(Instruction *instruction) { +int generateOr(Instruction *inst) { /* Both immediate: One immediate: @@ -2271,19 +2284,19 @@ int generateOr(Instruction *instruction) { */ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateOr failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + 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; @@ -2294,13 +2307,13 @@ int generateOr(Instruction *instruction) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\torll\t%d(\%rbp), %eax\n", getAddress(op2CG));//divides edx by value accessed from stack - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); //stores result + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\torll\t%d(%%rbp), %%eax\n", getAddress(op2CG));//divides edx by value accessed from stack + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); //stores result return 0; } -int generateAnd(Instruction *instruction) { +int generateAnd(Instruction *inst) { /* Both immediate: One immediate: @@ -2308,50 +2321,50 @@ int generateAnd(Instruction *instruction) { */ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { - printdebug("generateNeg failed, op1 is not constant but not in CGlist"); + printdebug("generateAnd failed, op1 is not constant but not in CGlist"); return -1; } if (op2CG == NULL) { - printdebug("generateNeg failed, %s is not initialized/in CG", getName(getTN(op2))); + printdebug("generateAnd failed, %s is not initialized/in CG", getName(getTN(op2))); return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tandl\t%d(\%rbp), %eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tandl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } -int generateNeg(Instruction *instruction) { +int generateNeg(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateNeg failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { printdebug("generateNeg failed, op1 is not constant but not in CGlist"); return -1; @@ -2362,27 +2375,27 @@ int generateNeg(Instruction *instruction) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tnegl\t%d %eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tnegl\t%d %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } -int generateNot(Instruction *instruction) { +int generateNot(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateNot failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { printdebug("generateNot failed, op1 is not constant but not in CGlist"); return -1; @@ -2393,15 +2406,15 @@ int generateNot(Instruction *instruction) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tnotl\t\%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tnotl\t%%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } -int generateAssign(Instruction *instruction) { +int generateAssign(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL) { @@ -2409,22 +2422,25 @@ int generateAssign(Instruction *instruction) { return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + 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)\n", getConst(op1), getAddress(cg)); + } - CGNode *op1CG = findCG(op1); + 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\n", getAddress(op1CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } @@ -2432,29 +2448,101 @@ int generateGoto(Instruction *instruction){ return -1; } -int generateCondGoto(Instruciton *instruction) { +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 *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\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)\n", getAddress(cg)); + return 0; } -int generateEqualTo(Instruction *instruction){ - return -1; + +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\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)\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; @@ -2466,5 +2554,6 @@ 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; } \ No newline at end of file From f256a90e3e4d34d7559ca2984e80ba53d1b6a8a7 Mon Sep 17 00:00:00 2001 From: Moroseui <157774170+Moroseui@users.noreply.github.com> Date: Fri, 25 Apr 2025 17:21:49 -0400 Subject: [PATCH 6/6] deleted extra files --- cg.s | 44 ---------- check.sh | 0 src/intermediate_code.c | 188 ---------------------------------------- src/intermediate_code.h | 109 ----------------------- test.alpha | 29 ------- test.sh | 0 6 files changed, 370 deletions(-) delete mode 100644 cg.s mode change 100755 => 100644 check.sh delete mode 100644 src/intermediate_code.c delete mode 100644 src/intermediate_code.h delete mode 100644 test.alpha mode change 100755 => 100644 test.sh diff --git a/cg.s b/cg.s deleted file mode 100644 index 47bbe30..0000000 --- a/cg.s +++ /dev/null @@ -1,44 +0,0 @@ - movl $3, 0(%rbp) - movl $2, 1(%rbp) - movl $8, 2(%rbp) - movl 1(%rbp), %eax - subl 2(%rbp), %eax - movl %eax, 3(%rbp) - movl 0(%rbp), %eax - addl 0(%rbp), %eax - movl %eax, 4(%rbp) - movl $3, 5(%rbp) - movl $2, 6(%rbp) - movl $8, 7(%rbp) - movl 6(%rbp), %eax - cltd - idivl 7(%rbp) - movl %eax, 8(%rbp) - movl 5(%rbp), %eax - subl 8(%rbp), %eax - movl %eax, 9(%rbp) - movl $2, 10(%rbp) - movl $8, 11(%rbp) - movl $3, 12(%rbp) - movl $2, 13(%rbp) - movl 12(%rbp), %eax - subl 13(%rbp), %eax - movl %eax, 14(%rbp) - movl $8, 15(%rbp) - movl 14(%rbp), %eax - cltd - idivl 15(%rbp) - movl %edx, 16(%rbp) - movl $3, 17(%rbp) - movl $2, 18(%rbp) - movl 17(%rbp), %eax - cltd - idivl 18(%rbp) - movl %edx, 19(%rbp) - movl $8, 20(%rbp) - movl 19(%rbp), %eax - subl 20(%rbp), %eax - movl %eax, 21(%rbp) - movl $3, 22(%rbp) - movl $8, 23(%rbp) - movl $0, 24(%rbp) diff --git a/check.sh b/check.sh old mode 100755 new mode 100644 diff --git a/src/intermediate_code.c b/src/intermediate_code.c deleted file mode 100644 index 6349054..0000000 --- a/src/intermediate_code.c +++ /dev/null @@ -1,188 +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 * tn_or_const(Op op, void * tnc) { - TNodeOrConst * count = calloc(1, sizeof(*count)); - count->d = op; - switch (op) { - 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 = *(bool*)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++; - current = inst; - } -} - -void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2){ - emit_helper(); - current->opcode = op; - current->result = result; - current->operand1 = arg1; - current->operand2 = arg2; - return; - } - -void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){ - emit_helper(); - current->opcode = op; - current->result = result; - current->operand1 = arg; - return; - } - -void emit_assignment(TableNode * target, TNodeOrConst * source){ - emit_helper(); - current->opcode = E_ASSIGN; // TODO: replace with move - current->result = target; - current->operand1 = source; - return; - } - -void emit_as_file(FILE * out_file, Instruction * instr_arr){ - if(instr_arr == NULL){ - return; - } - - //fprintf(out_file, - return; -} - - -void emit_label(int label){ - emit_helper(); - current->opcode = E_LABEL; - current->label = label; - return; -} -void emit_jump(int label){ - emit_helper(); - current->opcode = E_GOTO; - current->label = label; - return; -} - -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_LESSTHEN: case E_EQUALTO: - n1 = va_arg(argptr, TNodeOrConst *); - n2 = va_arg(argptr, TNodeOrConst *); - current->operand1 = n1; - current->operand2 = n2; - break; - } - va_end(argptr); - return; -} - -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 - return; -} - -void emit_parameter(TNodeOrConst * param){ - emit_helper(); - current->opcode = E_PARAM; - current->operand1 = param; - return; -} - -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; - return; -} -void emit_return(TNodeOrConst * value){ - emit_helper(); - current->opcode = E_RETURN; - current->operand1 = value; - return; -} -void emit_reserve(char* result, char* type_name, int size){ - emit_helper(); - return; -} -void emit_release(char* pointer){ - emit_helper(); - return; -} - - -void emit_field_access(char* result, char* record, char* field){ - emit_helper(); - return; -} -void emit_array_access(char* result, char* array, char* index, char* dimension){ - emit_helper(); - return; -} -void emit_bounds_check(char* index, char* size, char* error_label){ - emit_helper(); - return; -} - - -// * 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); - label_count++; - return ret; -} diff --git a/src/intermediate_code.h b/src/intermediate_code.h deleted file mode 100644 index 2bb423a..0000000 --- a/src/intermediate_code.h +++ /dev/null @@ -1,109 +0,0 @@ -// Track 1: Core Infrastructure & Basic Expressions -// * Add Bison actions for arithmetic expressions: -// - Addition: $$ = new_temp(); emit_binary_op($$, "ADD", $1, $3); -// - Subtraction, multiplication, division, modulo - - -// 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_LESSTHEN, // 6 rule 1 + 5 - E_EQUALTO, // 6 rule 1 + 5 - E_CALL, // 7 - E_PARAM, // 7 - E_RETURN, // 7 - E_INDEX_COPY_RIGHT, // 8 - E_INDEX_COPY_LEFT, // 8 - E_ADDRESS_OF // 9 - /* for x = *y and *y = x we can just use index copy right and left with - index 0*/ -} Op; - -typedef enum { - 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; -} TNConstUnion; - -typedef struct { - 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; - - Instruction * prev; - Instruction * next; -} Instruction; - -extern Instruction * begin; -extern Instruction * current; -int temp_count = 0; -int label_count = 0; -bool code_gen = true; - - - -TNodeOrConst * tn_or_const(Op op, void * tnc); - -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); -// TODO: Find out what these are suposed to do. Guess is create an entry in -// the list of instructions. Guess is that its suposed to ret a struct ptr - -// * Implement integer/boolean/character specific operation handling -// TODO: Find out what this means. - -// * Create output function to write instructions to file with line formatting -void emit_as_file(FILE * out_file, Instruction * instr_arr); - -// * Implement instruction array storage for backpatching - -void emit_label(int label); -void emit_jump(int label); -void emit_conditional_jump(Op condition, int label, ...); - -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(char* result, char* type_name, int size); -void emit_release(char* pointer); - -void emit_field_access(char* result, char* record, char* field); -void emit_array_access(char* result, char* array, char* index, char* dimension); -void emit_bounds_check(char* index, char* size, char* error_label); diff --git a/test.alpha b/test.alpha deleted file mode 100644 index 7b06a5e..0000000 --- a/test.alpha +++ /dev/null @@ -1,29 +0,0 @@ - - - -type a : 1 -> integers -type t : integer -> a -type r : integer -> integer - - - -function foo : t -function bar : r -function entry : - -bar(a) := { - 5 + bar(a - 1); - return a * bar(a-1); -} - -foo(c) := { - [a: arg] - arg := reserve arg(c); - return arg; -} - -entry(args) := { - [a: b] - b := foo(8); -} - diff --git a/test.sh b/test.sh old mode 100755 new mode 100644