From e3081f35a4032949e2ca3b599edf50efc2e719d5 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 6 May 2025 02:45:17 -0400 Subject: [PATCH 1/5] tweaking statement options --- src/grammar.h | 2 ++ src/grammar.y | 10 +++++++++- src/runner.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/grammar.h b/src/grammar.h index ec850a2..a4a9300 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -8,9 +8,11 @@ #include "../src/symbol_table.h" extern FILE *asc_flag; extern bool tc_flag; +extern bool entry_flag; extern void insert_code_line(char *error_message, int line_number); extern bool contains_errors; + typedef enum { ERROR_RUNTIME = 1, ERROR_SYNTAX = 2, diff --git a/src/grammar.y b/src/grammar.y index 3d7db57..4129d38 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -170,6 +170,10 @@ definition: } | ID { + if(strcmp($1, "entry") == 0){ + //seen entry function + entry_flag = true; + } emit_function_start(table_lookup(cur,$1)); //printf("ID: %s\n", $1); //printf("Type: %s\n", getType(table_lookup(getAncestor(cur), $1))); @@ -222,7 +226,7 @@ definition: } if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ - CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter))==undefined; + CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter));//==undefined; // throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition.");} } @@ -309,6 +313,7 @@ function_declaration: if (CreateEntry(cur,TYPE_FUNCTION_DECLARATION, table_lookup(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false,NULL)) == undefined) { throw_error(ERROR_TYPE, "Duplicate defination of function in function declaration"); } + } else{ throw_error(ERROR_TYPE, "Function declatation (%s) is not a valid function type", $2); @@ -722,9 +727,12 @@ simple_statement: | RETURN expression { $$ = getTypeEntry((TableNode*)$2); emit_return(tn_or_const(NODE,(TableNode*)$2));} + + // | assignable ASSIGN RESERVE assignable{ } |simple_statement error {yyerrok; yyclearin; printdebug("error in simple statement");} + ; diff --git a/src/runner.h b/src/runner.h index 37c7bad..5736311 100644 --- a/src/runner.h +++ b/src/runner.h @@ -56,6 +56,7 @@ FILE *ir_flag = NULL; FILE *cg_flag = NULL; bool tc_flag = false; bool DEBUG = false; +bool entry_flag = false; int no_flag = 0; int arg; bool contains_errors = false; From 8b177b2807c4b4c45cbfb3ddbe346e9fe19752eb Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 6 May 2025 04:38:35 -0400 Subject: [PATCH 2/5] tweaking statement options --- src/grammar.h | 4 +- src/grammar.y | 117 +++++++++++---------------------------------- src/runner.h | 2 + src/symbol_table.c | 31 ++++++++++++ src/symbol_table.h | 8 ++++ 5 files changed, 71 insertions(+), 91 deletions(-) diff --git a/src/grammar.h b/src/grammar.h index a4a9300..588ac23 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -11,8 +11,8 @@ extern bool tc_flag; extern bool entry_flag; extern void insert_code_line(char *error_message, int line_number); extern bool contains_errors; - - +extern int context; +extern TableNode* comparator; typedef enum { ERROR_RUNTIME = 1, ERROR_SYNTAX = 2, diff --git a/src/grammar.y b/src/grammar.y index 4129d38..14041ed 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -680,6 +680,14 @@ compound_statement: simple_statement: assignable{ + //updating context for reserve/release + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY){ + context = 1; + } + if(getAdInfoType((TableNode*)$1) == TYPE_RECORD){ + context = 2; + } + comparator = $1; S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); } ASSIGN expression @@ -721,6 +729,8 @@ simple_statement: throw_error(ERROR_TYPE, "Assignable Assign Expression - Object %s of type %s != Object %s of type %s", getName(node), getType(node), getName((TableNode*)$4), getType((TableNode*)$4)); } $$ = undefined; + //resetting context + context = 0; } @@ -768,6 +778,7 @@ ablock: argument_list: expression{ TableNode * arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); + //inside a scope of an array call if line number is -2 if(getLine(cur)==-2){ if(getTypeEntry(arg) != integ){ throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg)); @@ -793,6 +804,7 @@ argument_list: { TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); + //inside a scope of an array call if line number is -2 if(getLine(cur)==-2){ if(getTypeEntry(arg) != integ){ throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg)); @@ -1125,7 +1137,7 @@ expression: emit_reserve(node, tn_or_const(INTEGER, &v)); $$ = node; } - | RELEASE ID { + /*| RELEASE ID { TableNode * n = look_up(cur, $2); if(getAdInfoType(n) != TYPE_RECORD){ throw_error(ERROR_TYPE, "Invalid Release expression with object %s of type %s.", @@ -1136,7 +1148,7 @@ expression: TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); //emit release needed here $$ = node; - } + }*/ | RESERVE ID { cur = CreateScope(cur, -2,-1); } ablock { @@ -1159,50 +1171,8 @@ expression: $$=undefined; } cur = getParent(cur); - - - - /*TableNode * t = getFirstEntry(cur); - TableNode * n = look_up(cur, $2); - if(getAdInfoType(n) == TYPE_ARRAY){ - int array_dims = getNumArrDim(getTypeEntry(n)); - if ($5 != array_dims) { - throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", array_dims, $5); - }else{ - int traverse = 0; - while(t != NULL && t != undefined && getName(t)[0] != '&'){ - t = getNextEntry(t); - } - if(getTypeEntry(t) != integ){ - throw_error(ERROR_TYPE, "Arg for an array is not of type integer"); - $$= undefined; - }else{ - //seen first number - traverse++; - t = getNextEntry(t); - while(traversecon = context; + if (context_head == NULL) { + context_head = cs; + cs->next = NULL; + } else { + cs->next = context_head; + context_head = cs; + } + return cs; +} + +int PopContext() { + if (context_head == NULL) { + printf("cannot pop from an empty stack. Invalid.\n"); + return -1; + } + Context_stack *cs = context_head; + context_head = context_head->next; + printf("Popped context off stack: number %d\n", cs->con); + return cs->con; +} + Constant_Stack *Pop() { if (head == NULL) { printf("cannot pop from an empty stack. Invalid.\n"); diff --git a/src/symbol_table.h b/src/symbol_table.h index 2a8abb5..48419d9 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -29,6 +29,11 @@ typedef struct Constant_Stack { bool isConst; } Constant_Stack; +typedef struct Context_stack { + int con; + struct Context_stack *next; +} Context_stack; + typedef struct { int size; } primitive_info; @@ -107,7 +112,9 @@ void printdebug_impl(char *file, int line, const char *format, ...); char *temp_var_gen(); char *arg_var_gen(); Constant_Stack *Push(TableNode *type, void *value, bool isConst); +Context_stack *PushContext(int context); Constant_Stack *Pop(); +int PopContext(); Constant_Stack *Print_Stack(); AdInfo *CreatePrimitiveInfo(int size); int getPrimSize(TableNode *definition); @@ -184,6 +191,7 @@ extern TableNode *recprime; extern TableNode *funtypeprime; extern TableNode *undefined; extern Constant_Stack *head; +extern Context_stack *context_head; extern char *COLOR_RED; extern char *COLOR_GREEN; From 07255a5193862f225d1059be0114e90edd8c2184 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 6 May 2025 14:16:21 -0400 Subject: [PATCH 3/5] added a lot of new fucntions --- src/grammar.h | 2 +- src/grammar.y | 11 +++--- src/symbol_table.c | 90 +++++++++++++++++++++++++++++++++++++++++++--- src/symbol_table.h | 35 ++++++++++++++++-- 4 files changed, 125 insertions(+), 13 deletions(-) diff --git a/src/grammar.h b/src/grammar.h index 588ac23..2ad23b8 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -12,7 +12,7 @@ extern bool entry_flag; extern void insert_code_line(char *error_message, int line_number); extern bool contains_errors; extern int context; -extern TableNode* comparator; +//extern TableNode* comparator; typedef enum { ERROR_RUNTIME = 1, ERROR_SYNTAX = 2, diff --git a/src/grammar.y b/src/grammar.y index 14041ed..692df0e 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -682,12 +682,15 @@ simple_statement: assignable{ //updating context for reserve/release if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY){ + context = 1; } - if(getAdInfoType((TableNode*)$1) == TYPE_RECORD){ + else if(getAdInfoType((TableNode*)$1) == TYPE_RECORD){ context = 2; + } else{ + context = 0; } - comparator = $1; + //comparator = $1; S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); } ASSIGN expression @@ -1233,7 +1236,7 @@ assignable: //Creating a dummy scope where we create entries for all the arguments of a function call //Must also consider that we might be in an array access if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY){ - PushContext(3); + //PushContext(3); printdebug("%sCreating scope for array access", COLOR_CYAN); //special scope for numbers for array access scope cur = CreateScope(cur, -2,-1); @@ -1243,7 +1246,7 @@ assignable: //we have to consider emmissions in ablocks ablock { - PopContext(); + //PopContext(); //int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); int type = getAdInfoType(getTypeEntry((TableNode*)$1)); printdebug("%stype is %d", COLOR_PURPLE, type); diff --git a/src/symbol_table.c b/src/symbol_table.c index 98e1c0c..73a9b10 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -5,7 +5,9 @@ Constant_Stack *head = NULL; Context_stack *context_head = NULL; -TableNode* comparator = NULL; +//TableNode* comparator = NULL; +Function_Stack *function_head = NULL; + int temp2_count = 0; int temp3_count = 0; @@ -55,14 +57,20 @@ Constant_Stack *Push(TableNode *type, void *value, bool isConst) { return cs; } -Context_stack *PushContext(int context) { +Context_stack *PushContext(int context, TableNode *typeToCompare) { if (context != 1 && context != 2 && context != 3 && context != 0) { printdebug( "invalid context passed in"); return NULL; } - Context_stack *cs = (Context_stack *)malloc(sizeof(Context_stack)); + if(typeToCompare == NULL) { + printdebug( + "passed a NULL reference to PushContext. Invalid."); + return NULL; + } + Context_stack *cs = (Context_stack *)calloc(1,sizeof(Context_stack)); cs->con = context; + cs->typeToCompare = typeToCompare; if (context_head == NULL) { context_head = cs; cs->next = NULL; @@ -73,17 +81,89 @@ Context_stack *PushContext(int context) { return cs; } -int PopContext() { +Function_Stack *PushFunction(int arg, TableNode* FunctionType) { + if (FunctionType == NULL) { + printdebug( + "passed a NULL reference to PushFunction. Invalid."); + return NULL; + } + if(FunctionType == undefined) { + printdebug( + "passed an undefined reference to PushFunction. Invalid."); + return NULL; + } + Function_Stack *fs = (Function_Stack *)calloc(1,sizeof(Function_Stack)); + fs->arg = arg; + fs->FunctionType = FunctionType; + if (function_head == NULL) { + function_head = fs; + fs->next = NULL; + } else { + fs->next = function_head; + function_head = fs; + } + return fs; +} + +Function_Stack *PopFunction() { + if (function_head == NULL) { + printf("cannot pop from an empty stack. Invalid.\n"); + return NULL; + } + Function_Stack *fs = function_head; + function_head = function_head->next; + return fs; +} + +int getArgumentNumber(Function_Stack *fs) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to getArgumentNumber. Invalid."); + return -1; + } + return fs->arg; +} + +TableNode* getFunctionTypeContext(Function_Stack *fs) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to getFunctionTypeContext. Invalid."); + return undefined; + } + TableNode* tn = fs->FunctionType; + return tn; +} + +Context_stack *PopContext() { if (context_head == NULL) { printf("cannot pop from an empty stack. Invalid.\n"); - return -1; + return NULL; } Context_stack *cs = context_head; context_head = context_head->next; printf("Popped context off stack: number %d\n", cs->con); + return cs; +} + +int getContextType(Context_stack *cs) { + if (cs == NULL) { + printdebug( + "passed a NULL reference to getContextType. Invalid."); + return -1; + } return cs->con; } +//should be +TableNode *getContextTypeEntry(Context_stack *cs) { + if (cs == NULL) { + printdebug( + "passed a NULL reference to getContextTypeEntry. Invalid."); + return undefined; + } + TableNode* tn = cs->typeToCompare; + return NULL; +} Constant_Stack *Pop() { if (head == NULL) { printf("cannot pop from an empty stack. Invalid.\n"); diff --git a/src/symbol_table.h b/src/symbol_table.h index 48419d9..b71030b 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -17,10 +17,12 @@ extern FILE *ir_flag; -struct TableNode; +typedef struct TableNode TableNode; typedef struct TFList TFList; typedef struct CGNode CGNode; typedef struct SymbolTable SymbolTable; +typedef struct Function_Stack Function_Stack; +typedef struct Context_stack Context_stack; typedef struct Constant_Stack { struct TableNode *theType; @@ -28,12 +30,33 @@ typedef struct Constant_Stack { struct Constant_Stack *next; bool isConst; } Constant_Stack; +//explanation about context stack +//If we have an array context, it means that we are expecting an array, either on the left side of assignable or as the (one of the) arguments that needs to be passed in for a function +//with the array context, either we are initializing the array OR we are reserving space for an element of the array. Can only reserve a record or an array so that element must be a record or an array. +//if we have a record context, that means we are expecting a record on the left side of the assignable assignment or we are expecting a record passed as an argument for a function call. +//we push and pop these contexts as needed. +//we can also push the table node of the thing that we are trying to look at. If it is supposed to be an array, for example, we can push that array onto the stack +//if it is a record, we can push that record onto the stack so that we can approperiately type check +//0 - no expecting array or record +//1 - expecting an array +//2 - expecting a record +//we also have a function call stack to look at what function call we are inside (what parameters it is expecting) +//This is distinct from the context stack. We don't necessarily add to the function call stack. After every valid argument, we simply add one to what argument we are seeing +//This lets us update the context stack as needed with the next tablenode type that we are comparing against +//we can also simply add to the function call stack if we have functions inside functions and then update as needed typedef struct Context_stack { int con; + TableNode *typeToCompare; struct Context_stack *next; } Context_stack; +typedef struct Function_Stack{ + int arg; + TableNode *FunctionType; + struct Function_Stack *next; +} Function_Stack; + typedef struct { int size; } primitive_info; @@ -112,10 +135,15 @@ void printdebug_impl(char *file, int line, const char *format, ...); char *temp_var_gen(); char *arg_var_gen(); Constant_Stack *Push(TableNode *type, void *value, bool isConst); -Context_stack *PushContext(int context); +Context_stack *PushContext(int context,TableNode *typeToCompare); +Function_Stack *PushFunction(int arg, TableNode* FunctionType); Constant_Stack *Pop(); -int PopContext(); +Context_stack *PopContext(); +Function_Stack *PopFunction(); +TableNode* getFunctionTypeContext(Function_Stack *fs); +int getContextType(Context_stack *cs); Constant_Stack *Print_Stack(); +int getArgumentNumber(Function_Stack *fs); AdInfo *CreatePrimitiveInfo(int size); int getPrimSize(TableNode *definition); AdInfo *CreateArrayInfo(int dim, TableNode *type); @@ -192,6 +220,7 @@ extern TableNode *funtypeprime; extern TableNode *undefined; extern Constant_Stack *head; extern Context_stack *context_head; +extern Function_Stack *function_head; extern char *COLOR_RED; extern char *COLOR_GREEN; From 26b23a68fa76d9b8e6d92391cbc222840c4a8f26 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 6 May 2025 15:20:43 -0400 Subject: [PATCH 4/5] need to update argument list for the right context --- src/grammar.y | 10 +++++++++- src/symbol_table.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/symbol_table.h | 2 ++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/grammar.y b/src/grammar.y index 692df0e..61e9724 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1242,12 +1242,20 @@ assignable: cur = CreateScope(cur, -2,-1); }else{ cur = CreateScope(cur, -1,-1); - }} + } + + if(getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + //the function context is created. Pushing the type of the function since that has the information needed + PushFunction(1, getTypeEntry((TableNode*)$1)); + } + + } //we have to consider emmissions in ablocks ablock { //PopContext(); //int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); + PopFunction(); int type = getAdInfoType(getTypeEntry((TableNode*)$1)); printdebug("%stype is %d", COLOR_PURPLE, type); printdebug("%s", getName((TableNode*)$1)); diff --git a/src/symbol_table.c b/src/symbol_table.c index 73a9b10..50ae956 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -124,6 +124,48 @@ int getArgumentNumber(Function_Stack *fs) { return fs->arg; } +TableNode* getRecordNumberType(TableNode* record, int arg){ + if(record == NULL){ + //case where NULL is being passed in + return undefined; + } + if(getAdInfoType(record) != TYPE_RECORD_TYPE){ + //case where invalid argument number is being passed + return undefined; + } + if(arg Date: Tue, 6 May 2025 23:00:50 -0400 Subject: [PATCH 5/5] works? --- src/grammar.y | 105 ++++++++++++++++++++++++++++++++++------ src/intermediate_code.c | 29 ++++++++--- src/intermediate_code.h | 2 +- src/symbol_table.c | 99 +++++++++++++++++++++++++++++++++---- src/symbol_table.h | 12 +++-- 5 files changed, 211 insertions(+), 36 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 61e9724..78f5aa2 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -681,16 +681,10 @@ compound_statement: simple_statement: assignable{ //updating context for reserve/release - if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY){ - - context = 1; + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY || getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + PushContext(getTypeEntry((TableNode*)$1)); + printdebug("pushed %s to context stack in simple statement assignable rule\n",getName(getTypeEntry((TableNode*)$1))); } - else if(getAdInfoType((TableNode*)$1) == TYPE_RECORD){ - context = 2; - } else{ - context = 0; - } - //comparator = $1; S_Push(TrueList, S_Init(), 0); S_Push(FalseList, S_Init(), 0); } ASSIGN expression @@ -733,7 +727,10 @@ simple_statement: } $$ = undefined; //resetting context - context = 0; + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY || getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + PopContext(); + printdebug("popped a context off in simplestatement assignable rule\n"); + } } @@ -777,9 +774,15 @@ ablock: ; - argument_list: + expression{ + PopContext(); + printdebug("popped a context off in argument list\n"); + incrementArgumentNumber(function_head); + TableNode* typeOfArg = getFunctionNumberType(getFunctionType(function_head), getArgumentNumber(function_head)); + PushContext(typeOfArg); + printdebug("pushed %s to context stack\n",getName(typeOfArg)); TableNode * arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); //inside a scope of an array call if line number is -2 if(getLine(cur)==-2){ @@ -806,6 +809,8 @@ argument_list: | expression { + PopContext(); + printdebug("popped a context off in argument list (single arg rule)\n"); TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); //inside a scope of an array call if line number is -2 if(getLine(cur)==-2){ @@ -1127,7 +1132,7 @@ expression: } // TODO: We need to type check this. - | RESERVE ID { + /*| RESERVE ID { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); TableNode * n = look_up(cur, $2); @@ -1140,7 +1145,7 @@ expression: emit_reserve(node, tn_or_const(INTEGER, &v)); $$ = node; } - /*| RELEASE ID { + | RELEASE ID { TableNode * n = look_up(cur, $2); if(getAdInfoType(n) != TYPE_RECORD){ throw_error(ERROR_TYPE, "Invalid Release expression with object %s of type %s.", @@ -1151,7 +1156,7 @@ expression: TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); //emit release needed here $$ = node; - }*/ + } | RESERVE ID { cur = CreateScope(cur, -2,-1); } ablock { @@ -1174,7 +1179,66 @@ expression: $$=undefined; } cur = getParent(cur); + }*/ + | RESERVE assignable{ + + if(getTypeEntry((TableNode*)$2) == getContextTypeEntry(context_head) + && (/*getAdInfoType((TableNode*)$2)==TYPE_ARRAY ||*/ getAdInfoType(getTypeEntry((TableNode*)$2)) == TYPE_RECORD)){ + char* temp = temp_var_gen(); + //does this have integer? + TableNode* node = CreateEntry(cur,TYPE_RECORD, getContextTypeEntry(context_head), temp, NULL); + emit_reserve(node, tn_or_const(NODE,$2)); + $$ = node; + } + if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head))) + && (getAdInfoType(getContextTypeEntry(context_head)) == TYPE_ARRAY_TYPE)){ + char* temp = temp_var_gen(); + //does this have integer? + TableNode* node = CreateEntry(cur,TYPE_ARRAY, getContextTypeEntry(context_head), temp, NULL); + emit_reserve(node, tn_or_const(NODE,$2)); + $$ = node; + }else{ + $$ = undefined; + } + } + + | RELEASE assignable{ + + if(getTypeEntry((TableNode*)$2) == getContextTypeEntry(context_head) + && (/*getAdInfoType((TableNode*)$2)==TYPE_ARRAY ||*/ getAdInfoType(getTypeEntry((TableNode*)$2)) == TYPE_RECORD)){ + char* temp = temp_var_gen(); + //does this have integer? + TableNode* node = CreateEntry(cur,TYPE_RECORD, getContextTypeEntry(context_head), temp, NULL); + emit_release((TableNode*)$2); + $$ = node; + } + if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head))) + && (getAdInfoType(getContextTypeEntry(context_head)) == TYPE_ARRAY_TYPE)){ + char* temp = temp_var_gen(); + //does this have integer? + TableNode* node = CreateEntry(cur,TYPE_ARRAY, getContextTypeEntry(context_head), temp, NULL); + emit_release((TableNode*)$2); + $$ = node; + }else{ + $$=undefined; + } } + +/* + TableNode* node = CreateEntry(cur,getAdInfoType((TableNode*)$2), getTypeEntry(), temp, NULL); + int a = S_Size(S_Peek(stack)) + 1; + emit_push_all(S_Peek(stack)); + S_Pop(stack); + emit_function_call(node, a, tn_or_const(NODE, $2)); + $$ = node; + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) != TYPE_ARRAY){ + throw_error(ERROR_TYPE, "Invalid Reserve expression with object %s of type %s.", + getName(n), getType(n)); + $$=undefined; + } + */ +/* | RELEASE assignable{ char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); @@ -1232,6 +1296,14 @@ assignable: } | assignable { + //TableNode* pass = look_up(cur,$1); + //if(pass == undefined){ + // throw_error(ERROR_TYPE, "Undefined variable %s", $1); + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY|| getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + PushFunction(1,(TableNode*)$1); + PushContext(getFunctionNumberType(getFunctionType(function_head), getArgumentNumber(function_head))); + printdebug("pushed %s to function stack\n",getName((TableNode*)$1)); + } printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); //Creating a dummy scope where we create entries for all the arguments of a function call //Must also consider that we might be in an array access @@ -1246,16 +1318,17 @@ assignable: if(getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ //the function context is created. Pushing the type of the function since that has the information needed - PushFunction(1, getTypeEntry((TableNode*)$1)); } } //we have to consider emmissions in ablocks ablock { + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY|| getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + PopFunction(); + } //PopContext(); //int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); - PopFunction(); int type = getAdInfoType(getTypeEntry((TableNode*)$1)); printdebug("%stype is %d", COLOR_PURPLE, type); printdebug("%s", getName((TableNode*)$1)); diff --git a/src/intermediate_code.c b/src/intermediate_code.c index beccafd..813b51a 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -190,7 +190,8 @@ void emit_binary_op( Op op, TableNode *result, TNodeOrConst *arg1, - TNodeOrConst *arg2) { + TNodeOrConst *arg2 + ) { emit_helper(); current->opcode = op; // TODO: create temp and remove result from param list @@ -315,6 +316,9 @@ void emit_return(TNodeOrConst *value) { void emit_reserve(TableNode *result, TNodeOrConst *size) { // this needs to change // we need to take a int + /* + emit_binary_op(E_MUL, result, + */ emit_parameter(size); emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); } @@ -345,8 +349,12 @@ void emit_address_of(TableNode *x, TNodeOrConst *y) { current->operand1 = y; } -void emit_field_access(char *result, char *record, char *field) { +void emit_field_access(TableNode *result, TNodeOrConst *record, int offset){ emit_helper(); + current->opcode = E_DEREF_RIGHT; + current->result = result; + current->operand1 = record; + current->operand2 = tn_or_const(INTEGER, &offset); } void emit_array_access(Op op, TableNode *result, TNodeOrConst *array, TNodeOrConst *index) { @@ -587,19 +595,22 @@ void emit_as_file(FILE *out_file, Instruction *i) { getName(i->result), get_string(i->operand1)); break; - case E_DEREF_RIGHT: fprintf(out_file, - "%4.d: %s = *%s\n", + "%4.d: %s = *((char * )%s + %s)\n", i->index, getName(i->result), - get_string(i->operand1)); + get_string(i->operand1), + get_string(i->operand2) + ); + break; case E_DEREF_LEFT: fprintf(out_file, "%4.d: *%s = %s\n", i->index, getName(i->result), get_string(i->operand1)); + break; } emit_as_file(out_file, i->next); @@ -615,6 +626,12 @@ TableNode *getTN(TNodeOrConst *tnc) { int getConst(TNodeOrConst *tnc) { if (tnc->d == INTEGER) { return tnc->tnc_union->integer; + } else if (tnc->d == CHARACTER) { + return tnc->tnc_union->character; + } else if (tnc->d == BOOLEAN) { + return tnc->tnc_union->Boolean; + } else if (tnc->d == ADDRESS) { + return 0; } return -1; -} +} \ No newline at end of file diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 5f50828..87e3123 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -143,7 +143,7 @@ void emit_function_dec(TableNode * name); void emit_return(TNodeOrConst *value); void emit_reserve(TableNode *result, TNodeOrConst *size); void emit_release(TableNode *pointer); -void emit_field_access(char *result, char *record, char *field); +void emit_field_access(TableNode *result, TNodeOrConst *record, int offset); void emit_array_access(Op op, TableNode *result, TNodeOrConst *array, TNodeOrConst *index); void emit_bounds_check(TNodeOrConst *index, TNodeOrConst *arr); void emit_goto(int i); diff --git a/src/symbol_table.c b/src/symbol_table.c index 50ae956..d63f23e 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -57,19 +57,19 @@ Constant_Stack *Push(TableNode *type, void *value, bool isConst) { return cs; } -Context_stack *PushContext(int context, TableNode *typeToCompare) { - if (context != 1 && context != 2 && context != 3 && context != 0) { +Context_stack *PushContext(/*int context, */TableNode *typeToCompare) { + /*if (context != 1 && context != 2 && context != 3 && context != 0) { printdebug( "invalid context passed in"); return NULL; - } + }*/ if(typeToCompare == NULL) { printdebug( "passed a NULL reference to PushContext. Invalid."); return NULL; } Context_stack *cs = (Context_stack *)calloc(1,sizeof(Context_stack)); - cs->con = context; + //cs->con = context; cs->typeToCompare = typeToCompare; if (context_head == NULL) { context_head = cs; @@ -107,7 +107,7 @@ Function_Stack *PushFunction(int arg, TableNode* FunctionType) { Function_Stack *PopFunction() { if (function_head == NULL) { - printf("cannot pop from an empty stack. Invalid.\n"); + printf("cannot pop from an empty stack from popfunction. Invalid.\n"); return NULL; } Function_Stack *fs = function_head; @@ -124,6 +124,78 @@ int getArgumentNumber(Function_Stack *fs) { return fs->arg; } +int getTotalNumberArguments(TableNode* function) { + if (function == NULL) { + printdebug( + "passed a NULL reference to getTotalNumberArguments. Invalid."); + return -1; + } + if (getAdInfoType(function) != TYPE_FUNCTION_DECLARATION) { + printdebug( + "passed an invalid reference to getTotalNumberArguments. Invalid."); + return -1; + } + TableNode* functionType = getParameter(getTypeEntry(function)); + if(functionType != undefined){ + return -1; + } + if(getAdInfoType(functionType) != TYPE_RECORD_TYPE){ + return 1; + }else{ + return getRecLength(functionType); + } +} + +Function_Stack* setArgumentNumber(Function_Stack *fs, int arg) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to setArgumentNumber. Invalid."); + return NULL; + } + + if(argFunctionType)){ + //case where invalid argument number is being passed + return NULL; + } + fs->arg = arg; + return fs; +} +Function_Stack* setFunctionType(Function_Stack *fs, TableNode* functionType) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to setFunctionType. Invalid."); + return NULL; + } + if (functionType == NULL) { + printdebug( + "passed a NULL reference to setFunctionType. Invalid."); + return NULL; + } + fs->FunctionType = functionType; + return fs; +} +TableNode* getFunctionType(Function_Stack *fs) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to getFunctionType. Invalid."); + return undefined; + } + TableNode* tn = fs->FunctionType; + return tn; +} + +Function_Stack* incrementArgumentNumber(Function_Stack *fs) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to incrementArgumentNumber. Invalid."); + return NULL; + } + int cur=getArgumentNumber(fs); + setArgumentNumber(fs, cur+1); + //setFunctionType(fs, getFunctionNumberType(getFunctionType(fs), cur+1)); + return fs; +} + TableNode* getRecordNumberType(TableNode* record, int arg){ if(record == NULL){ //case where NULL is being passed in @@ -159,12 +231,20 @@ TableNode* getFunctionNumberType(TableNode* function, int arg){ //case where invalid argument number is being passed return undefined; } + if(getAdInfoType(function) == TYPE_FUNCTION_DECLARATION){ + if(getAdInfoType(getParameter(function)) != TYPE_RECORD_TYPE){ return getParameter(function); }else{ return getRecordNumberType(getParameter(function), arg); } +} else if(getAdInfoType(function) == TYPE_ARRAY_TYPE){ + return getArrType(function); +}else{ + return undefined; } +} + TableNode* getFunctionTypeContext(Function_Stack *fs) { if (fs == NULL) { @@ -178,15 +258,15 @@ TableNode* getFunctionTypeContext(Function_Stack *fs) { Context_stack *PopContext() { if (context_head == NULL) { - printf("cannot pop from an empty stack. Invalid.\n"); + printf("cannot pop from an empty stack from popcontext. Invalid.\n"); return NULL; } Context_stack *cs = context_head; context_head = context_head->next; - printf("Popped context off stack: number %d\n", cs->con); + //printf("Popped context off stack: number %d\n", cs->con); return cs; } - +/* int getContextType(Context_stack *cs) { if (cs == NULL) { printdebug( @@ -195,8 +275,7 @@ int getContextType(Context_stack *cs) { } return cs->con; } - -//should be +*/ TableNode *getContextTypeEntry(Context_stack *cs) { if (cs == NULL) { printdebug( diff --git a/src/symbol_table.h b/src/symbol_table.h index 14ca6e7..82ab464 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -46,7 +46,7 @@ typedef struct Constant_Stack { //we can also simply add to the function call stack if we have functions inside functions and then update as needed typedef struct Context_stack { - int con; + //int con; TableNode *typeToCompare; struct Context_stack *next; } Context_stack; @@ -134,14 +134,19 @@ void printdebug_impl(char *file, int line, const char *format, ...); char *temp_var_gen(); char *arg_var_gen(); +int getTotalNumberArguments(TableNode* function); +Function_Stack* incrementArgumentNumber(Function_Stack *fs); +Function_Stack* setArgumentNumber(Function_Stack *fs, int arg); Constant_Stack *Push(TableNode *type, void *value, bool isConst); -Context_stack *PushContext(int context,TableNode *typeToCompare); +Context_stack *PushContext(/*int context,*/TableNode *typeToCompare); Function_Stack *PushFunction(int arg, TableNode* FunctionType); Constant_Stack *Pop(); Context_stack *PopContext(); +Function_Stack* setFunctionType(Function_Stack *fs, TableNode* functionType); Function_Stack *PopFunction(); TableNode* getFunctionTypeContext(Function_Stack *fs); -int getContextType(Context_stack *cs); +TableNode* getFunctionType(Function_Stack *fs); +//int getContextType(Context_stack *cs); Constant_Stack *Print_Stack(); int getArgumentNumber(Function_Stack *fs); AdInfo *CreatePrimitiveInfo(int size); @@ -198,6 +203,7 @@ ListOfTable *getRestOfChildren(ListOfTable *lt); TableNode *getFirstEntry(SymbolTable *st); TableNode *getNextEntry(TableNode *tn); TableNode *printTableNode(TableNode *tn); +TableNode *getContextTypeEntry(Context_stack *cs); extern int yylex(void); extern char *yytext;