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;