Merge branch 'Sprint4-Merge_IR_Into_Symbol_Table' into Sprint4-ASC_TC-FE-t#NoTask

This commit is contained in:
Scarlett
2025-04-25 17:49:25 -04:00
10 changed files with 1499 additions and 113 deletions

0
check.sh Executable file → Normal file
View File

View File

@ -38,6 +38,7 @@
%union { %union {
int integ; int integ;
char* words; char* words;
char letter;
void* tn; void* tn;
} }
@ -547,30 +548,22 @@ WHILE L_PAREN expression R_PAREN sblock {
simple_statement: simple_statement:
assignable ASSIGN expression assignable ASSIGN expression
{ { printdebug("simple statement");
TableNode* node; TableNode* node;
if((getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE_TYPE|| if((getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION)||
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)||
(getAdInfoType((TableNode*)$1) == TYPE_ARRAY)|| (getAdInfoType((TableNode*)$1) == TYPE_ARRAY)||
(getAdInfoType((TableNode*)$1) == TYPE_RECORD)|| (getAdInfoType((TableNode*)$1) == TYPE_RECORD)||
(getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE)){ (getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE)){
node = getTypeEntry((TableNode*)$1); node = ((TableNode*)$1);
} else{ } else{
printdebug("Invalid type passed to assignable."); printdebug("Invalid type passed to assignable.");
node = undefined; node = undefined;
} }
if((getAdInfoType(node) == TYPE_ARRAY_TYPE||
getAdInfoType(node) == TYPE_RECORD_TYPE) && if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){
(strcmp(getName((TableNode*)$3),"address") == 0)){ //EMIT ASSIGN INSTRUCTION HERE
printdebug("%s[☺] Passed array/record type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3));
}
else if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){
printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3)); printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3));
} else { } else {
throw_error(ERROR_TYPE, "%s != %s", getName(node), getName((TableNode*)$3)); throw_error(ERROR_TYPE, "%s != %s", getName(node), getName((TableNode*)$3));
@ -580,7 +573,7 @@ simple_statement:
} }
| RETURN expression {$$ = $2;} | RETURN expression {$$ = getTypeEntry((TableNode*)$2);}
; ;
@ -601,6 +594,7 @@ ablock:
argument_list: argument_list:
//NEED TO EMIT PARAMETERS HERE. MAYBE USE STACK STRUCTURE
expression COMMA argument_list expression COMMA argument_list
{ {
CreateEntry(cur,getAdInfoType((TableNode*)$1), (TableNode*)$1, getName((TableNode*)$1), NULL); CreateEntry(cur,getAdInfoType((TableNode*)$1), (TableNode*)$1, getName((TableNode*)$1), NULL);
@ -627,19 +621,29 @@ expression:
| SUB_OR_NEG expression %prec UMINUS | SUB_OR_NEG expression %prec UMINUS
{ {
printdebug("negative expression"); printdebug("negative expression");
if((TableNode*)$2 != integ) { if(getTypeEntry((TableNode*)$2) == integ) {
printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column); char* temp = temp_var_gen();
$$=undefined; 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;
} else { } else {
$$=(TableNode*)$2; $$=undefined;
error_type(getTypeEntry((TableNode*)$2), integ, "");
} }
} }
| NOT expression | NOT expression
{ {
printdebug("not expression"); printdebug("not expression");
if((TableNode*)$2 == boo) { if(getTypeEntry((TableNode*)$2) == boo) {
$$=(TableNode*)$2; 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;
} else { } else {
$$=undefined; $$=undefined;
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$2), getName(boo)); throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$2), getName(boo));
@ -649,8 +653,11 @@ expression:
| expression ADD expression | expression ADD expression
{ {
printdebug("add expression"); printdebug("add expression");
if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) {
$$=(TableNode*)$1; char* temp = temp_var_gen();
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL);
emit_binary_op(E_ADD,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3));
$$ = node;
} else { } else {
$$=undefined; $$=undefined;
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
@ -660,8 +667,12 @@ expression:
| expression SUB_OR_NEG expression | expression SUB_OR_NEG expression
{ {
printdebug("sub or neg expression"); printdebug("sub or neg expression");
if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) {
$$=(TableNode*)$1; char* temp = temp_var_gen();
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL);
emit_binary_op(E_SUB,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3));
$$ = node;
} else { } else {
$$=undefined; $$=undefined;
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
@ -671,8 +682,11 @@ expression:
| expression MUL expression | expression MUL expression
{ {
printdebug("multiply expression"); printdebug("multiply expression");
if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) {
$$=(TableNode*)$1; char* temp = temp_var_gen();
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL);
emit_binary_op(E_MUL,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3));
$$ = node;
} else { } else {
$$=undefined; $$=undefined;
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
@ -682,8 +696,11 @@ expression:
| expression DIV expression | expression DIV expression
{ {
printdebug("divide expression"); printdebug("divide expression");
if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && ((TableNode*)$1 == integ)) { if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) {
$$=(TableNode*)$1; char* temp = temp_var_gen();
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL);
emit_binary_op(E_DIV,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3));
$$ = node;
} else { } else {
$$=undefined; $$=undefined;
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
@ -693,8 +710,11 @@ expression:
| expression REM expression | expression REM expression
{ {
printdebug("remainder expression"); printdebug("remainder expression");
if($1 == $3 && $1 == integ) { if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) {
$$=$1; char* temp = temp_var_gen();
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL);
emit_binary_op(E_MOD,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3));
$$ = node;
} else { } else {
$$=undefined; $$=undefined;
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
@ -703,9 +723,12 @@ expression:
| expression AND expression | expression AND expression
{ {
printdebug("AND expression"); printdebug("AND");
if($1 == $3 && $1 == boo){ if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) {
$$=$1; char* temp = temp_var_gen();
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL);
emit_binary_op(E_AND,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3));
$$ = node;
} else { } else {
$$=undefined; $$=undefined;
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
@ -715,8 +738,11 @@ expression:
| expression OR expression | expression OR expression
{ {
printdebug("OR"); printdebug("OR");
if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && $1 == boo) { if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) {
$$=$1; char* temp = temp_var_gen();
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL);
emit_binary_op(E_OR,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3));
$$ = node;
} else { } else {
$$=undefined; $$=undefined;
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
@ -726,8 +752,11 @@ expression:
| expression LESS_THAN expression | expression LESS_THAN expression
{ {
printdebug("less than expression"); printdebug("less than expression");
if($1 == $3 && $1==integ) { if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==integ) {
$$=boo; char* temp = temp_var_gen();
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL);
emit_binary_op(E_LESS_THAN,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3));
$$ = node;
} else { } else {
$$=undefined; $$=undefined;
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
@ -737,8 +766,12 @@ expression:
| expression EQUAL_TO expression | expression EQUAL_TO expression
{ {
printdebug("equals check expression"); printdebug("equals check expression");
if($1 == $3 && $1 != undefined) { if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1) != undefined) {
$$=boo; char* temp = temp_var_gen();
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL);
emit_binary_op(E_EQUAL_TO,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3));
$$ = node;
} else { } else {
$$ = undefined; $$ = undefined;
throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3));
@ -747,40 +780,23 @@ expression:
| assignable | assignable
{ {
printdebug("assignable expression. current type is %s",getName((TableNode*)$1)); $$ = $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 {
printdebug("Invalid type passed to expression.");
$$= ((TableNode*)$1);
}
} }
| L_PAREN expression R_PAREN | 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; $$=$2;
} }
| memOp assignable | memOp assignable
{ {
int d = getAdInfoType((TableNode*)$2); int d = getAdInfoType((TableNode*)$2);
if(d == TYPE_ARRAY_TYPE || d == TYPE_ARRAY || d == TYPE_RECORD_TYPE || d == TYPE_RECORD) { if(d == TYPE_ARRAY ||d == TYPE_RECORD) {
$$ = addr; 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 { } else {
throw_error(ERROR_TYPE, "Invalid memOp expression (%s).", getName((TableNode*)$2)); throw_error(ERROR_TYPE, "Invalid memOp expression (%s).", getName((TableNode*)$2));
$$=undefined; $$=undefined;
@ -797,8 +813,9 @@ expression:
assignable: assignable:
ID ID
{ {
$$ = getTypeEntry(look_up(cur,$1)); TableNode* pass = look_up(cur,$1);
printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getName((TableNode*)$$), $1); $$ = pass;
printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getType(pass), getName(pass));
} }
| assignable | assignable
@ -806,22 +823,24 @@ assignable:
printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN);
cur = CreateScope(cur, -1,-1); cur = CreateScope(cur, -1,-1);
} }
//we have to consider emmissions in ablocks
ablock ablock
{ {
int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); //int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1)));
int type = getAdInfoType(getTypeEntry((TableNode*)$1));
printdebug("%stype is %d", COLOR_PURPLE, type); printdebug("%stype is %d", COLOR_PURPLE, type);
printdebug("%s", getName((TableNode*)$1)); printdebug("%s", getName((TableNode*)$1));
if (type == TYPE_FUNCTION_TYPE) { if (type == TYPE_FUNCTION_TYPE) {
printdebug("%sEntering function call", COLOR_LIGHTGREEN); 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"); printdebug("as function");
//char *funtype = getType(look_up(cur, $1)); //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); TableNode *param = getParameter(typeNode);
printTableNode(param); printTableNode(param);
@ -862,7 +881,7 @@ assignable:
} }
} }
} else { } 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)); char *actual = getType(getFirstEntry(cur));
if (strcmp(expected, actual) != 0) { 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); printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column);
@ -871,29 +890,99 @@ assignable:
printdebug("expected 1 argument but got %d", $3); printdebug("expected 1 argument but got %d", $3);
} }
} }
printTableNode(getReturn($1)); printTableNode(getReturn(getTypeEntry((TableNode*)$1)));
$$ = getReturn($1); //
printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((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) { } else if (type == TYPE_ARRAY_TYPE) {
printdebug("%sEntering array call", COLOR_LIGHTGREEN); printdebug("%sEntering array call", COLOR_LIGHTGREEN);
if (getNumArrDim(look_up(getParent(cur), getName((TableNode*)$1))) != $<integ>2) { if (getNumArrDim(look_up(getParent(cur), getType((TableNode*)$1))) != $<integ>2) {
printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $<integ>2, @2.first_line, @2.first_column); printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $<integ>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)); char* temp = temp_var_gen();
printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); 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); cur = getParent(cur);
} }
| assignable rec_op ID | 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");
$$ = table_lookup(getRecList(table_lookup(getAncestor(cur), getName((TableNode*)$1))), $3);
} }
printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", getName((TableNode*)($$)), getName($1)); else if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3)) {
TableNode* type = table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3);
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] record = name: %s | field = %s", getName((TableNode*)($1)), getName((TableNode*)$3));
} }
; ;
@ -917,38 +1006,58 @@ memOp:
constant: constant:
C_STRING C_STRING
{ {
$$ = $1; char* temp = temp_var_gen();
printdebug("string of C_STRING in constant is %s",getName((TableNode*)$1)); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, stri, temp, NULL);
emit_assignment(node, tn_or_const(STRING,$1));
printdebug("string of C_STRING in constant is %s", $1);
$$ = node;
} }
| C_INTEGER | C_INTEGER
{ {
$$ = integ; char* temp = temp_var_gen();
printdebug("string of C_INTEGER in constant is integer"); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL);
emit_assignment(node, tn_or_const(INTEGER,&$1));
printdebug("number of C_INTEGER in constant is %d", $1);
$$ = node;
} }
| C_NULL | C_NULL
{ {
$$ = $1; char* temp = temp_var_gen();
printdebug("string of C_NULL in constant is %s",getName((TableNode*)$1)); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL);
emit_assignment(node, tn_or_const(ADDRESS,$1));
printdebug("string of C_NULL in constant is NULL");
$$ = node;
} }
| C_CHARACTER | C_CHARACTER
{ {
$$ = $1; char* temp = temp_var_gen();
printdebug("string of C_CHARACTER in constant is %s",getName((TableNode*)$1)); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, chara, temp, NULL);
emit_assignment(node, tn_or_const(CHARACTER,&$1));
printdebug("string of C_CHARACTER in constant is %s",$1);
$$ = node;
} }
| C_TRUE | C_TRUE
{ {
$$ = $1; char* temp = temp_var_gen();
printdebug("string of C_TRUE in constant is %s",getName((TableNode*)$1)); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL);
uint_least8_t b = 1;
emit_assignment(node, tn_or_const(BOOLEAN,&b));
printdebug("string of C_TRUE in constant is true");
$$ = node;
} }
| C_FALSE | C_FALSE
{ {
$$ = $1; char* temp = temp_var_gen();
printdebug("string of C_FALSE in constant is %s",getName((TableNode*)$1)); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL);
uint_least8_t b = 0;
emit_assignment(node, tn_or_const(BOOLEAN,&b));
printdebug("string of C_FALSE in constant is false");
$$ = node;
} }
; ;

View File

@ -82,10 +82,10 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\]
"," { if(tok_flag != NULL) {print_tok(COMMA);} incr(line_number,column_number,COMMA); return COMMA; } "," { if(tok_flag != NULL) {print_tok(COMMA);} incr(line_number,column_number,COMMA); return COMMA; }
"->" { if(tok_flag != NULL) {print_tok(ARROW);} incr(line_number,column_number,ARROW); return ARROW; } "->" { if(tok_flag != NULL) {print_tok(ARROW);} incr(line_number,column_number,ARROW); return ARROW; }
{DIGIT}+ { if(tok_flag != NULL) {print_tok(C_INTEGER);} incr(line_number,column_number,C_INTEGER); yylval.integ = atoi(yytext); return C_INTEGER; } {DIGIT}+ {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.integ = atoi(yytext)/*words = strdup("integer")*/;return C_INTEGER;}
'{CHAR}' { if(tok_flag != NULL) {print_tok(C_CHARACTER);} incr(line_number,column_number,C_CHARACTER); yylval.tn = chara; return C_CHARACTER; } '{CHAR}' {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);char* token = strdup(yytext)/*yylval.tn = chara*/;yylval.letter = token[1];return C_CHARACTER;}
\"{SCHAR}*\" { if(tok_flag != NULL) {print_tok(C_STRING);} incr(line_number,column_number,C_STRING); yylval.tn = stri; return C_STRING; } \"{SCHAR}*\" {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);int k = strlen(yytext);yytext[k-1] = '\0';yylval.words = strdup(&yytext[1]);return C_STRING;}
{COMMENT} { if(tok_flag != NULL) {print_tok(COMMENT);} incr(line_number,column_number,COMMENT);} {COMMENT} {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/}
"(" { if(tok_flag != NULL) {print_tok(L_PAREN);} incr(line_number,column_number,L_PAREN); return L_PAREN; } "(" { if(tok_flag != NULL) {print_tok(L_PAREN);} incr(line_number,column_number,L_PAREN); return L_PAREN; }
")" { if(tok_flag != NULL) {print_tok(R_PAREN);} incr(line_number,column_number,R_PAREN); return R_PAREN; } ")" { if(tok_flag != NULL) {print_tok(R_PAREN);} incr(line_number,column_number,R_PAREN); return R_PAREN; }

View File

@ -2,7 +2,8 @@
/* The Translators - Spring 2025 */ /* The Translators - Spring 2025 */
#include "runner.h" #include "runner.h"
FILE *ir_flag = NULL;
//Constant_Stack *head = NULL;
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (argc == 1) { if (argc == 1) {
fprintf(stderr, INVALID); fprintf(stderr, INVALID);
@ -35,6 +36,7 @@ int main(int argc, char *argv[]) {
alpha_file = fopen(argv[argc - 1], "r"); alpha_file = fopen(argv[argc - 1], "r");
} }
} }
cg_flag = fopen("cg.s", "w");
return run(alpha_file); return run(alpha_file);
} }
@ -140,7 +142,10 @@ int run(FILE *alpha) {
if (st_flag != NULL) { if (st_flag != NULL) {
print_symbol_table(top, st_flag); print_symbol_table(top, st_flag);
emit_as_file(stdout, begin);
fclose(st_flag); fclose(st_flag);
generate();
fclose(cg_flag);
} }
if (asc_flag != NULL) { if (asc_flag != NULL) {
@ -157,10 +162,10 @@ int run(FILE *alpha) {
fclose(ir_flag); fclose(ir_flag);
} }
if (cg_flag != NULL) { //if (cg_flag != NULL) {
printf("Flag -cg is not implemented yet\n"); // printf("Flag -cg is not implemented yet\n");
fclose(cg_flag); //fclose(cg_flag);
} //}
if (yyin != NULL) { if (yyin != NULL) {
fclose(yyin); fclose(yyin);

View File

@ -37,7 +37,8 @@
#include "../tmp/grammar.tab.h" #include "../tmp/grammar.tab.h"
#include "symbol_table.h" #include "symbol_table.h"
extern int line_number, column_number; extern int line_number;
extern int column_number;
extern char *yytext; extern char *yytext;
extern FILE *yyin; extern FILE *yyin;
extern bool DEBUG; extern bool DEBUG;
@ -48,9 +49,8 @@ SymbolTable *cur;
FILE *alpha_file; FILE *alpha_file;
FILE *tok_flag = NULL; FILE *tok_flag = NULL;
FILE *st_flag = NULL; FILE *st_flag = NULL;
FILE *ir_flag = NULL;
FILE *cg_flag = NULL;
FILE *asc_flag = NULL; FILE *asc_flag = NULL;
FILE *cg_flag = NULL;
bool tc_flag = false; bool tc_flag = false;
bool DEBUG = false; bool DEBUG = false;
int no_flag = 0; int no_flag = 0;
@ -66,6 +66,7 @@ TableNode *boo;
TableNode *recprime; TableNode *recprime;
TableNode *funtypeprime; TableNode *funtypeprime;
TableNode *undefined; TableNode *undefined;
extern Instruction* begin;
int main(int argc, char *argv[]); int main(int argc, char *argv[]);
int check_flag(char *arg, char *alpha); int check_flag(char *arg, char *alpha);

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdarg.h>
#include <stdint.h>
#define SIZE_INT 4 #define SIZE_INT 4
#define SIZE_ADDR 8 #define SIZE_ADDR 8
@ -12,6 +14,15 @@
#define SIZE_BOOL 4 //TODO: Ask Carl what this size should be #define SIZE_BOOL 4 //TODO: Ask Carl what this size should be
struct TableNode; struct TableNode;
typedef struct TFList TFList;
typedef struct CGNode CGNode;
typedef struct Constant_Stack {
struct TableNode *theType;
void *theValue;
struct Constant_Stack *next;
bool isConst;
} Constant_Stack;
typedef struct { typedef struct {
int size; int size;
@ -149,7 +160,7 @@ extern int line_number;
extern int column_number; extern int column_number;
extern FILE *yyin; extern FILE *yyin;
extern bool DEBUG; extern bool DEBUG;
extern int temp2_count;
extern TableNode *funprime; extern TableNode *funprime;
extern TableNode *arrayprim; extern TableNode *arrayprim;
extern TableNode *integ; extern TableNode *integ;
@ -160,6 +171,7 @@ extern TableNode *boo;
extern TableNode *recprime; extern TableNode *recprime;
extern TableNode *funtypeprime; extern TableNode *funtypeprime;
extern TableNode *undefined; extern TableNode *undefined;
extern Constant_Stack *head;
extern char *COLOR_RED; extern char *COLOR_RED;
extern char *COLOR_GREEN; extern char *COLOR_GREEN;
@ -176,3 +188,188 @@ extern char *COLOR_LIGHTBLUE;
extern char *COLOR_LIGHTPURPLE; extern char *COLOR_LIGHTPURPLE;
extern char *COLOR_LIGHTCYAN; extern char *COLOR_LIGHTCYAN;
extern char *COLOR_WHITE; 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
*/
//-------------------------------------------------------------
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);

0
test.sh Executable file → Normal file
View File

View File

@ -3,5 +3,5 @@ function entry: main
entry(arg) := { entry(arg) := {
[integer : x] [integer : x]
return 0; return 2;
} }