From 0662bea9c35cc3f57eb5190d389997db77c620d8 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 6 May 2025 23:00:50 -0400 Subject: [PATCH] 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;