From 04418cc75db6483aaedab72b9ab26c824155d6c7 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Thu, 27 Mar 2025 03:06:58 -0400 Subject: [PATCH 01/38] added testing suite for binary and unary operations typechecking --- test-s1 | 0 test-s2 | 0 tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha | 6 ++++++ tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha | 5 +++++ tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha | 9 +++++++++ tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha | 6 ++++++ 6 files changed, 26 insertions(+) create mode 100644 test-s1 create mode 100644 test-s2 create mode 100644 tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha create mode 100644 tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha create mode 100644 tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha create mode 100644 tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha diff --git a/test-s1 b/test-s1 new file mode 100644 index 0000000..e69de29 diff --git a/test-s2 b/test-s2 new file mode 100644 index 0000000..e69de29 diff --git a/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha new file mode 100644 index 0000000..5952129 --- /dev/null +++ b/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha @@ -0,0 +1,6 @@ +entry(arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] + b2 := 3 < x; + b1 := arr = 2; + b1 := 6<7 & arr2=7; +} diff --git a/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha b/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha new file mode 100644 index 0000000..12db768 --- /dev/null +++ b/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha @@ -0,0 +1,5 @@ +entry(arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] + b2 := !(3 < 2); + b1 := !5; +} diff --git a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha new file mode 100644 index 0000000..5b13147 --- /dev/null +++ b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha @@ -0,0 +1,9 @@ +entry(arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a] + x := 3 + 2 * 8; + x := 3 - 2 / 8; + x := a * 2 % 8; + b2 := 3 * 2 % 8; + x := 3 % 2 * 8; + x := 3 + arr - 8; +} diff --git a/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha new file mode 100644 index 0000000..31e01a7 --- /dev/null +++ b/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha @@ -0,0 +1,6 @@ +entry(arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] + x := -8; + x := -b1; + b2 := -x; +} From c4ad1547bf6ff6a208f11e6a77c674fb4f6413fc Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Thu, 27 Mar 2025 04:00:30 -0400 Subject: [PATCH 02/38] fixed most symbol table structure issues. Working on print symbol table --- Makefile | 2 +- src/symbol_table.c | 32 ++++++++++++++++++++++---------- test-s1 | 0 test-s2 | 0 4 files changed, 23 insertions(+), 11 deletions(-) delete mode 100644 test-s1 delete mode 100644 test-s2 diff --git a/Makefile b/Makefile index 8649a5c..815aec5 100644 --- a/Makefile +++ b/Makefile @@ -55,4 +55,4 @@ clean: rm -f *.st rm -rf out rm -rf tmp - rm -f parser \ No newline at end of file + rm -f parser diff --git a/src/symbol_table.c b/src/symbol_table.c index 208eb69..ba57818 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -479,7 +479,17 @@ char *getType(TableNode *tn) { return ""; } return tn->theType->theName; } -char *getName(TableNode *tn) { return tn->theName; } +char *getName(TableNode *tn) { + if(tn == NULL){ + printf("passed a NULL table entry to getName\n"); + return ""; + } + if(tn->theType == NULL){ + printf("name of entry is currently NULL, undefined \n"); + return ""; + } + return tn->theName; +} int getLine(SymbolTable *st) { return st->Line_Number; } int getColumn(SymbolTable *st) { return st->Column_Number; } TableNode* addName(TableNode *tn, char* str){ @@ -563,7 +573,6 @@ TableNode *look_up(SymbolTable *table, char *x) { void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - return; if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -586,17 +595,16 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", current_scope, parant_scope, "", "Empty Scope"); } - for (entrie != NULL; entrie = entrie->next;) { + for (;entrie != NULL; entrie = entrie->next) { + if (getAdInfoType(entrie) == TYPE_ARRAY){ if (parant_scope == 0) { - /*have to update*/ if (strcmp(entrie->theType->theName, - "function primitive") || - strcmp(entrie->theType->theName, - "array")) { - } + fprintf(file_ptr, - "%-17s: %06d : : %-21s: %-28s\n", + "%-17s: %06d : : %-21d -> %-21s: %-28s\n", entrie->theName, current_scope, - entrie->theType->theName, "Extra annotation"); + entrie->additionalinfo->ArrayAdInfo->numofdimensions, + entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, + "Type of Array"); } else { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", entrie->theName, current_scope, parant_scope, @@ -617,6 +625,10 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } //get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { + if(table == NULL){ + printf("passing a NULL reference to getAncestor. Invalid.\n"); + return NULL; + } if (table->Parent_Scope == NULL) { // if table has no parent, return itself return table; diff --git a/test-s1 b/test-s1 deleted file mode 100644 index e69de29..0000000 diff --git a/test-s2 b/test-s2 deleted file mode 100644 index e69de29..0000000 From 3686a64948d8453370bae0199c672a97fce669e9 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Thu, 27 Mar 2025 04:44:13 -0400 Subject: [PATCH 03/38] symbol_table print almost done but have to figure out seg fault --- src/symbol_table.c | 71 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index ba57818..9ba911f 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -505,6 +505,7 @@ SymbolTable* setLineNumber(SymbolTable *st,int line){ return st; } st->Line_Number = line; + return st; } SymbolTable* setColumnNumber(SymbolTable *st,int column){ @@ -513,6 +514,7 @@ SymbolTable* setColumnNumber(SymbolTable *st,int column){ return st; } st->Line_Number = column; + return st; } /* //we use false for type defs and true for functions for parameter of typeOf @@ -606,11 +608,76 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, "Type of Array"); } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", + fprintf(file_ptr, "%-17s: %06d : %06d : %-21d -> %-21s: %-28s\n", entrie->theName, current_scope, parant_scope, - entrie->theType->theName, "Extra annotation"); + entrie->additionalinfo->ArrayAdInfo->numofdimensions, + entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, + "Type of Array"); } } + if (getAdInfoType(entrie) == TYPE_RECORD){ + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-17s: %06d : :%-21s: elements-%-28d\n", + entrie->theName, current_scope, + "record", + entrie->additionalinfo->RecAdInfo->numofelements); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: elements-%-28d\n", + entrie->theName, current_scope, parant_scope, + "record", + entrie->additionalinfo->RecAdInfo->numofelements); + } + } + if (getAdInfoType(entrie) == TYPE_PRIMITIVE){ + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-17s: %06d : :%-21s: size-%-28d bytes\n", + entrie->theName, current_scope, + "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: size-%-28d bytes\n", + entrie->theName, current_scope, parant_scope, + "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } + } + if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE){ + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-17s: %06d : : %-21s -> %-21s: %-28s\n", + entrie->theName, current_scope, + entrie->additionalinfo->FunTypeAdInfo->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo->returntype->theName, + "Type of Function"); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s -> %-21s: %-28s\n", + entrie->theName, current_scope, parant_scope, + entrie->additionalinfo->FunTypeAdInfo->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo->returntype->theName, + "Type of Function"); + } + } + if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION){ + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-17s: %06d : :%-21s: %-28s\n", + entrie->theName, current_scope, + getType(entrie), + "Function"); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", + entrie->theName, current_scope, parant_scope, + getType(entrie), + "Function"); + } + } +} if (table->Children_Scope != NULL) { ListOfTable *node = table->Children_Scope; for (; node != NULL; node = node->next) { From 8f1c7590bd4fd64c9b781523a040e1664bff9769 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Thu, 27 Mar 2025 19:23:05 -0400 Subject: [PATCH 04/38] added get number of entries function --- src/grammar.y | 84 +++++++++++++++++++++++++++++++++++++++++++--- src/symbol_table.c | 25 +++++++++++++- 2 files changed, 104 insertions(+), 5 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 758b35d..2a02f11 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -157,8 +157,66 @@ declaration_list: ; declaration: - id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } - ; + id_or_types COLON ID { + TableNode* type = table_lookup(getAncestor(cur), $1); + AdInfo* info = NULL; + + // Check for NULL type + if (type == NULL) { + printf("Error: Type '%s' not found\n", $1); + } else { + // Create appropriate AdInfo based on the type + if (type == integ) { + // Integer type + info = CreatePrimitiveInfo(4); // 4 bytes for integer + } + else if (type == addr) { + // Address type + info = CreatePrimitiveInfo(8); // 8 bytes for address + } + else if (type == chara) { + // Character type + info = CreatePrimitiveInfo(1); // 1 byte for character + } + else if (type == boo) { + // Boolean type + info = CreatePrimitiveInfo(1); // 1 byte for boolean + } + else if (type == stri) { + // String type (array of characters) + info = CreateArrayInfo(1, chara); // 1-dimensional array of characters + } + else if (type == arrayprim) { + // Array type + // Need to determine dimensions and element type from context + // This is a placeholder - you'll need to adjust based on your grammar + info = CreateArrayInfo(1, NULL); // Default to 1D array of unknown type + } + else if (type == recprime) { + // Record type + // Need to determine elements from context + // This is a placeholder - you'll need to adjust based on your grammar + info = CreateRecordInfo(0, NULL); // Default to empty record + } + else if (type == funprime) { + // Function declaration + info = CreateFunctionDeclarationInfo(0, false); // Start at line 0, regular function + } + else if (type == funtypeprime) { + // Function type + // Need parameter and return types from context + // This is a placeholder - you'll need to adjust based on your grammar + info = CreateFunctionTypeInfo(NULL, NULL); // Default to no parameter/return type + } + // Add additional type cases as needed + } + + // Create the entry with the appropriate AdInfo + CreateEntry(cur, type, $3, info); + } +; +// id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } +// ; id_or_types: ID {printf("string of id in id_or_type is %s\n",$1);} {$$ = $1;} @@ -200,17 +258,35 @@ expression: | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); printf("mismatch at line %d and column %d\n",@1.first_line,@1.first_column);}} | expression ADD expression {printf("add expression\n");} + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression SUB_OR_NEG expression {printf("subtract expression\n");} + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression MUL expression {printf("multiply expression\n");} + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression DIV expression {printf("division expression\n");} + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression REM expression {printf("remainder expression\n");} + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression AND expression {printf("and expression\n");} + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression OR expression {printf("or expression\n");} +{printf("less than expression\n");if(strcmp($1,$3)==0 && + strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} - | expression LESS_THAN expression {printf("less than expression\n");if(strcmp($1,$3)==0 && - strcmp($1,"integer")==0){$$=strdup("Boolean");}else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + | expression LESS_THAN expression + {printf("less than expression\n");if(strcmp($1,$3)==0 && + strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression EQUAL_TO expression {printf("equals check expression\n"); if(strcmp($1,$3)==0){$$=strdup("Boolean");}else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| diff --git a/src/symbol_table.c b/src/symbol_table.c index 9ba911f..b453c6b 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -103,6 +103,14 @@ AdInfo *CreatePrimitiveInfo(int size) { // only gets the size of a primitive type int getPrimSize(TableNode *definition) { + if (definition == NULL){ + printf("passed an NULL entry to getPrimSize function. Invalid.\n"); + return -1; + } + if (definition->additionalinfo == NULL){ + printf("node has NULL additionalinfo. Invalid.\n"); + return -1; + } if (strcmp(getType(definition), "primitive") != 0) { printf("not checking the size of a primitive -- invalid op\n"); return 0; @@ -133,6 +141,11 @@ AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { } // This gets the number of dimensions from array info int getNumArrDim(TableNode *definition) { + if (definition == NULL){ + printf("passed an NULL entry to getNumArrDim function. Invalid.\n"); + return -1; + } + if( if (strcmp(getType(definition), "array") != 0) { printf("not checking the dim of an array -- invalid op\n"); return 0; @@ -181,6 +194,16 @@ SymbolTable *getRecList(TableNode *definition) { return definition->additionalinfo->RecAdInfo->recordScope; } +int getRecSize(SymbolTable* tn){ + int s = 0; + TableNode* cur = getFirstEntry(tn); + while(getNextEntry(cur) != NULL){ + s++; + cur = getNextEntry(cur); + } + return s; + } + // below function takes a bool to see if parameter should be decomposed or not // note that functions only take one input and have one output // using "as" the input record can be decomposed to give the illusion of @@ -484,7 +507,7 @@ char *getName(TableNode *tn) { printf("passed a NULL table entry to getName\n"); return ""; } - if(tn->theType == NULL){ + if(tn->theName == NULL){ printf("name of entry is currently NULL, undefined \n"); return ""; } From c93534e9d486fdc2423999b1459e08a814ea2e2d Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Thu, 27 Mar 2025 20:10:14 -0400 Subject: [PATCH 05/38] added setRecSize --- src/symbol_table.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/symbol_table.c b/src/symbol_table.c index b453c6b..2457042 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -194,6 +194,15 @@ SymbolTable *getRecList(TableNode *definition) { return definition->additionalinfo->RecAdInfo->recordScope; } +TableNode* setRecSize(TableNode* tn, int n){ + if(tn == NULL){ + printf("passed in NULL entry for setRecSize. Invalid\n"); + return NULL; + } + tn->AdInfo->RecAdInfo->numofelements = n; + return tn; + } + int getRecSize(SymbolTable* tn){ int s = 0; TableNode* cur = getFirstEntry(tn); From d7f6272d371daae47055f277f113cdeb92c6d0b4 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Thu, 27 Mar 2025 23:37:04 -0400 Subject: [PATCH 06/38] still editing grammar --- src/grammar.y | 88 +++++++++------------------------------- src/lexicalStructure.lex | 2 +- src/symbol_table.c | 2 +- 3 files changed, 22 insertions(+), 70 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 2a02f11..05fee0c 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -46,7 +46,7 @@ %token T_BOOLEAN 203 %token T_CHARACTER 204 %token T_STRING 205 -%token C_INTEGER 301 +%token C_INTEGER 301 %token C_NULL 302 %token C_CHARACTER 303 %token C_STRING 304 @@ -120,7 +120,7 @@ prototype: definition: TYPE ID COLON dblock - | TYPE ID COLON constant ARROW ID + | TYPE ID COLON C_INTEGER ARROW ID | function_declaration | TYPE ID COLON id_or_types ARROW id_or_types { CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); @@ -160,63 +160,8 @@ declaration: id_or_types COLON ID { TableNode* type = table_lookup(getAncestor(cur), $1); AdInfo* info = NULL; - - // Check for NULL type - if (type == NULL) { - printf("Error: Type '%s' not found\n", $1); - } else { - // Create appropriate AdInfo based on the type - if (type == integ) { - // Integer type - info = CreatePrimitiveInfo(4); // 4 bytes for integer - } - else if (type == addr) { - // Address type - info = CreatePrimitiveInfo(8); // 8 bytes for address - } - else if (type == chara) { - // Character type - info = CreatePrimitiveInfo(1); // 1 byte for character - } - else if (type == boo) { - // Boolean type - info = CreatePrimitiveInfo(1); // 1 byte for boolean - } - else if (type == stri) { - // String type (array of characters) - info = CreateArrayInfo(1, chara); // 1-dimensional array of characters - } - else if (type == arrayprim) { - // Array type - // Need to determine dimensions and element type from context - // This is a placeholder - you'll need to adjust based on your grammar - info = CreateArrayInfo(1, NULL); // Default to 1D array of unknown type - } - else if (type == recprime) { - // Record type - // Need to determine elements from context - // This is a placeholder - you'll need to adjust based on your grammar - info = CreateRecordInfo(0, NULL); // Default to empty record - } - else if (type == funprime) { - // Function declaration - info = CreateFunctionDeclarationInfo(0, false); // Start at line 0, regular function - } - else if (type == funtypeprime) { - // Function type - // Need parameter and return types from context - // This is a placeholder - you'll need to adjust based on your grammar - info = CreateFunctionTypeInfo(NULL, NULL); // Default to no parameter/return type - } - // Add additional type cases as needed - } - - // Create the entry with the appropriate AdInfo - CreateEntry(cur, type, $3, info); - } -; -// id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } -// ; + id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } + ; id_or_types: ID {printf("string of id in id_or_type is %s\n",$1);} {$$ = $1;} @@ -258,27 +203,34 @@ expression: | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); printf("mismatch at line %d and column %d\n",@1.first_line,@1.first_column);}} | expression ADD expression {printf("add expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + {printf("less than expression\n"); + if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression SUB_OR_NEG expression {printf("subtract expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + {printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression MUL expression {printf("multiply expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + {printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression DIV expression {printf("division expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression REM expression {printf("remainder expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression AND expression {printf("and expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression OR expression {printf("or expression\n");} -{printf("less than expression\n");if(strcmp($1,$3)==0 && + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} @@ -316,7 +268,7 @@ memOp: constant: C_STRING {$$ = $1;} - | C_INTEGER {$$ = $1;} + | C_INTEGER {$$ = "integer";} | C_NULL {$$ = $1;} | C_CHARACTER {$$ = $1;} | C_TRUE {$$ = $1;} diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index 24eaa78..2fab3b4 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -72,7 +72,7 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "," {if(DEBUG) {printf( "COMMA: %s (%d)\n", yytext, COMMA);} else {if(tok_flag != NULL){print_tok(COMMA);}incr(line_number,column_number,COMMA);return COMMA;}} "->" {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.words = strdup("integer");return C_INTEGER;}} +{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(yytex)/*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.words = strdup("character");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.words = strdup("string");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;*/}} diff --git a/src/symbol_table.c b/src/symbol_table.c index 2457042..8b0b99c 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -199,7 +199,7 @@ TableNode* setRecSize(TableNode* tn, int n){ printf("passed in NULL entry for setRecSize. Invalid\n"); return NULL; } - tn->AdInfo->RecAdInfo->numofelements = n; + tn->additionalinfo->RecAdInfo->numofelements = n; return tn; } From 38a1d0b0911ffa99809191616e99a94bac783a23 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 28 Mar 2025 02:02:44 -0400 Subject: [PATCH 07/38] added more helper functions --- src/grammar.y | 45 ++++++++++++++++++++-------------------- src/lexicalStructure.lex | 2 +- src/symbol_table.c | 20 +++++++++++++++++- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 05fee0c..faaabae 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -145,7 +145,8 @@ idlist: sblock: L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE - | L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE + | L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} + dblock {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE ; dblock: @@ -157,10 +158,7 @@ declaration_list: ; declaration: - id_or_types COLON ID { - TableNode* type = table_lookup(getAncestor(cur), $1); - AdInfo* info = NULL; - id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } + id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL);} ; id_or_types: @@ -202,46 +200,49 @@ expression: $$=strdup("undefined");}else{$$=$2;}} | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); printf("mismatch at line %d and column %d\n",@1.first_line,@1.first_column);}} - | expression ADD expression {printf("add expression\n");} - {printf("less than expression\n"); - if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + | expression ADD expression + {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} - | expression SUB_OR_NEG expression {printf("subtract expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean"); + + | expression SUB_OR_NEG expression + {printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} - | expression MUL expression {printf("multiply expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean"); + | expression MUL expression + {printf("multiply expression\n"); + printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} - | expression DIV expression {printf("division expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + | expression DIV expression + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} - | expression REM expression {printf("remainder expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + | expression REM expression + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} - | expression AND expression {printf("and expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + | expression AND expression + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} - | expression OR expression {printf("or expression\n");} + | expression OR expression {printf("less than expression\n");if(strcmp($1,$3)==0 && - strcmp($1,"integer")==0){$$=strdup("Boolean"); + strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression LESS_THAN expression {printf("less than expression\n");if(strcmp($1,$3)==0 && - strcmp($1,"integer")==0){$$=strdup("Boolean"); + strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} + | expression EQUAL_TO expression {printf("equals check expression\n"); - if(strcmp($1,$3)==0){$$=strdup("Boolean");}else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| + if(strcmp($1,$3)==0){$$=strdup("Boolean");} + else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column);$$=strdup("undefined");}} | assignable {printf("assignable expression\n");$$=$1;} diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index 2fab3b4..b43c979 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -72,7 +72,7 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "," {if(DEBUG) {printf( "COMMA: %s (%d)\n", yytext, COMMA);} else {if(tok_flag != NULL){print_tok(COMMA);}incr(line_number,column_number,COMMA);return COMMA;}} "->" {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(yytex)/*words = strdup("integer")*/;return C_INTEGER;}} +{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.words = strdup("character");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.words = strdup("string");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;*/}} diff --git a/src/symbol_table.c b/src/symbol_table.c index 8b0b99c..59a27c9 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -145,7 +145,6 @@ int getNumArrDim(TableNode *definition) { printf("passed an NULL entry to getNumArrDim function. Invalid.\n"); return -1; } - if( if (strcmp(getType(definition), "array") != 0) { printf("not checking the dim of an array -- invalid op\n"); return 0; @@ -236,6 +235,15 @@ int getStartLine(TableNode *definition) { } return definition->additionalinfo->FunDecAdInfo->startlinenumber; } + +TableNode* setStartLine(TableNode* tn, int start){ + if(tn == NULL){ + printf("passing in a NULL entry to setStartLine. invalid\n"); + return NULL; + } + tn->additionalinfo->FunDecAdInfo->startlinenumber = start; + return tn; + } // checks if "as" keyword was used for function definition. Either 0 or 1 for // not used or used. bool getAsKeyword(TableNode *definition) { @@ -246,6 +254,16 @@ bool getAsKeyword(TableNode *definition) { } return definition->additionalinfo->FunDecAdInfo->regularoras; } + +TableNode* setAsKeyword(TableNode* tn, bool as){ + if(tn == NULL){ + printf("passing in a NULL entry to setAsKeyword. invalid\n"); + return NULL; + } + tn->additionalinfo->FunDecAdInfo->regularoras = as; + return tn; + } + // stores the type of a function (parameter type and return type) AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); From 2654308396f4066d36c7f3954d65ac7ebd7709b1 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 28 Mar 2025 02:14:50 -0400 Subject: [PATCH 08/38] fixed expression rules --- src/grammar.y | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index faaabae..6b2b70b 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -195,58 +195,67 @@ rec_op : expression: constant {printf("constant expression\n");} {$$ = $1;} + | SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");if(strcmp($2,"integer") != 0) {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("undefined");}else{$$=$2;}} + | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); printf("mismatch at line %d and column %d\n",@1.first_line,@1.first_column);}} + | expression ADD expression - {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} + {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} | expression SUB_OR_NEG expression - {printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean");} + {printf("sub or neg expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} + | expression MUL expression {printf("multiply expression\n"); - printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean");} + if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} + | expression DIV expression - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} + {printf("divide expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} + | expression REM expression - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} + {printf("remainder expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} | expression AND expression - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} + {printf("AND expression\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} | expression OR expression - {printf("less than expression\n");if(strcmp($1,$3)==0 && - strcmp($1,"integer")==0){$$=strdup("Boolean");} + {printf("OR\n");if(strcmp($1,$3)==0 && + strcmp($1,"Boolean")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} | expression LESS_THAN expression {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} | expression EQUAL_TO expression {printf("equals check expression\n"); if(strcmp($1,$3)==0){$$=strdup("Boolean");} else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column);$$=strdup("undefined");}} + | assignable {printf("assignable expression\n");$$=$1;} + | L_PAREN expression R_PAREN {printf("paren expression\n");$$=$2;} + | memOp assignable {$$ = strdup("address");} ; From 36694a2f4ae815e0bb2827fd198aab4272b79a4c Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 28 Mar 2025 13:47:53 -0400 Subject: [PATCH 09/38] updated lookups to return undefined entry if invalid --- src/grammar.y | 34 +++++++++++++-------- src/symbol_table.c | 34 ++++++++++++++------- tests/sprint2/test/test_carls_mistake.alpha | 4 +-- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 6b2b70b..7ff44da 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -201,60 +201,70 @@ expression: $$=strdup("undefined");}else{$$=$2;}} | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); - printf("mismatch at line %d and column %d\n",@1.first_line,@1.first_column);}} + printf("mismatch at line %d and column %d. Invalid type being negated is %s\n", + @1.first_line,@1.first_column,$2);}} | expression ADD expression {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression SUB_OR_NEG expression {printf("sub or neg expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression MUL expression {printf("multiply expression\n"); if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression DIV expression {printf("divide expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression REM expression {printf("remainder expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression AND expression {printf("AND expression\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression OR expression {printf("OR\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression LESS_THAN expression {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression EQUAL_TO expression {printf("equals check expression\n"); if(strcmp($1,$3)==0){$$=strdup("Boolean");} else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column);$$=strdup("undefined");}} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s\n", + @2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} - | assignable {printf("assignable expression\n");$$=$1;} + | assignable {printf("assignable expression. current type is %s\n",$1);$$=$1;} - | L_PAREN expression R_PAREN {printf("paren expression\n");$$=$2;} + | L_PAREN expression R_PAREN {printf("paren expression. current type is %s\n",$2);$$=$2;} | memOp assignable {$$ = strdup("address");} ; diff --git a/src/symbol_table.c b/src/symbol_table.c index 59a27c9..dabcafa 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -18,6 +18,7 @@ TableNode *stri; TableNode *boo; TableNode *recprime; TableNode *funtypeprime; +TableNode *undefined; typedef enum { // First 4 below are primitive types that are all encapsulated in @@ -228,7 +229,7 @@ AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { // gets the line at which the function was first defined. (Can be used to print // out in table if needed) int getStartLine(TableNode *definition) { - if (strcmp(getType(definition), "function primitive") != 0) { + if (strcmp(getType(definition), "primitive function") != 0) { printf("not checking the start line of a function -- invalid " "op\n"); return 0; @@ -247,7 +248,7 @@ TableNode* setStartLine(TableNode* tn, int start){ // checks if "as" keyword was used for function definition. Either 0 or 1 for // not used or used. bool getAsKeyword(TableNode *definition) { - if (strcmp(getType(definition), "function primitive") != 0) { + if (strcmp(getType(definition), "primitive function") != 0) { printf("not checking if a function is called with as or not -- " "invalid op\n"); return NULL; @@ -275,7 +276,7 @@ AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { } // returns parameter type of a function TableNode *getParameter(TableNode *definition) { - if (strcmp(getType(definition), "function type primitive") != 0) { + if (strcmp(getType(definition), "primitive function type") != 0) { printf( "not checking the parameter of a function -- invalid op\n"); return NULL; @@ -284,7 +285,7 @@ TableNode *getParameter(TableNode *definition) { } // returns return type of a function TableNode *getReturn(TableNode *definition) { - if (strcmp(getType(definition), "function type primitive") != 0) { + if (strcmp(getType(definition), "primitive function type") != 0) { printf("not checking the return of a function -- invalid op\n"); return NULL; } @@ -394,6 +395,12 @@ SymbolTable *init(SymbolTable *start) { funtypeprime->additionalinfo = NULL; funtypeprime->next = NULL; + undefined = (TableNode *)malloc(sizeof(TableNode)); + undefined->theName = "undefined"; + undefined->theType = NULL; + undefined->additionalinfo = NULL; + undefined->next = NULL; + integ->theType = prime; addr->theType = prime; chara->theType = prime; @@ -522,24 +529,26 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, char *getType(TableNode *tn) { if(tn == NULL){ printf("passed a NULL table entry to getType\n"); - return ""; + return getName(undefined); } if(tn->theType == NULL){ printf("type of entry is currently NULL, undefined type \n"); - return ""; + return getName(undefined); } return tn->theType->theName; } + char *getName(TableNode *tn) { if(tn == NULL){ printf("passed a NULL table entry to getName\n"); - return ""; + return undefined->theName; } if(tn->theName == NULL){ printf("name of entry is currently NULL, undefined \n"); - return ""; + return undefined->theName; } return tn->theName; } + int getLine(SymbolTable *st) { return st->Line_Number; } int getColumn(SymbolTable *st) { return st->Column_Number; } TableNode* addName(TableNode *tn, char* str){ @@ -609,17 +618,20 @@ TableNode *table_lookup(SymbolTable *table, char *x) { return entrie; } } - return NULL; + return undefined; } //check current table and all parents TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { - return NULL; + printf("passed in empty scope. error.\n"); + return undefined; } TableNode *ret = table_lookup(table, x); - if (ret != NULL) { + if (ret != NULL && ret != undefined) { return ret; } + printf("could not find %s in scope that started at line %d and column %d so moving up a scope\n" + ,x,getLine(table),getColumn(table)); return look_up(table->Parent_Scope, x); } diff --git a/tests/sprint2/test/test_carls_mistake.alpha b/tests/sprint2/test/test_carls_mistake.alpha index fb75ca3..f2b3703 100644 --- a/tests/sprint2/test/test_carls_mistake.alpha +++ b/tests/sprint2/test/test_carls_mistake.alpha @@ -18,10 +18,10 @@ bar2 as (r,s) := { entry(arg) := { [ integer: result ; rec: w] result := foo(5); - w := reserve(w); (* see types.alpha – reserve returns a value of type address, which can be assigned to array and record variables*) + w := reserve w; (* see types.alpha – reserve returns a value of type address, which can be assigned to array and record variables*) w.x := 5; w.y := 7; result := bar1(w); (* pass w (a rec type value) to bar1 *) result := bar2(5,7); (* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *) return 0; -} \ No newline at end of file +} From d0a00c86841469434bc9cf302d4a687403223cac Mon Sep 17 00:00:00 2001 From: Moroseui <157774170+Moroseui@users.noreply.github.com> Date: Fri, 28 Mar 2025 13:58:45 -0400 Subject: [PATCH 10/38] Update grammar.y with Annie's changes --- src/grammar.y | 131 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 111 insertions(+), 20 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 7ff44da..c9da70b 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -119,18 +119,58 @@ prototype: L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; definition: - TYPE ID COLON dblock - | TYPE ID COLON C_INTEGER ARROW ID +definition: +TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); + if (table_lookup(getAncestor(cur), $2) == NULL) { + printf("rec not found \n"); + } + }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); + cur = getParent(cur);} + | TYPE ID COLON C_INTEGER ARROW id_or_types { CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} | function_declaration | TYPE ID COLON id_or_types ARROW id_or_types { CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); - } - | ID parameter ASSIGN sblock + } + | ID { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, false); + } + cur = CreateScope(cur, 0, 0); + } L_PAREN ID { + CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); + }R_PAREN ASSIGN sblock + | ID { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == NULL) { + printf("null check\n"); + } + if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, false); + } + cur = CreateScope(cur, 0, 0); + }AS L_PAREN { + TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); + if (parameter == NULL || getAdInfoType(parameter) != TYPE_RECORD) { + printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ + CreateEntry(cur, entry, NULL, NULL); + } + } + } idlist R_PAREN ASSIGN sblock ; + function_declaration: - FUNCTION ID COLON ID - | EXTERNAL FUNCTION ID COLON ID +FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} + | EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);} ; parameter: @@ -139,14 +179,34 @@ parameter: ; idlist: - ID COMMA idlist - | ID + ID { + TableNode *entry = getFirstEntry(cur); + while (getName(entry) != NULL) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) == NULL) { + printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + } + addName(entry, $1); + } COMMA idlist + | ID { + + TableNode *entry = getFirstEntry(cur); + while (getName(entry) != NULL) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) != NULL) { + printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + } + addName(entry, $1); + } ; + sblock: - L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE - | L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} - dblock {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE +L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE + | L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock + {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE ; dblock: @@ -158,8 +218,8 @@ declaration_list: ; declaration: - id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL);} - ; + id_or_types COLON ID {printf("ID/TYPE: %s, ID: %s\n", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } + ; id_or_types: ID {printf("string of id in id_or_type is %s\n",$1);} {$$ = $1;} @@ -180,14 +240,45 @@ compound_statement: ; simple_statement: - assignable ASSIGN expression + assignable ASSIGN expression {if(strcmp($1, $3) == 0){ + } else { + printf("Mismatch at line %d and column%d\n", @2.first_line, @2.first_column); + }} + | RETURN expression ; assignable: - ID - | assignable ablock - | assignable rec_op ID +ID {TableNode *node = table_lookup(cur, $1); + printf("%s\n", $1); + if (node == NULL) { + printf("could not find %s in current scope\n", $1); + node = table_lookup(getAncestor(cur), $1); + if (node != NULL && getAdInfoType(node) == TYPE_FUNCTION_DECLARATION) { + if (getAsKeyword(node)) { + node = table_lookup(getAncestor(cur), getType(node)); + $$ = getRecLength(getParameter(node)); + } else { + $$ = 1; + } + } + else { + printf("assignable not defined as correct type at line %d, column %d\n", @1.first_line, @1.first_column); + } + } else if (getAdInfoType(node) == TYPE_ARRAY) { + $$ = getNumArrDim(node); + } else { + $$ = getName(node); + } +} +| assignable ablock {if ($1 != $2) { + printf("invalid number of expressions in ablock at line %d, column %d\n", @1.first_line, @1.first_column); + } + $$ = getName(getReturn(look_up(cur, $1))); +} +| assignable rec_op ID {TableNode * tn; printf("this is assignable.id %s\n", getType(look_up(cur, $1)));if(NULL != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) + {$$ = "test";} +} ; rec_op : @@ -271,12 +362,12 @@ expression: ablock: - L_PAREN argument_list R_PAREN +L_PAREN argument_list {$$ = $2;} R_PAREN ; argument_list: - expression COMMA argument_list - | expression +expression COMMA argument_list {$$ = $3 + 1;} +| expression {$$ = 1;} ; From 37dedf181832c17d73a3260de89663cf1bb3b8b5 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 28 Mar 2025 14:16:49 -0400 Subject: [PATCH 11/38] fixed some grammar rules --- src/grammar.y | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index c9da70b..9e765e2 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -26,6 +26,7 @@ extern TableNode* chara; extern TableNode* stri; extern TableNode* boo; + TableNode * tn; %} //%define api.location.type {location_t} %locations @@ -118,7 +119,6 @@ prototype_or_definition_list: prototype: L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; -definition: definition: TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); if (table_lookup(getAncestor(cur), $2) == NULL) { @@ -169,14 +169,10 @@ TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo function_declaration: -FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} + FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} | EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);} ; -parameter: - L_PAREN ID R_PAREN - | AS L_PAREN idlist R_PAREN - ; idlist: ID { @@ -222,7 +218,7 @@ declaration: ; id_or_types: - ID {printf("string of id in id_or_type is %s\n",$1);} {$$ = $1;} + ID {printf("string of id in id_or_type is %s\n",$1); $$ = getType(look_up(cur,$1));} | types {printf("string of type in id_or_type is %s\n",$1);} {$$ = $1;} ; @@ -276,7 +272,8 @@ ID {TableNode *node = table_lookup(cur, $1); } $$ = getName(getReturn(look_up(cur, $1))); } -| assignable rec_op ID {TableNode * tn; printf("this is assignable.id %s\n", getType(look_up(cur, $1)));if(NULL != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) +| assignable rec_op ID {TableNode * tn; printf("this is assignable.id %s\n", getType(look_up(cur, $1))); + if(NULL != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) {$$ = "test";} } ; From cca01eb0b5a4588a02c981d21b052889d2e3f0bc Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 28 Mar 2025 14:49:17 -0400 Subject: [PATCH 12/38] working on tabel --- src/grammar.y | 36 +++++------------------------------- src/symbol_table.c | 17 ++++++++++++++--- 2 files changed, 19 insertions(+), 34 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 9e765e2..b464641 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1,3 +1,4 @@ + /* Syntax Analyzer with Bison (3.8.2) */ /* The Translators - Spring 2025 */ @@ -245,37 +246,10 @@ simple_statement: ; assignable: -ID {TableNode *node = table_lookup(cur, $1); - printf("%s\n", $1); - if (node == NULL) { - printf("could not find %s in current scope\n", $1); - node = table_lookup(getAncestor(cur), $1); - if (node != NULL && getAdInfoType(node) == TYPE_FUNCTION_DECLARATION) { - if (getAsKeyword(node)) { - node = table_lookup(getAncestor(cur), getType(node)); - $$ = getRecLength(getParameter(node)); - } else { - $$ = 1; - } - } - else { - printf("assignable not defined as correct type at line %d, column %d\n", @1.first_line, @1.first_column); - } - } else if (getAdInfoType(node) == TYPE_ARRAY) { - $$ = getNumArrDim(node); - } else { - $$ = getName(node); - } -} -| assignable ablock {if ($1 != $2) { - printf("invalid number of expressions in ablock at line %d, column %d\n", @1.first_line, @1.first_column); - } - $$ = getName(getReturn(look_up(cur, $1))); -} -| assignable rec_op ID {TableNode * tn; printf("this is assignable.id %s\n", getType(look_up(cur, $1))); - if(NULL != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) - {$$ = "test";} -} + ID {$$ = $1; } + | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} + | assignable rec_op ID {if(undefined != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) + {$$ = getType(tn);}} ; rec_op : diff --git a/src/symbol_table.c b/src/symbol_table.c index dabcafa..123c6a8 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -44,7 +44,8 @@ typedef enum { // size TYPE_PRIMITIVE = 6, //likely NULL - TYPE_ALL_ELSE = 7 + TYPE_ALL_ELSE = 7, + TYPE_UNDEFINED = 8 } types; @@ -214,7 +215,13 @@ int getRecSize(SymbolTable* tn){ } // below function takes a bool to see if parameter should be decomposed or not -// note that functions only take one input and have one output +assignable: + ID {$$ = $1; } + | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} + | assignable rec_op ID {TableNode * tn; if(NULL != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) + {$$ = getType(tn);} + } + ;// note that functions only take one input and have one output // using "as" the input record can be decomposed to give the illusion of // multiple inputs Below function also has the line number where the function is // first defined @@ -488,7 +495,10 @@ int getAdInfoType(TableNode* tn){ if(strcmp(getType(tn),getName(arrayprim))==0){ return TYPE_ARRAY; } - else{ + if(strcmp(getType(tn),getName(undefined))==0){ + return TYPE_UNDEFINED; + } + else{ return TYPE_FUNCTION_DECLARATION; } } @@ -637,6 +647,7 @@ TableNode *look_up(SymbolTable *table, char *x) { void print_symbol_table(SymbolTable *table, FILE *file_ptr) { + return; if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); From f217500b5517a92e532d01fbdc49cdad9976f521 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 28 Mar 2025 16:11:42 -0400 Subject: [PATCH 13/38] removed most seg faults --- Makefile | 9 +++- src/grammar.y | 6 +-- src/symbol_table.c | 101 +++++++++++++++++++++++---------------------- 3 files changed, 63 insertions(+), 53 deletions(-) diff --git a/Makefile b/Makefile index 815aec5..729ca3d 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ CFLAGS := YACC := bison TESTS-S1 := $(wildcard tests/sprint1/test/*.alpha) +TESTS-S3 := $(wildcard tests/sprint3/test/*.alpha) TESTS-S2 := $(wildcard tests/sprint2/test/*.alpha) compiler: clean runner @@ -32,13 +33,19 @@ runner: tmp/lex.yy.c tmp/runner.o tmp/symbol_table.o debug: CFLAGS += -DDEBUG=1 debug: clean compiler -test: test-s1 test-s2 +test: test-s1 test-s3 test-s2 test-s1: chmod +x ./check.sh $(foreach test, $(TESTS-S1), ./$(EXE) -tok $(test);) ./check.sh + +test-s3: + chmod +x ./check.sh + $(foreach test, $(TESTS-S3), ./$(EXE) -st $(test);) + ./check.sh + test-s2: chmod +x ./check.sh $(foreach test, $(TESTS-S2), ./$(EXE) -st $(test);) diff --git a/src/grammar.y b/src/grammar.y index b464641..5238aac 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -246,10 +246,10 @@ simple_statement: ; assignable: - ID {$$ = $1; } + ID {$$ = getType(look_up(cur,$1));} | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} - | assignable rec_op ID {if(undefined != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) - {$$ = getType(tn);}} + | assignable rec_op ID {if(undefined != table_lookup(getRecList(look_up(cur, $1)), $3)){ + {$$ = getName(table_lookup(getRecList(look_up(cur, $1)), $3));}};} ; rec_op : diff --git a/src/symbol_table.c b/src/symbol_table.c index 123c6a8..4b31b1e 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -105,7 +105,7 @@ AdInfo *CreatePrimitiveInfo(int size) { // only gets the size of a primitive type int getPrimSize(TableNode *definition) { - if (definition == NULL){ + if (definition == NULL || definition == undefined){ printf("passed an NULL entry to getPrimSize function. Invalid.\n"); return -1; } @@ -143,7 +143,7 @@ AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { } // This gets the number of dimensions from array info int getNumArrDim(TableNode *definition) { - if (definition == NULL){ + if (definition == NULL|| definition == undefined){ printf("passed an NULL entry to getNumArrDim function. Invalid.\n"); return -1; } @@ -158,7 +158,7 @@ int getNumArrDim(TableNode *definition) { TableNode *getArrType(TableNode *definition) { if (strcmp(getType(definition), "array") != 0) { printf("not checking the type of an array -- invalid op\n"); - return NULL; + return undefined; } return definition->additionalinfo->ArrayAdInfo->typeofarray; } @@ -196,9 +196,9 @@ SymbolTable *getRecList(TableNode *definition) { } TableNode* setRecSize(TableNode* tn, int n){ - if(tn == NULL){ + if(tn == NULL||tn==undefined){ printf("passed in NULL entry for setRecSize. Invalid\n"); - return NULL; + return undefined; } tn->additionalinfo->RecAdInfo->numofelements = n; return tn; @@ -215,12 +215,6 @@ int getRecSize(SymbolTable* tn){ } // below function takes a bool to see if parameter should be decomposed or not -assignable: - ID {$$ = $1; } - | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} - | assignable rec_op ID {TableNode * tn; if(NULL != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) - {$$ = getType(tn);} - } ;// note that functions only take one input and have one output // using "as" the input record can be decomposed to give the illusion of // multiple inputs Below function also has the line number where the function is @@ -245,9 +239,9 @@ int getStartLine(TableNode *definition) { } TableNode* setStartLine(TableNode* tn, int start){ - if(tn == NULL){ - printf("passing in a NULL entry to setStartLine. invalid\n"); - return NULL; + if(tn == NULL||tn==undefined){ + printf("passing in a NULL or undefined entry to setStartLine. invalid\n"); + return undefined; } tn->additionalinfo->FunDecAdInfo->startlinenumber = start; return tn; @@ -258,15 +252,15 @@ bool getAsKeyword(TableNode *definition) { if (strcmp(getType(definition), "primitive function") != 0) { printf("not checking if a function is called with as or not -- " "invalid op\n"); - return NULL; + return 0; } return definition->additionalinfo->FunDecAdInfo->regularoras; } TableNode* setAsKeyword(TableNode* tn, bool as){ - if(tn == NULL){ - printf("passing in a NULL entry to setAsKeyword. invalid\n"); - return NULL; + if(tn == NULL||tn==undefined){ + printf("passing in a NULL or undefined entry to setAsKeyword. invalid\n"); + return undefined; } tn->additionalinfo->FunDecAdInfo->regularoras = as; return tn; @@ -286,7 +280,7 @@ TableNode *getParameter(TableNode *definition) { if (strcmp(getType(definition), "primitive function type") != 0) { printf( "not checking the parameter of a function -- invalid op\n"); - return NULL; + return undefined; } return definition->additionalinfo->FunTypeAdInfo->parameter; } @@ -294,7 +288,7 @@ TableNode *getParameter(TableNode *definition) { TableNode *getReturn(TableNode *definition) { if (strcmp(getType(definition), "primitive function type") != 0) { printf("not checking the return of a function -- invalid op\n"); - return NULL; + return undefined; } return definition->additionalinfo->FunTypeAdInfo->returntype; } @@ -444,17 +438,17 @@ TableNode* recprime; TableNode* funtypeprime; */ TableNode* populateTypeAndInfo(TableNode* tn, TableNode* type, AdInfo* info){ - if(tn == NULL){ - printf("passed in an invalid table node to modify (NULL).\n"); - return NULL; + if(tn == NULL||tn==undefined){ + printf("passed in an invalid table node to modify (NULL or undefined).\n"); + return undefined; } - if(type == NULL){ - printf("passed in a NULL type reference to populate a table node. Invalid.\n"); - return NULL; + if(type == NULL||type==undefined){ + printf("passed in a NULL or undefined type reference to populate a table node. Invalid.\n"); + return undefined; } if(info == NULL){ printf("passed in a NULL info reference to populate a table node. Invalid.\n"); - return NULL; + return undefined; } tn->theType = type; tn->additionalinfo = info; @@ -463,12 +457,12 @@ TableNode* populateTypeAndInfo(TableNode* tn, TableNode* type, AdInfo* info){ } int getAdInfoType(TableNode* tn){ - if(tn == NULL){ - printf("passing in NULL table entry. Invalid\n"); + if(tn == NULL||tn==undefined){ + printf("passing in NULL or undefined table entry. Invalid\n"); return -1; } - if(tn->theType == NULL){ - printf("Entry being passed in has a null reference for theType. Invalid.\n"); + if(tn->theType == NULL|| tn->theType == undefined){ + printf("Entry being passed in has a null or undefined reference for theType. Invalid.\n"); return -1; } if(strcmp(getType(tn),getName(integ))==0){ @@ -508,7 +502,7 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, if (table == NULL) { printf("Null reference to table"); - return NULL; + return undefined; } /* TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); @@ -517,11 +511,11 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, return NULL; } */ - if (typeOf == NULL) { - printf("This is not pointing to a proper definition\n"); - return NULL; + if (typeOf == NULL||typeOf == undefined) { + printf("This is not pointing to a proper definition (either NULL or undefined)\n"); + return undefined; } - TableNode *newEntry = (TableNode *)malloc(sizeof(TableNode)); + TableNode *newEntry = (TableNode *)calloc(1,sizeof(TableNode)); newEntry->theType = typeOf /*topDef*/; newEntry->theName = id; newEntry->additionalinfo = ad; @@ -537,23 +531,23 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, } char *getType(TableNode *tn) { - if(tn == NULL){ - printf("passed a NULL table entry to getType\n"); + if(tn == NULL||tn==undefined){ + printf("passed a NULL or undefined table entry to getType\n"); return getName(undefined); } - if(tn->theType == NULL){ - printf("type of entry is currently NULL, undefined type \n"); + if(tn->theType == NULL|| tn->theType == undefined){ + printf("type of entry is currently NULL or undefined type \n"); return getName(undefined); } return tn->theType->theName; } char *getName(TableNode *tn) { - if(tn == NULL){ - printf("passed a NULL table entry to getName\n"); + if(tn == NULL||tn==undefined){ + //printf("passed a NULL or undefined table entry to getName\n"); return undefined->theName; } if(tn->theName == NULL){ - printf("name of entry is currently NULL, undefined \n"); + //printf("name of entry is currently NULL, undefined \n"); return undefined->theName; } return tn->theName; @@ -562,10 +556,20 @@ char *getName(TableNode *tn) { int getLine(SymbolTable *st) { return st->Line_Number; } int getColumn(SymbolTable *st) { return st->Column_Number; } TableNode* addName(TableNode *tn, char* str){ - if(tn == NULL){ - printf("passed a Null table node to the addName function. Invalid./n"); - return tn; + if(tn == NULL||tn==undefined){ + printf("passed a Null or undefined table node to the addName function. Invalid./n"); + return undefined; } + if(tn->theName != NULL){ + printf("Name doesn't look like it is empty before you change. Are you sure you need to update name?/n"); + return undefined; + } + if(str == NULL){ + printf("passed a NULL string to the addName function. Invalid./n"); + return undefined; + } + tn->theName = str; + return tn; } SymbolTable* setLineNumber(SymbolTable *st,int line){ @@ -647,7 +651,6 @@ TableNode *look_up(SymbolTable *table, char *x) { void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - return; if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -811,11 +814,11 @@ bool typeCheck(char *firstID, char *secondID) { TableNode *entry1 = look_up(cur, firstID); TableNode *entry2 = look_up(cur, secondID); - if (entry1 == NULL) { + if (entry1 == NULL|| entry1 == undefined) { printf("first type not defined\n"); return false; } - if (entry2 == NULL) { + if (entry2 == NULL|| entry2 == undefined) { printf("second type not defined\n"); return false; } From 227cec0b7341f222745c6054252fe369773f60b0 Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 28 Mar 2025 18:02:40 -0400 Subject: [PATCH 14/38] continuing. need fix of makefile --- Makefile | 17 ++-- src/grammar.y | 17 ++-- src/symbol_table.c | 200 ++++++++++++++++++++++++++++----------------- 3 files changed, 144 insertions(+), 90 deletions(-) diff --git a/Makefile b/Makefile index 729ca3d..c58b895 100644 --- a/Makefile +++ b/Makefile @@ -33,22 +33,21 @@ runner: tmp/lex.yy.c tmp/runner.o tmp/symbol_table.o debug: CFLAGS += -DDEBUG=1 debug: clean compiler -test: test-s1 test-s3 test-s2 +test: test-s1 test-s2 test-s3 test-s1: chmod +x ./check.sh - $(foreach test, $(TESTS-S1), ./$(EXE) -tok $(test);) - ./check.sh - - -test-s3: - chmod +x ./check.sh - $(foreach test, $(TESTS-S3), ./$(EXE) -st $(test);) + for test in $(TESTS-S1); do ./$(EXE) -tok $$test || echo "Test $$test failed but continuing"; done ./check.sh test-s2: chmod +x ./check.sh - $(foreach test, $(TESTS-S2), ./$(EXE) -st $(test);) + for test in $(TESTS-S2); do ./$(EXE) -st $$test || echo "Test $$test failed but continuing"; done + ./check.sh + +test-s3: + chmod +x ./check.sh + for test in $(TESTS-S3); do ./$(EXE) -st $$test || echo "Test $$test failed but continuing"; done ./check.sh clean: diff --git a/src/grammar.y b/src/grammar.y index 5238aac..fcb06b8 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -219,8 +219,11 @@ declaration: ; id_or_types: - ID {printf("string of id in id_or_type is %s\n",$1); $$ = getType(look_up(cur,$1));} - | types {printf("string of type in id_or_type is %s\n",$1);} {$$ = $1;} + ID {printf("string of id is %s in ID pattern of id_or_type rule.\n"); $$ = $1;} + //{printf("string of id is %s in ID pattern of id_or_type rule. Type passed up the tree is %s.\n",$1,getType(look_up(cur,$1))); $$ = getType(look_up(cur,$1));} + | types {printf("string of type is %s in types pattern of id_or_type rule.\n",$1);} {$$ = $1;} + //{printf("string of type is %s in types pattern of id_or_type rule. That is passed up the tree.\n",$1);} {$$ = $1;} + ; ; statement_list: @@ -247,7 +250,7 @@ simple_statement: assignable: ID {$$ = getType(look_up(cur,$1));} - | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} + | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} //add array case here | assignable rec_op ID {if(undefined != table_lookup(getRecList(look_up(cur, $1)), $3)){ {$$ = getName(table_lookup(getRecList(look_up(cur, $1)), $3));}};} ; @@ -360,10 +363,10 @@ constant: types: // Commented out T_String below // T_STRING {printf("string of T_STRING in types is %s\n",$1);} {$$ = $1;} - T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} - | T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$1);} {$$ = $1;} - | T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$1);} {$$ = $1;} - | T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$1);} {$$ = $1;} + T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} + | T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$1);} {$$ = $1;} + | T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$1);} {$$ = $1;} + | T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$1);} {$$ = $1;} ; %% diff --git a/src/symbol_table.c b/src/symbol_table.c index 4b31b1e..7f8849b 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -650,7 +650,6 @@ TableNode *look_up(SymbolTable *table, char *x) { } void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -673,87 +672,23 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", current_scope, parant_scope, "", "Empty Scope"); } - for (;entrie != NULL; entrie = entrie->next) { - if (getAdInfoType(entrie) == TYPE_ARRAY){ + for (; entrie != NULL; entrie = entrie->next) { if (parant_scope == 0) { - + /*have to update*/ if (strcmp(entrie->theType->theName, + "function primitive") || + strcmp(entrie->theType->theName, + "array")) { + } fprintf(file_ptr, - "%-17s: %06d : : %-21d -> %-21s: %-28s\n", + "%-17s: %06d : : %-21s: %-28s\n", entrie->theName, current_scope, - entrie->additionalinfo->ArrayAdInfo->numofdimensions, - entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, - "Type of Array"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21d -> %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - entrie->additionalinfo->ArrayAdInfo->numofdimensions, - entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, - "Type of Array"); - } - } - if (getAdInfoType(entrie) == TYPE_RECORD){ - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-17s: %06d : :%-21s: elements-%-28d\n", - entrie->theName, current_scope, - "record", - entrie->additionalinfo->RecAdInfo->numofelements); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: elements-%-28d\n", - entrie->theName, current_scope, parant_scope, - "record", - entrie->additionalinfo->RecAdInfo->numofelements); - } - } - if (getAdInfoType(entrie) == TYPE_PRIMITIVE){ - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-17s: %06d : :%-21s: size-%-28d bytes\n", - entrie->theName, current_scope, - "Primitive", - entrie->additionalinfo->PrimAdInfo->size); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: size-%-28d bytes\n", - entrie->theName, current_scope, parant_scope, - "Primitive", - entrie->additionalinfo->PrimAdInfo->size); - } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE){ - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-17s: %06d : : %-21s -> %-21s: %-28s\n", - entrie->theName, current_scope, - entrie->additionalinfo->FunTypeAdInfo->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo->returntype->theName, - "Type of Function"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s -> %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - entrie->additionalinfo->FunTypeAdInfo->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo->returntype->theName, - "Type of Function"); - } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION){ - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-17s: %06d : :%-21s: %-28s\n", - entrie->theName, current_scope, - getType(entrie), - "Function"); + entrie->theType->theName, "Extra annotation"); } else { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", entrie->theName, current_scope, parant_scope, - getType(entrie), - "Function"); + entrie->theType->theName, "Extra annotation"); } } -} if (table->Children_Scope != NULL) { ListOfTable *node = table->Children_Scope; for (; node != NULL; node = node->next) { @@ -766,6 +701,123 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { "----------------------\n"); } } +// void print_symbol_table(SymbolTable *table, FILE *file_ptr) { + +// if (table->Parent_Scope == NULL) { +// fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", +// "SCOPE", "PARENT", "TYPE", "Extra annotation"); +// } +// TableNode *entrie = table->entries; +// fprintf(file_ptr, "-----------------:--------:--------:----------------" +// "------:---------" +// "--------------------\n"); +// int parant_scope = 0; +// int current_scope = 0; +// if (table->Parent_Scope != NULL) { +// parant_scope = table->Parent_Scope->Line_Number * 1000 + +// table->Parent_Scope->Column_Number; +// current_scope = +// table->Line_Number * 1000 + table->Column_Number; +// } else { +// current_scope = 1001; +// } +// if (entrie == NULL) { +// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", +// current_scope, parant_scope, "", "Empty Scope"); +// } +// for (;entrie != NULL; entrie = entrie->next) { +// if (getAdInfoType(entrie) == TYPE_ARRAY){ +// if (parant_scope == 0) { + +// fprintf(file_ptr, +// "%-17s: %06d : : %-21d -> %-21s: %-28s\n", +// entrie->theName, current_scope, +// entrie->additionalinfo->ArrayAdInfo->numofdimensions, +// entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, +// "Type of Array"); +// } else { +// fprintf(file_ptr, "%-17s: %06d : %06d : %-21d -> %-21s: %-28s\n", +// entrie->theName, current_scope, parant_scope, +// entrie->additionalinfo->ArrayAdInfo->numofdimensions, +// entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, +// "Type of Array"); +// } +// } +// if (getAdInfoType(entrie) == TYPE_RECORD){ +// if (parant_scope == 0) { + +// fprintf(file_ptr, +// "%-17s: %06d : :%-21s: elements-%-28d\n", +// entrie->theName, current_scope, +// "record", +// entrie->additionalinfo->RecAdInfo->numofelements); +// } else { +// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: elements-%-28d\n", +// entrie->theName, current_scope, parant_scope, +// "record", +// entrie->additionalinfo->RecAdInfo->numofelements); +// } +// } +// if (getAdInfoType(entrie) == TYPE_PRIMITIVE){ +// if (parant_scope == 0) { + +// fprintf(file_ptr, +// "%-17s: %06d : :%-21s: size-%-28d bytes\n", +// entrie->theName, current_scope, +// "Primitive", +// entrie->additionalinfo->PrimAdInfo->size); +// } else { +// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: size-%-28d bytes\n", +// entrie->theName, current_scope, parant_scope, +// "Primitive", +// entrie->additionalinfo->PrimAdInfo->size); +// } +// } +// if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE){ +// if (parant_scope == 0) { + +// fprintf(file_ptr, +// "%-17s: %06d : : %-21s -> %-21s: %-28s\n", +// entrie->theName, current_scope, +// entrie->additionalinfo->FunTypeAdInfo->parameter->theName, +// entrie->additionalinfo->FunTypeAdInfo->returntype->theName, +// "Type of Function"); +// } else { +// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s -> %-21s: %-28s\n", +// entrie->theName, current_scope, parant_scope, +// entrie->additionalinfo->FunTypeAdInfo->parameter->theName, +// entrie->additionalinfo->FunTypeAdInfo->returntype->theName, +// "Type of Function"); +// } +// } +// if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION){ +// if (parant_scope == 0) { + +// fprintf(file_ptr, +// "%-17s: %06d : :%-21s: %-28s\n", +// entrie->theName, current_scope, +// getType(entrie), +// "Function"); +// } else { +// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", +// entrie->theName, current_scope, parant_scope, +// getType(entrie), +// "Function"); +// } +// } +// } +// if (table->Children_Scope != NULL) { +// ListOfTable *node = table->Children_Scope; +// for (; node != NULL; node = node->next) { +// print_symbol_table(node->table, file_ptr); +// } +// } +// if (table->Parent_Scope == NULL) { +// fprintf(file_ptr, "-----------------:--------:--------:--------" +// "--------------:-------" +// "----------------------\n"); +// } +// } //get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { if(table == NULL){ From 982a8a045424cd402ff78aff152513f991100ead Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 28 Mar 2025 18:22:05 -0400 Subject: [PATCH 15/38] init --- src/grammar.y~ | 373 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100644 src/grammar.y~ diff --git a/src/grammar.y~ b/src/grammar.y~ new file mode 100644 index 0000000..5238aac --- /dev/null +++ b/src/grammar.y~ @@ -0,0 +1,373 @@ + +/* Syntax Analyzer with Bison (3.8.2) */ +/* The Translators - Spring 2025 */ + +%{ + #include + #include "../src/symbol_table.c" + #include + extern int yylex(void); + void yyerror(const char *err); + extern char* yytext; + extern int yyleng; + extern int yychar; + extern SymbolTable * cur; + //char* cur_value; + //char* cur_type; + int token_tracker; + extern int line_number; + extern int column_number; + extern FILE * yyin; + extern TableNode* funprime; + extern TableNode* arrayprim; + extern TableNode* recprime; + extern TableNode* funtypeprime; + extern TableNode* integ; + extern TableNode* addr; + extern TableNode* chara; + extern TableNode* stri; + extern TableNode* boo; + TableNode * tn; +%} +//%define api.location.type {location_t} +%locations +%union { + int integ; + char * words; +} + + +%type assignable +%type expression +%type constant +%type id_or_types +%type types +%token ID 101 +%token T_INTEGER 201 +%token T_ADDRESS 202 +%token T_BOOLEAN 203 +%token T_CHARACTER 204 +%token T_STRING 205 +%token C_INTEGER 301 +%token C_NULL 302 +%token C_CHARACTER 303 +%token C_STRING 304 +%token C_TRUE 305 +%token C_FALSE 306 +%token WHILE 401 +%token IF 402 +%token THEN 403 +%token ELSE 404 +%token TYPE 405 +%token FUNCTION 406 +%token RETURN 407 +%token EXTERNAL 408 +%token AS 409 +%token L_PAREN 501 +%token R_PAREN 502 +%token L_BRACKET 503 +%token R_BRACKET 504 +%token L_BRACE 505 +%token R_BRACE 506 +%token SEMI_COLON 507 +%token COLON 508 +%token COMMA 509 +%token ARROW 510 +%token MUL 603 +%token DIV 604 +%token REM 605 +%token ADD 601 +%token LESS_THAN 606 +%token EQUAL_TO 607 +%token AND 610 +%token OR 611 +%token ASSIGN 608 +%token SUB_OR_NEG 602 +%token NOT 609 +%token DOT 612 +%token RESERVE 613 +%token RELEASE 614 +%token COMMENT 700 + +//precedence order +%left ASSIGN +%left OR +%left AND +%left EQUAL_TO +%left LESS_THAN +%left ADD SUB_OR_NEG +%left MUL DIV REM +%precedence NOT +%precedence UMINUS +%precedence DOT +%precedence RESERVE RELEASE + + + +%% + +program: + prototype_or_definition_list + ; + +prototype_or_definition_list: + prototype prototype_or_definition_list + | definition prototype_or_definition_list + | prototype + | definition + ; + +prototype: + L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; + +definition: +TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); + if (table_lookup(getAncestor(cur), $2) == NULL) { + printf("rec not found \n"); + } + }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); + cur = getParent(cur);} + | TYPE ID COLON C_INTEGER ARROW id_or_types { CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} + | function_declaration + | TYPE ID COLON id_or_types ARROW id_or_types { + CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); + } + | ID { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, false); + } + cur = CreateScope(cur, 0, 0); + } L_PAREN ID { + CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); + }R_PAREN ASSIGN sblock + | ID { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == NULL) { + printf("null check\n"); + } + if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, false); + } + cur = CreateScope(cur, 0, 0); + }AS L_PAREN { + TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); + if (parameter == NULL || getAdInfoType(parameter) != TYPE_RECORD) { + printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ + CreateEntry(cur, entry, NULL, NULL); + } + } + } idlist R_PAREN ASSIGN sblock + ; + + +function_declaration: + FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} + | EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);} + ; + + +idlist: + ID { + TableNode *entry = getFirstEntry(cur); + while (getName(entry) != NULL) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) == NULL) { + printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + } + addName(entry, $1); + } COMMA idlist + | ID { + + TableNode *entry = getFirstEntry(cur); + while (getName(entry) != NULL) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) != NULL) { + printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + } + addName(entry, $1); + } + ; + + +sblock: +L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE + | L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock + {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE + ; + +dblock: + L_BRACKET declaration_list R_BRACKET; + +declaration_list: + declaration SEMI_COLON declaration_list + | declaration + ; + +declaration: + id_or_types COLON ID {printf("ID/TYPE: %s, ID: %s\n", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } + ; + +id_or_types: + ID {printf("string of id in id_or_type is %s\n",$1); $$ = getType(look_up(cur,$1));} + | types {printf("string of type in id_or_type is %s\n",$1);} {$$ = $1;} + ; + +statement_list: + compound_statement statement_list + | compound_statement + | simple_statement SEMI_COLON statement_list + | simple_statement SEMI_COLON + ; + +compound_statement: + WHILE L_PAREN expression R_PAREN sblock + | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock + | sblock //{printf("seen a compound statement rule\n");} + ; + +simple_statement: + assignable ASSIGN expression {if(strcmp($1, $3) == 0){ + } else { + printf("Mismatch at line %d and column%d\n", @2.first_line, @2.first_column); + }} + + | RETURN expression + ; + +assignable: + ID {$$ = getType(look_up(cur,$1));} + | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} + | assignable rec_op ID {if(undefined != table_lookup(getRecList(look_up(cur, $1)), $3)){ + {$$ = getName(table_lookup(getRecList(look_up(cur, $1)), $3));}};} + ; + +rec_op : + DOT + +expression: + constant {printf("constant expression\n");} {$$ = $1;} + + | SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");if(strcmp($2,"integer") != 0) + {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("undefined");}else{$$=$2;}} + + | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); + printf("mismatch at line %d and column %d. Invalid type being negated is %s\n", + @1.first_line,@1.first_column,$2);}} + + | expression ADD expression + {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression SUB_OR_NEG expression + {printf("sub or neg expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression MUL expression + {printf("multiply expression\n"); + if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression DIV expression + {printf("divide expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression REM expression + {printf("remainder expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression AND expression + {printf("AND expression\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression OR expression + {printf("OR\n");if(strcmp($1,$3)==0 && + strcmp($1,"Boolean")==0){$$=strdup("Boolean");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression LESS_THAN expression + {printf("less than expression\n");if(strcmp($1,$3)==0 && + strcmp($1,"integer")==0){$$=strdup("Boolean");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression EQUAL_TO expression {printf("equals check expression\n"); + if(strcmp($1,$3)==0){$$=strdup("Boolean");} + else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| + strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s\n", + @2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} + + | assignable {printf("assignable expression. current type is %s\n",$1);$$=$1;} + + | L_PAREN expression R_PAREN {printf("paren expression. current type is %s\n",$2);$$=$2;} + + | memOp assignable {$$ = strdup("address");} + ; + + +ablock: +L_PAREN argument_list {$$ = $2;} R_PAREN + ; + +argument_list: +expression COMMA argument_list {$$ = $3 + 1;} +| expression {$$ = 1;} + ; + + +memOp: + RESERVE {printf("reserve expression\n");} + | RELEASE {printf("release expression\n");} + ; + + +constant: + C_STRING {$$ = $1;} + | C_INTEGER {$$ = "integer";} + | C_NULL {$$ = $1;} + | C_CHARACTER {$$ = $1;} + | C_TRUE {$$ = $1;} + | C_FALSE {$$ = $1;} + ; + +types: + // Commented out T_String below + // T_STRING {printf("string of T_STRING in types is %s\n",$1);} {$$ = $1;} + T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} + | T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$1);} {$$ = $1;} + | T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$1);} {$$ = $1;} + | T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$1);} {$$ = $1;} + ; + +%% + +void yyerror(const char *err) { + fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d\n", err,yytext,yylloc.first_line,yylloc.first_column); +} From ad4f55c2bf5005d7bc38655d0573d0f572b0c98d Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 28 Mar 2025 20:38:21 -0400 Subject: [PATCH 16/38] HUGE Makefile updates! --- Makefile | 33 +- check.sh | 73 ++-- src/grammar.y~ | 373 ------------------ src/symbol_table.c | 2 +- test.sh | 166 ++++++++ ..._mistake.alpha => sp2_carls_mistake.alpha} | 0 ...id_recop.alpha => sp2_invalid_recop.alpha} | 0 ...elease.alpha => sp2_invalid_release.alpha} | 0 ...pha => sp2_valid_assignable_and_mem.alpha} | 0 9 files changed, 242 insertions(+), 405 deletions(-) delete mode 100644 src/grammar.y~ create mode 100755 test.sh rename tests/sprint2/test/{test_carls_mistake.alpha => sp2_carls_mistake.alpha} (100%) rename tests/sprint2/test/{test_invalid_recop.alpha => sp2_invalid_recop.alpha} (100%) rename tests/sprint2/test/{test_invalid_release.alpha => sp2_invalid_release.alpha} (100%) rename tests/sprint2/test/{test_valid_assignable_and_mem.alpha => sp2_valid_assignable_and_mem.alpha} (100%) diff --git a/Makefile b/Makefile index c58b895..0f04da9 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,9 @@ CFLAGS := YACC := bison TESTS-S1 := $(wildcard tests/sprint1/test/*.alpha) -TESTS-S3 := $(wildcard tests/sprint3/test/*.alpha) TESTS-S2 := $(wildcard tests/sprint2/test/*.alpha) +TESTS-S3 := $(wildcard tests/sprint3/test/*.alpha) +TESTS-S4 := $(wildcard tests/sprint4/test/*.alpha) compiler: clean runner @@ -33,22 +34,38 @@ runner: tmp/lex.yy.c tmp/runner.o tmp/symbol_table.o debug: CFLAGS += -DDEBUG=1 debug: clean compiler -test: test-s1 test-s2 test-s3 +test: + chmod +x ./check.sh + chmod +x ./test.sh + $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) || true);) + ./test.sh sp2 + ./test.sh sp3 + ./test.sh sp4 + ./check.sh test-s1: chmod +x ./check.sh - for test in $(TESTS-S1); do ./$(EXE) -tok $$test || echo "Test $$test failed but continuing"; done - ./check.sh + chmod +x ./test.sh + $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) || true);) + ./check.sh sp1 test-s2: chmod +x ./check.sh - for test in $(TESTS-S2); do ./$(EXE) -st $$test || echo "Test $$test failed but continuing"; done - ./check.sh + chmod +x ./test.sh + ./test.sh sp2 + ./check.sh sp2 test-s3: chmod +x ./check.sh - for test in $(TESTS-S3); do ./$(EXE) -st $$test || echo "Test $$test failed but continuing"; done - ./check.sh + chmod +x ./test.sh + ./test.sh sp3 + ./check.sh sp3 + +test-s4: + chmod +x ./check.sh + chmod +x ./test.sh + ./test.sh sp4 + ./check.sh sp4 clean: rm -f *.o diff --git a/check.sh b/check.sh index f325421..bac18ec 100755 --- a/check.sh +++ b/check.sh @@ -5,34 +5,61 @@ # The Translators - Spring 2025 # TOK_DIR="out" +NOCOLOR='\033[0m' RED='\033[0;31m' GREEN='\033[0;32m' -WHITE='\033[0m' -PURPLE='\033[0;35m' ORANGE='\033[0;33m' +BLUE='\033[0;34m' +PURPLE='\033[0;35m' +CYAN='\033[0;36m' +LIGHTGRAY='\033[0;37m' +DARKGRAY='\033[1;30m' +LIGHTRED='\033[1;31m' +LIGHTGREEN='\033[1;32m' +YELLOW='\033[1;33m' +LIGHTBLUE='\033[1;34m' +LIGHTPURPLE='\033[1;35m' +LIGHTCYAN='\033[1;36m' +WHITE='\033[1;37m' + +compare_files() { + local file="$1" + local filename=$(basename -- "$file") + filename="${filename%.*}" + local num=${filename:2:1} + local exp="./tests/sprint$num/expected/$filename.expected" + + if [[ -f "$exp" ]]; then + diff -q "$file" "$exp" > /dev/null + if [[ $? -eq 0 ]]; then + echo -e "${GREEN}[✔] ${PURPLE}$filename ${WHITE}passed.${NOCOLOR}" + else + echo -e "\n${RED}[✘] ${PURPLE}$file ${WHITE}failed with an unexpected value...${NOCOLOR}" + diff --color=always "$file" "$exp" + echo -e "" + fi + else + echo -e "${ORANGE}[-] ${PURPLE}$filename ${WHITE}does not have an expected value.${NOCOLOR}" + fi +} if [[ ! -d "$TOK_DIR" ]]; then - echo "Directory $TOK_DIR does not exist." + echo -e "${RED}[ERROR] ${YELLOW}Directory $TOK_DIR does not exist.${NOCOLOR}" exit 1 fi -echo -e "\n" -for file in "$TOK_DIR"/*; do - filename=$(basename -- "$file") - filename="${filename%.*}" - num=${filename:2:1} - exp="./tests/sprint$num/expected/$filename.expected" - - if [[ -f "$exp" ]]; then - diff -q "$file" "$exp" > /dev/null - if [[ $? -eq 0 ]]; then - echo -e "${GREEN}[✔] ${PURPLE}$filename ${WHITE}passed." - else - echo -e "\n${RED}[✘] ${PURPLE}$file ${WHITE}failed with an unexpected value..." - diff --color=always "$file" "$exp" - echo -e "" - fi - else - echo -e "${ORANGE}[-] ${PURPLE}$filename ${WHITE}does not have an expected value." - fi -done \ No newline at end of file +if [[ $# -eq 0 ]]; then + for file in "$TOK_DIR"/*; do + compare_files "$file" + done +elif [[ $# -eq 1 ]]; then + prefix="$1" + for file in "$TOK_DIR"/"$prefix"*; do + if [[ -f "$file" ]]; then + compare_files "$file" + fi + done +else + echo -e "${LIGHTBLUE}Usage: $0 [sp#]${NOCOLOR}" + exit 1 +fi \ No newline at end of file diff --git a/src/grammar.y~ b/src/grammar.y~ deleted file mode 100644 index 5238aac..0000000 --- a/src/grammar.y~ +++ /dev/null @@ -1,373 +0,0 @@ - -/* Syntax Analyzer with Bison (3.8.2) */ -/* The Translators - Spring 2025 */ - -%{ - #include - #include "../src/symbol_table.c" - #include - extern int yylex(void); - void yyerror(const char *err); - extern char* yytext; - extern int yyleng; - extern int yychar; - extern SymbolTable * cur; - //char* cur_value; - //char* cur_type; - int token_tracker; - extern int line_number; - extern int column_number; - extern FILE * yyin; - extern TableNode* funprime; - extern TableNode* arrayprim; - extern TableNode* recprime; - extern TableNode* funtypeprime; - extern TableNode* integ; - extern TableNode* addr; - extern TableNode* chara; - extern TableNode* stri; - extern TableNode* boo; - TableNode * tn; -%} -//%define api.location.type {location_t} -%locations -%union { - int integ; - char * words; -} - - -%type assignable -%type expression -%type constant -%type id_or_types -%type types -%token ID 101 -%token T_INTEGER 201 -%token T_ADDRESS 202 -%token T_BOOLEAN 203 -%token T_CHARACTER 204 -%token T_STRING 205 -%token C_INTEGER 301 -%token C_NULL 302 -%token C_CHARACTER 303 -%token C_STRING 304 -%token C_TRUE 305 -%token C_FALSE 306 -%token WHILE 401 -%token IF 402 -%token THEN 403 -%token ELSE 404 -%token TYPE 405 -%token FUNCTION 406 -%token RETURN 407 -%token EXTERNAL 408 -%token AS 409 -%token L_PAREN 501 -%token R_PAREN 502 -%token L_BRACKET 503 -%token R_BRACKET 504 -%token L_BRACE 505 -%token R_BRACE 506 -%token SEMI_COLON 507 -%token COLON 508 -%token COMMA 509 -%token ARROW 510 -%token MUL 603 -%token DIV 604 -%token REM 605 -%token ADD 601 -%token LESS_THAN 606 -%token EQUAL_TO 607 -%token AND 610 -%token OR 611 -%token ASSIGN 608 -%token SUB_OR_NEG 602 -%token NOT 609 -%token DOT 612 -%token RESERVE 613 -%token RELEASE 614 -%token COMMENT 700 - -//precedence order -%left ASSIGN -%left OR -%left AND -%left EQUAL_TO -%left LESS_THAN -%left ADD SUB_OR_NEG -%left MUL DIV REM -%precedence NOT -%precedence UMINUS -%precedence DOT -%precedence RESERVE RELEASE - - - -%% - -program: - prototype_or_definition_list - ; - -prototype_or_definition_list: - prototype prototype_or_definition_list - | definition prototype_or_definition_list - | prototype - | definition - ; - -prototype: - L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; - -definition: -TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); - if (table_lookup(getAncestor(cur), $2) == NULL) { - printf("rec not found \n"); - } - }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); - cur = getParent(cur);} - | TYPE ID COLON C_INTEGER ARROW id_or_types { CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} - | function_declaration - | TYPE ID COLON id_or_types ARROW id_or_types { - CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); - } - | ID { - TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { - printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); - } else { - setStartLine(node, @1.first_line); - setAsKeyword(node, false); - } - cur = CreateScope(cur, 0, 0); - } L_PAREN ID { - CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); - }R_PAREN ASSIGN sblock - | ID { - TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == NULL) { - printf("null check\n"); - } - if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { - printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); - } else { - setStartLine(node, @1.first_line); - setAsKeyword(node, false); - } - cur = CreateScope(cur, 0, 0); - }AS L_PAREN { - TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); - if (parameter == NULL || getAdInfoType(parameter) != TYPE_RECORD) { - printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); - } else { - for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ - CreateEntry(cur, entry, NULL, NULL); - } - } - } idlist R_PAREN ASSIGN sblock - ; - - -function_declaration: - FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} - | EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);} - ; - - -idlist: - ID { - TableNode *entry = getFirstEntry(cur); - while (getName(entry) != NULL) { - entry = getNextEntry(entry); - } - if (getNextEntry(entry) == NULL) { - printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); - } - addName(entry, $1); - } COMMA idlist - | ID { - - TableNode *entry = getFirstEntry(cur); - while (getName(entry) != NULL) { - entry = getNextEntry(entry); - } - if (getNextEntry(entry) != NULL) { - printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); - } - addName(entry, $1); - } - ; - - -sblock: -L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE - | L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock - {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE - ; - -dblock: - L_BRACKET declaration_list R_BRACKET; - -declaration_list: - declaration SEMI_COLON declaration_list - | declaration - ; - -declaration: - id_or_types COLON ID {printf("ID/TYPE: %s, ID: %s\n", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } - ; - -id_or_types: - ID {printf("string of id in id_or_type is %s\n",$1); $$ = getType(look_up(cur,$1));} - | types {printf("string of type in id_or_type is %s\n",$1);} {$$ = $1;} - ; - -statement_list: - compound_statement statement_list - | compound_statement - | simple_statement SEMI_COLON statement_list - | simple_statement SEMI_COLON - ; - -compound_statement: - WHILE L_PAREN expression R_PAREN sblock - | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock - | sblock //{printf("seen a compound statement rule\n");} - ; - -simple_statement: - assignable ASSIGN expression {if(strcmp($1, $3) == 0){ - } else { - printf("Mismatch at line %d and column%d\n", @2.first_line, @2.first_column); - }} - - | RETURN expression - ; - -assignable: - ID {$$ = getType(look_up(cur,$1));} - | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} - | assignable rec_op ID {if(undefined != table_lookup(getRecList(look_up(cur, $1)), $3)){ - {$$ = getName(table_lookup(getRecList(look_up(cur, $1)), $3));}};} - ; - -rec_op : - DOT - -expression: - constant {printf("constant expression\n");} {$$ = $1;} - - | SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");if(strcmp($2,"integer") != 0) - {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("undefined");}else{$$=$2;}} - - | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); - printf("mismatch at line %d and column %d. Invalid type being negated is %s\n", - @1.first_line,@1.first_column,$2);}} - - | expression ADD expression - {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression SUB_OR_NEG expression - {printf("sub or neg expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression MUL expression - {printf("multiply expression\n"); - if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression DIV expression - {printf("divide expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression REM expression - {printf("remainder expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression AND expression - {printf("AND expression\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression OR expression - {printf("OR\n");if(strcmp($1,$3)==0 && - strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression LESS_THAN expression - {printf("less than expression\n");if(strcmp($1,$3)==0 && - strcmp($1,"integer")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression EQUAL_TO expression {printf("equals check expression\n"); - if(strcmp($1,$3)==0){$$=strdup("Boolean");} - else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| - strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s\n", - @2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} - - | assignable {printf("assignable expression. current type is %s\n",$1);$$=$1;} - - | L_PAREN expression R_PAREN {printf("paren expression. current type is %s\n",$2);$$=$2;} - - | memOp assignable {$$ = strdup("address");} - ; - - -ablock: -L_PAREN argument_list {$$ = $2;} R_PAREN - ; - -argument_list: -expression COMMA argument_list {$$ = $3 + 1;} -| expression {$$ = 1;} - ; - - -memOp: - RESERVE {printf("reserve expression\n");} - | RELEASE {printf("release expression\n");} - ; - - -constant: - C_STRING {$$ = $1;} - | C_INTEGER {$$ = "integer";} - | C_NULL {$$ = $1;} - | C_CHARACTER {$$ = $1;} - | C_TRUE {$$ = $1;} - | C_FALSE {$$ = $1;} - ; - -types: - // Commented out T_String below - // T_STRING {printf("string of T_STRING in types is %s\n",$1);} {$$ = $1;} - T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} - | T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$1);} {$$ = $1;} - | T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$1);} {$$ = $1;} - | T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$1);} {$$ = $1;} - ; - -%% - -void yyerror(const char *err) { - fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d\n", err,yytext,yylloc.first_line,yylloc.first_column); -} diff --git a/src/symbol_table.c b/src/symbol_table.c index 7f8849b..cdcbd30 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -921,4 +921,4 @@ TableNode *getNextEntry(TableNode *tn) { return tn->next; } printf("The type of the first entry is %s\n",First_Entry->theType); return 0; } - */ + */ \ No newline at end of file diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..e35809e --- /dev/null +++ b/test.sh @@ -0,0 +1,166 @@ +#!/bin/bash + +# Test Tool # +# The Translators - Spring 2025 # + +RED='\033[0;31m' +GREEN='\033[0;32m' +ORANGE='\033[0;33m' +BLUE='\033[0;34m' +PURPLE='\033[0;35m' +CYAN='\033[0;36m' +LIGHTGRAY='\033[0;37m' +DARKGRAY='\033[1;30m' +LIGHTRED='\033[1;31m' +LIGHTGREEN='\033[1;32m' +YELLOW='\033[1;33m' +LIGHTBLUE='\033[1;34m' +LIGHTPURPLE='\033[1;35m' +LIGHTCYAN='\033[1;36m' +WHITE='\033[1;37m' + +if [ ! -f "./alpha" ]; then + echo -e "${RED}[ERROR] ${YELLOW}File ./alpha not found!${WHITE}" + exit 1 +fi + +if [ ! -d "./out" ]; then + mkdir -p out +fi + +SWITCH=${YELLOW} +count=0 + +switchfunc() { + if [ $count -eq 0 ]; then + count=1 + SWITCH=${YELLOW} + else + count=0 + SWITCH='\033[0;35m' + fi +} + +if [ $# -eq 0 ]; then + echo -e "${YELLOW}[INFO] ${WHITE}Running all tests...${WHITE}" + echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-1 ---------------------------\n${WHITE}" + for file in ./tests/sprint1/test/*; do + if [ -f "$file" ]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + echo -e "" + + echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-2 ---------------------------\n${WHITE}" + for file in ./tests/sprint2/test/*; do + if [ -f "$file" ]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + echo -e "" + + echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-3 ---------------------------\n${WHITE}" + for file in ./tests/sprint3/test/*; do + if [ -f "$file" ]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + echo -e "" + + echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-4 ---------------------------\n${WHITE}" + for file in ./tests/sprint4/test/*; do + if [ -f "$file" ]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n${WHITE}" + switchfunc + fi + done + +else + if [ "$1" == "--help" ]; then + echo -e "${YELLOW}[INFO] ${WHITE}Usage: ./test.sh [prefix]" + echo -e "${YELLOW}[INFO] ${WHITE}--help: show this help message" + echo -e "${YELLOW}[INFO] ${WHITE}--file : run test with file" + exit 0 + fi + if [[ "$1" == "--file" ]]; then + shift + if [ $# -eq 0 ]; then + echo -e "${RED}[ERROR] ${YELLOW}No file specified!${WHITE}" + exit 1 + fi + if [ -f "$1" ]; then + filename=$(basename -- "$1") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$1" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}" + exit 1 + else + echo -e "${RED}[ERROR] ${YELLOW}File $1 not found!${WHITE}" + exit 1 + fi + fi + + if [[ "$1" == "sp1" ]]; then + echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..." + for file in ./tests/sprint1/test/*; do + if [[ "$file" == *"$1"* ]]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + elif [[ "$1" == "sp2" ]]; then + echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..." + for file in ./tests/sprint2/test/*; do + if [[ "$file" == *"$1"* ]]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + elif [[ "$1" == "sp3" ]]; then + echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..." + for file in ./tests/sprint3/test/*; do + if [[ "$file" == *"$1"* ]]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + elif [[ "$1" == "sp4" ]]; then + echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..." + for file in ./tests/sprint4/test/*; do + if [[ "$file" == *"$1"* ]]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + else + echo -e "${RED}[ERROR] ${YELLOW}Invalid prefix $1!${WHITE}" + exit 1 + fi +fi \ No newline at end of file diff --git a/tests/sprint2/test/test_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha similarity index 100% rename from tests/sprint2/test/test_carls_mistake.alpha rename to tests/sprint2/test/sp2_carls_mistake.alpha diff --git a/tests/sprint2/test/test_invalid_recop.alpha b/tests/sprint2/test/sp2_invalid_recop.alpha similarity index 100% rename from tests/sprint2/test/test_invalid_recop.alpha rename to tests/sprint2/test/sp2_invalid_recop.alpha diff --git a/tests/sprint2/test/test_invalid_release.alpha b/tests/sprint2/test/sp2_invalid_release.alpha similarity index 100% rename from tests/sprint2/test/test_invalid_release.alpha rename to tests/sprint2/test/sp2_invalid_release.alpha diff --git a/tests/sprint2/test/test_valid_assignable_and_mem.alpha b/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha similarity index 100% rename from tests/sprint2/test/test_valid_assignable_and_mem.alpha rename to tests/sprint2/test/sp2_valid_assignable_and_mem.alpha From 57ba34ab37ccb716b60e9079a366cfd34f049762 Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 28 Mar 2025 22:22:58 -0400 Subject: [PATCH 17/38] added a bunch of NULL checks --- src/grammar.y | 41 ++- src/symbol_table.c | 346 +++++++++++++++---------- tests/sprint2/sp2_function_types.alpha | 17 ++ 3 files changed, 260 insertions(+), 144 deletions(-) create mode 100644 tests/sprint2/sp2_function_types.alpha diff --git a/src/grammar.y b/src/grammar.y index fcb06b8..b7438bd 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -36,7 +36,7 @@ char * words; } - +%type idlist %type assignable %type expression %type constant @@ -121,27 +121,39 @@ prototype: L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; definition: -TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); +TYPE ID COLON { + printf("Currently see a record definition for %s\n", $2); + tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); if (table_lookup(getAncestor(cur), $2) == NULL) { printf("rec not found \n"); } }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); cur = getParent(cur);} - | TYPE ID COLON C_INTEGER ARROW id_or_types { CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} + | TYPE ID COLON C_INTEGER ARROW id_or_types + {printf("Currently see a array definition of name %s,storing type %s, of dimensions %d\n", + $2, $6, $4); + CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} | function_declaration | TYPE ID COLON id_or_types ARROW id_or_types { + printf("Currently see a function type definition of name %s,parameter type %s, of return type %s\n", + $2, $4, $6); CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); } | ID { TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + if (node == NULL) { printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); - } else { + }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } + else { setStartLine(node, @1.first_line); setAsKeyword(node, false); } cur = CreateScope(cur, 0, 0); } L_PAREN ID { + printf("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s\n", + $1,$4); CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); }R_PAREN ASSIGN sblock | ID { @@ -149,23 +161,29 @@ TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo if (node == NULL) { printf("null check\n"); } - if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + if (node == NULL) { printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); - } else { + }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } + else { setStartLine(node, @1.first_line); setAsKeyword(node, false); } cur = CreateScope(cur, 0, 0); }AS L_PAREN { TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); - if (parameter == NULL || getAdInfoType(parameter) != TYPE_RECORD) { + if (parameter == NULL) { printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); - } else { + }else if(getAdInfoType(parameter) != TYPE_RECORD){ + printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); + }else { for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ CreateEntry(cur, entry, NULL, NULL); } } - } idlist R_PAREN ASSIGN sblock + } idlist {printf("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d\n", + $1,$6);} R_PAREN ASSIGN sblock ; @@ -185,7 +203,7 @@ idlist: printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); } addName(entry, $1); - } COMMA idlist + } COMMA idlist {$$ = $3 + 1;} | ID { TableNode *entry = getFirstEntry(cur); @@ -196,6 +214,7 @@ idlist: printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); } addName(entry, $1); + $$ = 1; } ; diff --git a/src/symbol_table.c b/src/symbol_table.c index 7f8849b..e8e1868 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -19,6 +19,7 @@ TableNode *boo; TableNode *recprime; TableNode *funtypeprime; TableNode *undefined; +//AdInfo *Undefined_function_type_info; typedef enum { // First 4 below are primitive types that are all encapsulated in @@ -133,6 +134,10 @@ int getPrimSize(TableNode *definition) { // type stored in the array per professor, the actual size of the array is // calculated at runtime so bounds checking only needs to be done then AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { + if(type == NULL || type == undefined){ + printf("passed a NULL or undefined type reference to CreateArrayInfo. Invalid.\n"); + return NULL; + } AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); info->ArrayAdInfo = (array_info *)malloc(sizeof(array_info)); info->ArrayAdInfo->numofdimensions = dim; @@ -144,7 +149,7 @@ AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { // This gets the number of dimensions from array info int getNumArrDim(TableNode *definition) { if (definition == NULL|| definition == undefined){ - printf("passed an NULL entry to getNumArrDim function. Invalid.\n"); + printf("passed an NULL or undefined entry to getNumArrDim function. Invalid.\n"); return -1; } if (strcmp(getType(definition), "array") != 0) { @@ -156,6 +161,10 @@ int getNumArrDim(TableNode *definition) { // This gets the type stored in an array from arrtype. It returns a reference to // the entry of that type TableNode *getArrType(TableNode *definition) { + if(definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getArrType function. Invalid.\n"); + return NULL; + } if (strcmp(getType(definition), "array") != 0) { printf("not checking the type of an array -- invalid op\n"); return undefined; @@ -179,6 +188,10 @@ AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope) { // Perhaps this may not be needed since we need to iterate over all elements // anyways. int getRecLength(TableNode *definition) { + if (definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getRecLength function. Invalid.\n"); + return -1; + } if (strcmp(getType(definition), "record") != 0) { printf("not checking the length of an record -- invalid op\n"); return 0; @@ -187,6 +200,10 @@ int getRecLength(TableNode *definition) { } // This gets the array. Needs to up be updated to get the scope instead SymbolTable *getRecList(TableNode *definition) { + if (definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getRecList function. Invalid.\n"); + return NULL; + } if (strcmp(getType(definition), "record") != 0) { printf("not checking the list of types of a record -- invalid " "op\n"); @@ -205,13 +222,20 @@ TableNode* setRecSize(TableNode* tn, int n){ } int getRecSize(SymbolTable* tn){ + if(tn == NULL){ + printf("passed in NULL SymbolTable for getRecSize. Invalid\n"); + return -1; + } int s = 0; TableNode* cur = getFirstEntry(tn); + if (cur != NULL){ while(getNextEntry(cur) != NULL){ s++; cur = getNextEntry(cur); } return s; + } +return -1; } // below function takes a bool to see if parameter should be decomposed or not @@ -230,6 +254,10 @@ AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { // gets the line at which the function was first defined. (Can be used to print // out in table if needed) int getStartLine(TableNode *definition) { + if (definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getStartLine function. Invalid.\n"); + return -1; + } if (strcmp(getType(definition), "primitive function") != 0) { printf("not checking the start line of a function -- invalid " "op\n"); @@ -249,6 +277,10 @@ TableNode* setStartLine(TableNode* tn, int start){ // checks if "as" keyword was used for function definition. Either 0 or 1 for // not used or used. bool getAsKeyword(TableNode *definition) { + if (definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getAsKeyword function. Invalid.\n"); + return false; + } if (strcmp(getType(definition), "primitive function") != 0) { printf("not checking if a function is called with as or not -- " "invalid op\n"); @@ -268,6 +300,14 @@ TableNode* setAsKeyword(TableNode* tn, bool as){ // stores the type of a function (parameter type and return type) AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { + if(parameter == NULL||parameter == undefined){ + printf("passed a NULL or undefined parameter to CreateFunctionTypeInfo. Invalid.\n"); + return NULL; + } + if(returntype == NULL||returntype == undefined){ + printf("passed a NULL or undefined return type to CreateFunctionTypeInfo. Invalid.\n"); + return NULL; + } AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); info->FunTypeAdInfo = (function_type_info *)malloc(sizeof(function_type_info)); @@ -277,6 +317,10 @@ AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { } // returns parameter type of a function TableNode *getParameter(TableNode *definition) { + if (definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getParameter function. Invalid.\n"); + return undefined; + } if (strcmp(getType(definition), "primitive function type") != 0) { printf( "not checking the parameter of a function -- invalid op\n"); @@ -286,6 +330,10 @@ TableNode *getParameter(TableNode *definition) { } // returns return type of a function TableNode *getReturn(TableNode *definition) { + if (definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getReturn function. Invalid.\n"); + return NULL; + } if (strcmp(getType(definition), "primitive function type") != 0) { printf("not checking the return of a function -- invalid op\n"); return undefined; @@ -331,11 +379,11 @@ SymbolTable *init(SymbolTable *start) { "Cannot initialize a scope that is not the parent scope\n"); return NULL; } - integ = (TableNode *)malloc(sizeof(TableNode)); - addr = (TableNode *)malloc(sizeof(TableNode)); - chara = (TableNode *)malloc(sizeof(TableNode)); - stri = (TableNode *)malloc(sizeof(TableNode)); - boo = (TableNode *)malloc(sizeof(TableNode)); + integ = (TableNode *)calloc(1,sizeof(TableNode)); + addr = (TableNode *)calloc(1,sizeof(TableNode)); + chara = (TableNode *)calloc(1,sizeof(TableNode)); + stri = (TableNode *)calloc(1,sizeof(TableNode)); + boo = (TableNode *)calloc(1,sizeof(TableNode)); // TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); start->entries = integ; integ->next = addr; @@ -402,6 +450,8 @@ SymbolTable *init(SymbolTable *start) { undefined->additionalinfo = NULL; undefined->next = NULL; + //Undefined_function_type_info = CreateFunctionTypeInfo(undefined, undefined); + integ->theType = prime; addr->theType = prime; chara->theType = prime; @@ -465,31 +515,31 @@ int getAdInfoType(TableNode* tn){ printf("Entry being passed in has a null or undefined reference for theType. Invalid.\n"); return -1; } - if(strcmp(getType(tn),getName(integ))==0){ + if(strcmp(getName(tn),getName(integ))==0){ return TYPE_PRIMITIVE; } - if(strcmp(getType(tn),getName(addr))==0){ + if(strcmp(getName(tn),getName(addr))==0){ return TYPE_PRIMITIVE; } - if(strcmp(getType(tn),getName(chara))==0){ + if(strcmp(getName(tn),getName(chara))==0){ return TYPE_PRIMITIVE; } - if(strcmp(getType(tn),getName(stri))==0){ + if(strcmp(getName(tn),getName(stri))==0){ return TYPE_ARRAY; } - if(strcmp(getType(tn),getName(boo))==0){ + if(strcmp(getName(tn),getName(boo))==0){ return TYPE_PRIMITIVE; } - if(strcmp(getType(tn),getName(recprime))==0){ + if(strcmp(getName(tn),getName(recprime))==0){ return TYPE_RECORD; } - if(strcmp(getType(tn),getName(funtypeprime))==0){ + if(strcmp(getName(tn),getName(funtypeprime))==0){ return TYPE_FUNCTION_TYPE; } - if(strcmp(getType(tn),getName(arrayprim))==0){ + if(strcmp(getName(tn),getName(arrayprim))==0){ return TYPE_ARRAY; } - if(strcmp(getType(tn),getName(undefined))==0){ + if(strcmp(getName(tn),getName(undefined))==0){ return TYPE_UNDEFINED; } else{ @@ -497,13 +547,13 @@ int getAdInfoType(TableNode* tn){ } } -TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, - AdInfo *ad) { +TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, AdInfo *ad) { if (table == NULL) { printf("Null reference to table"); return undefined; } + /* TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); if(topDef == NULL){ @@ -553,8 +603,18 @@ char *getName(TableNode *tn) { return tn->theName; } -int getLine(SymbolTable *st) { return st->Line_Number; } -int getColumn(SymbolTable *st) { return st->Column_Number; } +int getLine(SymbolTable *st) { + if(st == NULL){ + printf("passed a NULL symbol table to getLine function. Invalid.\n"); + return -1; + } + return st->Line_Number; } +int getColumn(SymbolTable *st) { + if(st == NULL){ + printf("passed a NULL symbol table to getColumn function. Invalid.\n"); + return -1; + } + return st->Column_Number; } TableNode* addName(TableNode *tn, char* str){ if(tn == NULL||tn==undefined){ printf("passed a Null or undefined table node to the addName function. Invalid./n"); @@ -626,6 +686,10 @@ names\n"); return NULL; */ //only check table that is given TableNode *table_lookup(SymbolTable *table, char *x) { + if(table == NULL) { + printf("passed in empty scope. error.\n"); + return undefined; + } TableNode *entrie = table->entries; for (; entrie != NULL; entrie = entrie->next) { if (!strcmp(entrie->theName, x)) { @@ -648,8 +712,9 @@ TableNode *look_up(SymbolTable *table, char *x) { ,x,getLine(table),getColumn(table)); return look_up(table->Parent_Scope, x); } - +/* void print_symbol_table(SymbolTable *table, FILE *file_ptr) { + if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -674,7 +739,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } for (; entrie != NULL; entrie = entrie->next) { if (parant_scope == 0) { - /*have to update*/ if (strcmp(entrie->theType->theName, + /*have to update if (strcmp(entrie->theType->theName, "function primitive") || strcmp(entrie->theType->theName, "array")) { @@ -700,124 +765,139 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { "--------------:-------" "----------------------\n"); } -} -// void print_symbol_table(SymbolTable *table, FILE *file_ptr) { +}*/ +void print_symbol_table(SymbolTable *table, FILE *file_ptr) { -// if (table->Parent_Scope == NULL) { -// fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", -// "SCOPE", "PARENT", "TYPE", "Extra annotation"); -// } -// TableNode *entrie = table->entries; -// fprintf(file_ptr, "-----------------:--------:--------:----------------" -// "------:---------" -// "--------------------\n"); -// int parant_scope = 0; -// int current_scope = 0; -// if (table->Parent_Scope != NULL) { -// parant_scope = table->Parent_Scope->Line_Number * 1000 + -// table->Parent_Scope->Column_Number; -// current_scope = -// table->Line_Number * 1000 + table->Column_Number; -// } else { -// current_scope = 1001; -// } -// if (entrie == NULL) { -// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", -// current_scope, parant_scope, "", "Empty Scope"); -// } -// for (;entrie != NULL; entrie = entrie->next) { -// if (getAdInfoType(entrie) == TYPE_ARRAY){ -// if (parant_scope == 0) { + if (table->Parent_Scope == NULL) { + fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", + "SCOPE", "PARENT", "TYPE", "Extra annotation"); + } + TableNode *entrie = table->entries; + fprintf(file_ptr, "-----------------:--------:--------:----------------" + "------:---------" + "--------------------\n"); + int parant_scope = 0; + int current_scope = 0; + if (table->Parent_Scope != NULL) { + parant_scope = table->Parent_Scope->Line_Number * 1000 + + table->Parent_Scope->Column_Number; + current_scope = + table->Line_Number * 1000 + table->Column_Number; + } else { + current_scope = 1001; + } + if (entrie == NULL) { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", + current_scope, parant_scope, "", "Empty Scope"); + } + for (;entrie != NULL; entrie = entrie->next) { + if (getAdInfoType(entrie) == TYPE_ARRAY){ + if (parant_scope == 0) { -// fprintf(file_ptr, -// "%-17s: %06d : : %-21d -> %-21s: %-28s\n", -// entrie->theName, current_scope, -// entrie->additionalinfo->ArrayAdInfo->numofdimensions, -// entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, -// "Type of Array"); -// } else { -// fprintf(file_ptr, "%-17s: %06d : %06d : %-21d -> %-21s: %-28s\n", -// entrie->theName, current_scope, parant_scope, -// entrie->additionalinfo->ArrayAdInfo->numofdimensions, -// entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, -// "Type of Array"); -// } -// } -// if (getAdInfoType(entrie) == TYPE_RECORD){ -// if (parant_scope == 0) { + fprintf(file_ptr, + "%-17s: %06d : : %-21d -> %-21s: %-28s\n", + entrie->theName, current_scope, + entrie->additionalinfo->ArrayAdInfo->numofdimensions, + entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, + "Type of Array"); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21d -> %-21s: %-28s\n", + entrie->theName, current_scope, parant_scope, + entrie->additionalinfo->ArrayAdInfo->numofdimensions, + entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, + "Type of Array"); + } + } + if (getAdInfoType(entrie) == TYPE_RECORD){ + if (parant_scope == 0) { -// fprintf(file_ptr, -// "%-17s: %06d : :%-21s: elements-%-28d\n", -// entrie->theName, current_scope, -// "record", -// entrie->additionalinfo->RecAdInfo->numofelements); -// } else { -// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: elements-%-28d\n", -// entrie->theName, current_scope, parant_scope, -// "record", -// entrie->additionalinfo->RecAdInfo->numofelements); -// } -// } -// if (getAdInfoType(entrie) == TYPE_PRIMITIVE){ -// if (parant_scope == 0) { + fprintf(file_ptr, + "%-17s: %06d : :%-21s: elements-%-28d\n", + entrie->theName, current_scope, + "record", + entrie->additionalinfo->RecAdInfo->numofelements); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: elements-%-28d\n", + entrie->theName, current_scope, parant_scope, + "record", + entrie->additionalinfo->RecAdInfo->numofelements); + } + } + if (getAdInfoType(entrie) == TYPE_PRIMITIVE){ + if (parant_scope == 0) { -// fprintf(file_ptr, -// "%-17s: %06d : :%-21s: size-%-28d bytes\n", -// entrie->theName, current_scope, -// "Primitive", -// entrie->additionalinfo->PrimAdInfo->size); -// } else { -// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: size-%-28d bytes\n", -// entrie->theName, current_scope, parant_scope, -// "Primitive", -// entrie->additionalinfo->PrimAdInfo->size); -// } -// } -// if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE){ -// if (parant_scope == 0) { + fprintf(file_ptr, + "%-17s: %06d : :%-21s: size-%-28d bytes\n", + entrie->theName, current_scope, + "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: size-%-28d bytes\n", + entrie->theName, current_scope, parant_scope, + "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } + } + if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE){ + if (parant_scope == 0) { -// fprintf(file_ptr, -// "%-17s: %06d : : %-21s -> %-21s: %-28s\n", -// entrie->theName, current_scope, -// entrie->additionalinfo->FunTypeAdInfo->parameter->theName, -// entrie->additionalinfo->FunTypeAdInfo->returntype->theName, -// "Type of Function"); -// } else { -// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s -> %-21s: %-28s\n", -// entrie->theName, current_scope, parant_scope, -// entrie->additionalinfo->FunTypeAdInfo->parameter->theName, -// entrie->additionalinfo->FunTypeAdInfo->returntype->theName, -// "Type of Function"); -// } -// } -// if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION){ -// if (parant_scope == 0) { + fprintf(file_ptr, + "%-17s: %06d : : %-21s -> %-21s: %-28s\n", + entrie->theName, current_scope, + entrie->additionalinfo->FunTypeAdInfo->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo->returntype->theName, + "Type of Function"); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s -> %-21s: %-28s\n", + entrie->theName, current_scope, parant_scope, + entrie->additionalinfo->FunTypeAdInfo->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo->returntype->theName, + "Type of Function"); + } + } + if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION){ + if (parant_scope == 0) { -// fprintf(file_ptr, -// "%-17s: %06d : :%-21s: %-28s\n", -// entrie->theName, current_scope, -// getType(entrie), -// "Function"); -// } else { -// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", -// entrie->theName, current_scope, parant_scope, -// getType(entrie), -// "Function"); -// } -// } -// } -// if (table->Children_Scope != NULL) { -// ListOfTable *node = table->Children_Scope; -// for (; node != NULL; node = node->next) { -// print_symbol_table(node->table, file_ptr); -// } -// } -// if (table->Parent_Scope == NULL) { -// fprintf(file_ptr, "-----------------:--------:--------:--------" -// "--------------:-------" -// "----------------------\n"); -// } -// } + fprintf(file_ptr, + "%-17s: %06d : :%-21s: %-28s\n", + entrie->theName, current_scope, + getType(entrie), + "Function"); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", + entrie->theName, current_scope, parant_scope, + getType(entrie), + "Function"); + } + } + if (getAdInfoType(entrie) == TYPE_UNDEFINED){ + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-17s: %06d : :%-21s: %-28s\n", + entrie->theName, current_scope, + "undefined", + "undefined entry"); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", + entrie->theName, current_scope, parant_scope, + "undefined", + "undefined entry"); + } + } +} + if (table->Children_Scope != NULL) { + ListOfTable *node = table->Children_Scope; + for (; node != NULL; node = node->next) { + print_symbol_table(node->table, file_ptr); + } + } + if (table->Parent_Scope == NULL) { + fprintf(file_ptr, "-----------------:--------:--------:--------" + "--------------:-------" + "----------------------\n"); + } +} //get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { if(table == NULL){ diff --git a/tests/sprint2/sp2_function_types.alpha b/tests/sprint2/sp2_function_types.alpha new file mode 100644 index 0000000..509de78 --- /dev/null +++ b/tests/sprint2/sp2_function_types.alpha @@ -0,0 +1,17 @@ +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +function integerXinteger2integer: integerXinteger (*-> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer +external function reserve: integer2address +external function release: address2integer +function entry: string2integer*) \ No newline at end of file From d587ed9f3bc7639ca5435363ecf80e2cd81774cd Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 28 Mar 2025 23:33:08 -0400 Subject: [PATCH 18/38] Updated --- Makefile | 4 +- src/grammar.y | 2 +- src/runner.c | 13 +- src/symbol_table.c | 635 ++++++++++-------- test.sh | 18 +- .../{ => test}/sp2_function_types.alpha | 0 6 files changed, 383 insertions(+), 289 deletions(-) rename tests/sprint2/{ => test}/sp2_function_types.alpha (100%) diff --git a/Makefile b/Makefile index 0f04da9..4b92e65 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ debug: clean compiler test: chmod +x ./check.sh chmod +x ./test.sh - $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) || true);) + $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) -debug || true);) ./test.sh sp2 ./test.sh sp3 ./test.sh sp4 @@ -46,7 +46,7 @@ test: test-s1: chmod +x ./check.sh chmod +x ./test.sh - $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) || true);) + $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) -debug || true);) ./check.sh sp1 test-s2: diff --git a/src/grammar.y b/src/grammar.y index b7438bd..8ff8a8f 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -122,7 +122,7 @@ prototype: definition: TYPE ID COLON { - printf("Currently see a record definition for %s\n", $2); + printf("Currently see a record definition for %s\n", $2); tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); if (table_lookup(getAncestor(cur), $2) == NULL) { printf("rec not found \n"); diff --git a/src/runner.c b/src/runner.c index 68198f8..a87b527 100644 --- a/src/runner.c +++ b/src/runner.c @@ -9,8 +9,19 @@ extern TableNode *addr; extern TableNode *chara; extern TableNode *stri; extern TableNode *boo; +extern bool DEBUG; +extern char * COLOR_YELLOW; +extern char * COLOR_BLUE; +extern char * COLOR_WHITE; int main(int argc, char *argv[]) { + // if last argument is debug then set to true and ignore it for the rest of this file + if (argc > 1 && strcmp(argv[argc - 1], "-debug") == 0) { + DEBUG = true; + argc--; + } + + if (argc == 1) { fprintf(stderr, INVALID); return -1; @@ -221,4 +232,4 @@ void exit_scope() { return; } cur = cur->Parent_Scope; -} +} \ No newline at end of file diff --git a/src/symbol_table.c b/src/symbol_table.c index 26d8798..8fa87d2 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -19,7 +19,7 @@ TableNode *boo; TableNode *recprime; TableNode *funtypeprime; TableNode *undefined; -//AdInfo *Undefined_function_type_info; +// AdInfo *Undefined_function_type_info; typedef enum { // First 4 below are primitive types that are all encapsulated in @@ -44,9 +44,9 @@ typedef enum { // The Type being pointed to by the first 4 above that only stores the // size TYPE_PRIMITIVE = 6, - //likely NULL - TYPE_ALL_ELSE = 7, - TYPE_UNDEFINED = 8 + // likely NULL + TYPE_ALL_ELSE = 7, + TYPE_UNDEFINED = 8 } types; @@ -106,14 +106,15 @@ AdInfo *CreatePrimitiveInfo(int size) { // only gets the size of a primitive type int getPrimSize(TableNode *definition) { - if (definition == NULL || definition == undefined){ - printf("passed an NULL entry to getPrimSize function. Invalid.\n"); - return -1; - } - if (definition->additionalinfo == NULL){ - printf("node has NULL additionalinfo. Invalid.\n"); - return -1; - } + if (definition == NULL || definition == undefined) { + printf( + "passed an NULL entry to getPrimSize function. Invalid.\n"); + return -1; + } + if (definition->additionalinfo == NULL) { + printf("node has NULL additionalinfo. Invalid.\n"); + return -1; + } if (strcmp(getType(definition), "primitive") != 0) { printf("not checking the size of a primitive -- invalid op\n"); return 0; @@ -134,8 +135,9 @@ int getPrimSize(TableNode *definition) { // type stored in the array per professor, the actual size of the array is // calculated at runtime so bounds checking only needs to be done then AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { - if(type == NULL || type == undefined){ - printf("passed a NULL or undefined type reference to CreateArrayInfo. Invalid.\n"); + if (type == NULL || type == undefined) { + printf("passed a NULL or undefined type reference to " + "CreateArrayInfo. Invalid.\n"); return NULL; } AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); @@ -148,8 +150,9 @@ AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { } // This gets the number of dimensions from array info int getNumArrDim(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getNumArrDim function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getNumArrDim " + "function. Invalid.\n"); return -1; } if (strcmp(getType(definition), "array") != 0) { @@ -161,8 +164,9 @@ int getNumArrDim(TableNode *definition) { // This gets the type stored in an array from arrtype. It returns a reference to // the entry of that type TableNode *getArrType(TableNode *definition) { - if(definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getArrType function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getArrType " + "function. Invalid.\n"); return NULL; } if (strcmp(getType(definition), "array") != 0) { @@ -188,8 +192,9 @@ AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope) { // Perhaps this may not be needed since we need to iterate over all elements // anyways. int getRecLength(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getRecLength function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getRecLength " + "function. Invalid.\n"); return -1; } if (strcmp(getType(definition), "record") != 0) { @@ -200,8 +205,9 @@ int getRecLength(TableNode *definition) { } // This gets the array. Needs to up be updated to get the scope instead SymbolTable *getRecList(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getRecList function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getRecList " + "function. Invalid.\n"); return NULL; } if (strcmp(getType(definition), "record") != 0) { @@ -212,34 +218,34 @@ SymbolTable *getRecList(TableNode *definition) { return definition->additionalinfo->RecAdInfo->recordScope; } -TableNode* setRecSize(TableNode* tn, int n){ - if(tn == NULL||tn==undefined){ - printf("passed in NULL entry for setRecSize. Invalid\n"); - return undefined; - } - tn->additionalinfo->RecAdInfo->numofelements = n; - return tn; - } - -int getRecSize(SymbolTable* tn){ - if(tn == NULL){ +TableNode *setRecSize(TableNode *tn, int n) { + if (tn == NULL || tn == undefined) { + printf("passed in NULL entry for setRecSize. Invalid\n"); + return undefined; + } + tn->additionalinfo->RecAdInfo->numofelements = n; + return tn; +} + +int getRecSize(SymbolTable *tn) { + if (tn == NULL) { printf("passed in NULL SymbolTable for getRecSize. Invalid\n"); return -1; } - int s = 0; - TableNode* cur = getFirstEntry(tn); - if (cur != NULL){ - while(getNextEntry(cur) != NULL){ - s++; - cur = getNextEntry(cur); - } - return s; + int s = 0; + TableNode *cur = getFirstEntry(tn); + if (cur != NULL) { + while (getNextEntry(cur) != NULL) { + s++; + cur = getNextEntry(cur); + } + return s; } -return -1; - } + return -1; +} // below function takes a bool to see if parameter should be decomposed or not - ;// note that functions only take one input and have one output +; // note that functions only take one input and have one output // using "as" the input record can be decomposed to give the illusion of // multiple inputs Below function also has the line number where the function is // first defined @@ -254,8 +260,9 @@ AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { // gets the line at which the function was first defined. (Can be used to print // out in table if needed) int getStartLine(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getStartLine function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getStartLine " + "function. Invalid.\n"); return -1; } if (strcmp(getType(definition), "primitive function") != 0) { @@ -266,19 +273,21 @@ int getStartLine(TableNode *definition) { return definition->additionalinfo->FunDecAdInfo->startlinenumber; } -TableNode* setStartLine(TableNode* tn, int start){ - if(tn == NULL||tn==undefined){ - printf("passing in a NULL or undefined entry to setStartLine. invalid\n"); - return undefined; - } - tn->additionalinfo->FunDecAdInfo->startlinenumber = start; - return tn; - } +TableNode *setStartLine(TableNode *tn, int start) { + if (tn == NULL || tn == undefined) { + printf("passing in a NULL or undefined entry to setStartLine. " + "invalid\n"); + return undefined; + } + tn->additionalinfo->FunDecAdInfo->startlinenumber = start; + return tn; +} // checks if "as" keyword was used for function definition. Either 0 or 1 for // not used or used. bool getAsKeyword(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getAsKeyword function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getAsKeyword " + "function. Invalid.\n"); return false; } if (strcmp(getType(definition), "primitive function") != 0) { @@ -289,23 +298,26 @@ bool getAsKeyword(TableNode *definition) { return definition->additionalinfo->FunDecAdInfo->regularoras; } -TableNode* setAsKeyword(TableNode* tn, bool as){ - if(tn == NULL||tn==undefined){ - printf("passing in a NULL or undefined entry to setAsKeyword. invalid\n"); +TableNode *setAsKeyword(TableNode *tn, bool as) { + if (tn == NULL || tn == undefined) { + printf("passing in a NULL or undefined entry to setAsKeyword. " + "invalid\n"); return undefined; } - tn->additionalinfo->FunDecAdInfo->regularoras = as; - return tn; - } - + tn->additionalinfo->FunDecAdInfo->regularoras = as; + return tn; +} + // stores the type of a function (parameter type and return type) AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { - if(parameter == NULL||parameter == undefined){ - printf("passed a NULL or undefined parameter to CreateFunctionTypeInfo. Invalid.\n"); + if (parameter == NULL || parameter == undefined) { + printf("passed a NULL or undefined parameter to " + "CreateFunctionTypeInfo. Invalid.\n"); return NULL; } - if(returntype == NULL||returntype == undefined){ - printf("passed a NULL or undefined return type to CreateFunctionTypeInfo. Invalid.\n"); + if (returntype == NULL || returntype == undefined) { + printf("passed a NULL or undefined return type to " + "CreateFunctionTypeInfo. Invalid.\n"); return NULL; } AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); @@ -317,8 +329,9 @@ AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { } // returns parameter type of a function TableNode *getParameter(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getParameter function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getParameter " + "function. Invalid.\n"); return undefined; } if (strcmp(getType(definition), "primitive function type") != 0) { @@ -330,8 +343,9 @@ TableNode *getParameter(TableNode *definition) { } // returns return type of a function TableNode *getReturn(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getReturn function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getReturn " + "function. Invalid.\n"); return NULL; } if (strcmp(getType(definition), "primitive function type") != 0) { @@ -379,11 +393,11 @@ SymbolTable *init(SymbolTable *start) { "Cannot initialize a scope that is not the parent scope\n"); return NULL; } - integ = (TableNode *)calloc(1,sizeof(TableNode)); - addr = (TableNode *)calloc(1,sizeof(TableNode)); - chara = (TableNode *)calloc(1,sizeof(TableNode)); - stri = (TableNode *)calloc(1,sizeof(TableNode)); - boo = (TableNode *)calloc(1,sizeof(TableNode)); + integ = (TableNode *)calloc(1, sizeof(TableNode)); + addr = (TableNode *)calloc(1, sizeof(TableNode)); + chara = (TableNode *)calloc(1, sizeof(TableNode)); + stri = (TableNode *)calloc(1, sizeof(TableNode)); + boo = (TableNode *)calloc(1, sizeof(TableNode)); // TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); start->entries = integ; integ->next = addr; @@ -450,7 +464,8 @@ SymbolTable *init(SymbolTable *start) { undefined->additionalinfo = NULL; undefined->next = NULL; - //Undefined_function_type_info = CreateFunctionTypeInfo(undefined, undefined); + // Undefined_function_type_info = CreateFunctionTypeInfo(undefined, + // undefined); integ->theType = prime; addr->theType = prime; @@ -487,67 +502,71 @@ TableNode* boo; TableNode* recprime; TableNode* funtypeprime; */ -TableNode* populateTypeAndInfo(TableNode* tn, TableNode* type, AdInfo* info){ - if(tn == NULL||tn==undefined){ - printf("passed in an invalid table node to modify (NULL or undefined).\n"); - return undefined; - } - if(type == NULL||type==undefined){ - printf("passed in a NULL or undefined type reference to populate a table node. Invalid.\n"); - return undefined; - } - if(info == NULL){ - printf("passed in a NULL info reference to populate a table node. Invalid.\n"); - return undefined; - } - tn->theType = type; - tn->additionalinfo = info; - //returning reference to modified table node - return tn; - } +TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { + if (tn == NULL || tn == undefined) { + printf("passed in an invalid table node to modify (NULL or " + "undefined).\n"); + return undefined; + } + if (type == NULL || type == undefined) { + printf("passed in a NULL or undefined type reference to " + "populate a table node. Invalid.\n"); + return undefined; + } + if (info == NULL) { + printf("passed in a NULL info reference to populate a table " + "node. Invalid.\n"); + return undefined; + } + tn->theType = type; + tn->additionalinfo = info; + // returning reference to modified table node + return tn; +} -int getAdInfoType(TableNode* tn){ - if(tn == NULL||tn==undefined){ - printf("passing in NULL or undefined table entry. Invalid\n"); - return -1; - } - if(tn->theType == NULL|| tn->theType == undefined){ - printf("Entry being passed in has a null or undefined reference for theType. Invalid.\n"); - return -1; - } - if(strcmp(getName(tn),getName(integ))==0){ - return TYPE_PRIMITIVE; - } - if(strcmp(getName(tn),getName(addr))==0){ +int getAdInfoType(TableNode *tn) { + if (tn == NULL || tn == undefined) { + printf("passing in NULL or undefined table entry. Invalid\n"); + return -1; + } + if (tn->theType == NULL || tn->theType == undefined) { + printf("Entry being passed in has a null or undefined " + "reference for theType. Invalid.\n"); + return -1; + } + if (strcmp(getName(tn), getName(integ)) == 0) { return TYPE_PRIMITIVE; } - if(strcmp(getName(tn),getName(chara))==0){ + if (strcmp(getName(tn), getName(addr)) == 0) { return TYPE_PRIMITIVE; } - if(strcmp(getName(tn),getName(stri))==0){ + if (strcmp(getName(tn), getName(chara)) == 0) { + return TYPE_PRIMITIVE; + } + if (strcmp(getName(tn), getName(stri)) == 0) { return TYPE_ARRAY; } - if(strcmp(getName(tn),getName(boo))==0){ + if (strcmp(getName(tn), getName(boo)) == 0) { return TYPE_PRIMITIVE; } - if(strcmp(getName(tn),getName(recprime))==0){ + if (strcmp(getName(tn), getName(recprime)) == 0) { return TYPE_RECORD; } - if(strcmp(getName(tn),getName(funtypeprime))==0){ + if (strcmp(getName(tn), getName(funtypeprime)) == 0) { return TYPE_FUNCTION_TYPE; } - if(strcmp(getName(tn),getName(arrayprim))==0){ + if (strcmp(getName(tn), getName(arrayprim)) == 0) { return TYPE_ARRAY; } - if(strcmp(getName(tn),getName(undefined))==0){ - return TYPE_UNDEFINED; - } - else{ + if (strcmp(getName(tn), getName(undefined)) == 0) { + return TYPE_UNDEFINED; + } else { return TYPE_FUNCTION_DECLARATION; } } -TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, AdInfo *ad) { +TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, + AdInfo *ad) { if (table == NULL) { printf("Null reference to table"); @@ -561,11 +580,12 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, AdInfo * return NULL; } */ - if (typeOf == NULL||typeOf == undefined) { - printf("This is not pointing to a proper definition (either NULL or undefined)\n"); + if (typeOf == NULL || typeOf == undefined) { + printf("This is not pointing to a proper definition (either " + "NULL or undefined)\n"); return undefined; } - TableNode *newEntry = (TableNode *)calloc(1,sizeof(TableNode)); + TableNode *newEntry = (TableNode *)calloc(1, sizeof(TableNode)); newEntry->theType = typeOf /*topDef*/; newEntry->theName = id; newEntry->additionalinfo = ad; @@ -581,74 +601,85 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, AdInfo * } char *getType(TableNode *tn) { - if(tn == NULL||tn==undefined){ - printf("passed a NULL or undefined table entry to getType\n"); - return getName(undefined); - } - if(tn->theType == NULL|| tn->theType == undefined){ - printf("type of entry is currently NULL or undefined type \n"); - return getName(undefined); - } - return tn->theType->theName; } - -char *getName(TableNode *tn) { - if(tn == NULL||tn==undefined){ - //printf("passed a NULL or undefined table entry to getName\n"); - return undefined->theName; + if (tn == NULL || tn == undefined) { + printf("passed a NULL or undefined table entry to getType\n"); + return getName(undefined); } - if(tn->theName == NULL){ - //printf("name of entry is currently NULL, undefined \n"); - return undefined->theName; + if (tn->theType == NULL || tn->theType == undefined) { + printf("type of entry is currently NULL or undefined type \n"); + return getName(undefined); } - return tn->theName; + return tn->theType->theName; } -int getLine(SymbolTable *st) { - if(st == NULL){ - printf("passed a NULL symbol table to getLine function. Invalid.\n"); +char *getName(TableNode *tn) { + if (tn == NULL || tn == undefined) { + // printf("passed a NULL or undefined table entry to + // getName\n"); + return undefined->theName; + } + if (tn->theName == NULL) { + // printf("name of entry is currently NULL, undefined \n"); + return undefined->theName; + } + return tn->theName; +} + +int getLine(SymbolTable *st) { + if (st == NULL) { + printf("passed a NULL symbol table to getLine function. " + "Invalid.\n"); return -1; } - return st->Line_Number; } -int getColumn(SymbolTable *st) { - if(st == NULL){ - printf("passed a NULL symbol table to getColumn function. Invalid.\n"); + return st->Line_Number; +} +int getColumn(SymbolTable *st) { + if (st == NULL) { + printf("passed a NULL symbol table to getColumn function. " + "Invalid.\n"); return -1; } - return st->Column_Number; } -TableNode* addName(TableNode *tn, char* str){ - if(tn == NULL||tn==undefined){ - printf("passed a Null or undefined table node to the addName function. Invalid./n"); - return undefined; - } - if(tn->theName != NULL){ - printf("Name doesn't look like it is empty before you change. Are you sure you need to update name?/n"); + return st->Column_Number; +} +TableNode *addName(TableNode *tn, char *str) { + if (tn == NULL || tn == undefined) { + printf("passed a Null or undefined table node to the addName " + "function. Invalid./n"); return undefined; - } - if(str == NULL){ - printf("passed a NULL string to the addName function. Invalid./n"); + } + if (tn->theName != NULL) { + printf("Name doesn't look like it is empty before you change. " + "Are you sure you need to update name?/n"); return undefined; - } + } + if (str == NULL) { + printf( + "passed a NULL string to the addName function. Invalid./n"); + return undefined; + } tn->theName = str; return tn; } -SymbolTable* setLineNumber(SymbolTable *st,int line){ - if(st == NULL){ - printf("passed a Null Symbol Table to the setLineNumber function. Invalid./n"); - return st; - } - st->Line_Number = line; - return st; - } - -SymbolTable* setColumnNumber(SymbolTable *st,int column){ - if(st == NULL){ - printf("passed a Null Symbol Table to the setColumnNumber function. Invalid./n"); +SymbolTable *setLineNumber(SymbolTable *st, int line) { + if (st == NULL) { + printf("passed a Null Symbol Table to the setLineNumber " + "function. Invalid./n"); return st; - } - st->Line_Number = column; - return st; } + st->Line_Number = line; + return st; +} + +SymbolTable *setColumnNumber(SymbolTable *st, int column) { + if (st == NULL) { + printf("passed a Null Symbol Table to the setColumnNumber " + "function. Invalid./n"); + return st; + } + st->Line_Number = column; + return st; +} /* //we use false for type defs and true for functions for parameter of typeOf TableNode* Define(SymbolTable* table, bool typeOf, char* id) { @@ -684,9 +715,9 @@ names\n"); return NULL; } */ -//only check table that is given +// only check table that is given TableNode *table_lookup(SymbolTable *table, char *x) { - if(table == NULL) { + if (table == NULL) { printf("passed in empty scope. error.\n"); return undefined; } @@ -698,23 +729,24 @@ TableNode *table_lookup(SymbolTable *table, char *x) { } return undefined; } -//check current table and all parents +// check current table and all parents TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { - printf("passed in empty scope. error.\n"); + printf("passed in empty scope. error.\n"); return undefined; } TableNode *ret = table_lookup(table, x); if (ret != NULL && ret != undefined) { return ret; } - printf("could not find %s in scope that started at line %d and column %d so moving up a scope\n" - ,x,getLine(table),getColumn(table)); + printf("could not find %s in scope that started at line %d and column " + "%d so moving up a scope\n", + x, getLine(table), getColumn(table)); return look_up(table->Parent_Scope, x); } /* void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - + if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -767,7 +799,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } }*/ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - + if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -790,102 +822,127 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", current_scope, parant_scope, "", "Empty Scope"); } - for (;entrie != NULL; entrie = entrie->next) { - if (getAdInfoType(entrie) == TYPE_ARRAY){ - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-17s: %06d : : %-21d -> %-21s: %-28s\n", - entrie->theName, current_scope, - entrie->additionalinfo->ArrayAdInfo->numofdimensions, - entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, - "Type of Array"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21d -> %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - entrie->additionalinfo->ArrayAdInfo->numofdimensions, - entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, - "Type of Array"); - } - } - if (getAdInfoType(entrie) == TYPE_RECORD){ - if (parant_scope == 0) { + for (; entrie != NULL; entrie = entrie->next) { + if (getAdInfoType(entrie) == TYPE_ARRAY) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-17s: %06d : :%-21s: elements-%-28d\n", - entrie->theName, current_scope, - "record", - entrie->additionalinfo->RecAdInfo->numofelements); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: elements-%-28d\n", - entrie->theName, current_scope, parant_scope, - "record", - entrie->additionalinfo->RecAdInfo->numofelements); + fprintf(file_ptr, + "%-17s: %06d : : %-21d -> " + "%-21s: %-28s\n", + entrie->theName, current_scope, + entrie->additionalinfo->ArrayAdInfo + ->numofdimensions, + entrie->additionalinfo->ArrayAdInfo + ->typeofarray->theName, + "Type of Array"); + } else { + fprintf(file_ptr, + "%-17s: %06d : %06d : %-21d -> %-21s: " + "%-28s\n", + entrie->theName, current_scope, + parant_scope, + entrie->additionalinfo->ArrayAdInfo + ->numofdimensions, + entrie->additionalinfo->ArrayAdInfo + ->typeofarray->theName, + "Type of Array"); + } } - } - if (getAdInfoType(entrie) == TYPE_PRIMITIVE){ - if (parant_scope == 0) { + if (getAdInfoType(entrie) == TYPE_RECORD) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-17s: %06d : :%-21s: size-%-28d bytes\n", - entrie->theName, current_scope, - "Primitive", - entrie->additionalinfo->PrimAdInfo->size); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: size-%-28d bytes\n", - entrie->theName, current_scope, parant_scope, - "Primitive", - entrie->additionalinfo->PrimAdInfo->size); + fprintf(file_ptr, + "%-17s: %06d : :%-21s: " + "elements-%-28d\n", + entrie->theName, current_scope, + "record", + entrie->additionalinfo->RecAdInfo + ->numofelements); + } else { + fprintf(file_ptr, + "%-17s: %06d : %06d : %-21s: " + "elements-%-28d\n", + entrie->theName, current_scope, + parant_scope, "record", + entrie->additionalinfo->RecAdInfo + ->numofelements); + } } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE){ - if (parant_scope == 0) { + if (getAdInfoType(entrie) == TYPE_PRIMITIVE) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-17s: %06d : : %-21s -> %-21s: %-28s\n", - entrie->theName, current_scope, - entrie->additionalinfo->FunTypeAdInfo->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo->returntype->theName, - "Type of Function"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s -> %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - entrie->additionalinfo->FunTypeAdInfo->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo->returntype->theName, - "Type of Function"); + fprintf( + file_ptr, + "%-17s: %06d : :%-21s: size-%-28d " + "bytes\n", + entrie->theName, current_scope, "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } else { + fprintf( + file_ptr, + "%-17s: %06d : %06d : %-21s: size-%-28d " + "bytes\n", + entrie->theName, current_scope, + parant_scope, "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION){ - if (parant_scope == 0) { + if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-17s: %06d : :%-21s: %-28s\n", - entrie->theName, current_scope, - getType(entrie), - "Function"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - getType(entrie), - "Function"); + fprintf(file_ptr, + "%-17s: %06d : : %-21s -> " + "%-21s: %-28s\n", + entrie->theName, current_scope, + entrie->additionalinfo->FunTypeAdInfo + ->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo + ->returntype->theName, + "Type of Function"); + } else { + fprintf(file_ptr, + "%-17s: %06d : %06d : %-21s -> %-21s: " + "%-28s\n", + entrie->theName, current_scope, + parant_scope, + entrie->additionalinfo->FunTypeAdInfo + ->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo + ->returntype->theName, + "Type of Function"); + } } - } - if (getAdInfoType(entrie) == TYPE_UNDEFINED){ - if (parant_scope == 0) { + if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-17s: %06d : :%-21s: %-28s\n", - entrie->theName, current_scope, - "undefined", - "undefined entry"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - "undefined", - "undefined entry"); + fprintf(file_ptr, + "%-17s: %06d : :%-21s: %-28s\n", + entrie->theName, current_scope, + getType(entrie), "Function"); + } else { + fprintf(file_ptr, + "%-17s: %06d : %06d : %-21s: %-28s\n", + entrie->theName, current_scope, + parant_scope, getType(entrie), + "Function"); + } + } + if (getAdInfoType(entrie) == TYPE_UNDEFINED) { + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-17s: %06d : :%-21s: %-28s\n", + entrie->theName, current_scope, + "undefined", "undefined entry"); + } else { + fprintf(file_ptr, + "%-17s: %06d : %06d : %-21s: %-28s\n", + entrie->theName, current_scope, + parant_scope, "undefined", + "undefined entry"); + } } } -} if (table->Children_Scope != NULL) { ListOfTable *node = table->Children_Scope; for (; node != NULL; node = node->next) { @@ -898,12 +955,12 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { "----------------------\n"); } } -//get top most symbol table +// get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { - if(table == NULL){ - printf("passing a NULL reference to getAncestor. Invalid.\n"); - return NULL; - } + if (table == NULL) { + printf("passing a NULL reference to getAncestor. Invalid.\n"); + return NULL; + } if (table->Parent_Scope == NULL) { // if table has no parent, return itself return table; @@ -941,16 +998,17 @@ SymbolTable *removeEntry(SymbolTable *scope, char *search) { return scope; } -//almost certainly don't need to use the below function since type checking happens by passing types up the grammar +// almost certainly don't need to use the below function since type checking +// happens by passing types up the grammar bool typeCheck(char *firstID, char *secondID) { TableNode *entry1 = look_up(cur, firstID); TableNode *entry2 = look_up(cur, secondID); - if (entry1 == NULL|| entry1 == undefined) { + if (entry1 == NULL || entry1 == undefined) { printf("first type not defined\n"); return false; } - if (entry2 == NULL|| entry2 == undefined) { + if (entry2 == NULL || entry2 == undefined) { printf("second type not defined\n"); return false; } @@ -1001,4 +1059,29 @@ TableNode *getNextEntry(TableNode *tn) { return tn->next; } printf("The type of the first entry is %s\n",First_Entry->theType); return 0; } - */ \ No newline at end of file + */ + +char *getLineStr(); +char *COLOR_RED = "\033[0;31m"; +char *COLOR_GREEN = "\033[0;32m"; +char *COLOR_ORANGE = "\033[0;33m"; +char *COLOR_BLUE = "\033[0;34m"; +char *COLOR_PURPLE = "\033[0;35m"; +char *COLOR_CYAN = "\033[0;36m"; +char *COLOR_LIGHTGRAY = "\033[0;37m"; +char *COLOR_DARKGRAY = "\033[1;30m"; +char *COLOR_LIGHTRED = "\033[1;31m"; +char *COLOR_LIGHTGREEN = "\033[1;32m"; +char *COLOR_YELLOW = "\033[1;33m"; +char *COLOR_LIGHTBLUE = "\033[1;34m"; +char *COLOR_LIGHTPURPLE = "\033[1;35m"; +char *COLOR_LIGHTCYAN = "\033[1;36m"; +char *COLOR_WHITE = "\033[1;37m"; + +bool DEBUG = false; + +char *getLineStr(int d) { + char *new_text = malloc(100); + sprintf(new_text, "%s[%d]%s ", COLOR_DARKGRAY, d, COLOR_WHITE); + return new_text; +} \ No newline at end of file diff --git a/test.sh b/test.sh index e35809e..9c32bed 100755 --- a/test.sh +++ b/test.sh @@ -48,7 +48,7 @@ if [ $# -eq 0 ]; then if [ -f "$file" ]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -60,7 +60,7 @@ if [ $# -eq 0 ]; then if [ -f "$file" ]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -72,7 +72,7 @@ if [ $# -eq 0 ]; then if [ -f "$file" ]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -84,7 +84,7 @@ if [ $# -eq 0 ]; then if [ -f "$file" ]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n${WHITE}" switchfunc fi @@ -106,7 +106,7 @@ else if [ -f "$1" ]; then filename=$(basename -- "$1") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$1" + ./alpha -st "$1" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}" exit 1 else @@ -121,7 +121,7 @@ else if [[ "$file" == *"$1"* ]]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -132,7 +132,7 @@ else if [[ "$file" == *"$1"* ]]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -143,7 +143,7 @@ else if [[ "$file" == *"$1"* ]]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -154,7 +154,7 @@ else if [[ "$file" == *"$1"* ]]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi diff --git a/tests/sprint2/sp2_function_types.alpha b/tests/sprint2/test/sp2_function_types.alpha similarity index 100% rename from tests/sprint2/sp2_function_types.alpha rename to tests/sprint2/test/sp2_function_types.alpha From be311c7418218c4f8ea8aa3c1ce7578b877d9251 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 31 Mar 2025 11:43:30 -0400 Subject: [PATCH 19/38] printdebug function with line and file names --- src/grammar.y | 114 ++++++++++---------- src/runner.c | 10 +- src/symbol_table.c | 263 +++++++++++++++++++++++++-------------------- 3 files changed, 206 insertions(+), 181 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 8ff8a8f..6421c42 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -27,7 +27,7 @@ extern TableNode* chara; extern TableNode* stri; extern TableNode* boo; - TableNode * tn; + TableNode * tn; %} //%define api.location.type {location_t} %locations @@ -122,29 +122,29 @@ prototype: definition: TYPE ID COLON { - printf("Currently see a record definition for %s\n", $2); + printdebug("Currently see a record definition for %s", $2); tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); if (table_lookup(getAncestor(cur), $2) == NULL) { - printf("rec not found \n"); + printdebug("rec not found "); } }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); cur = getParent(cur);} | TYPE ID COLON C_INTEGER ARROW id_or_types - {printf("Currently see a array definition of name %s,storing type %s, of dimensions %d\n", + {printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, $6, $4); CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} | function_declaration | TYPE ID COLON id_or_types ARROW id_or_types { - printf("Currently see a function type definition of name %s,parameter type %s, of return type %s\n", + printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", $2, $4, $6); CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); } | ID { TableNode *node = table_lookup(getAncestor(cur), $1); if (node == NULL) { - printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); } else { setStartLine(node, @1.first_line); @@ -152,19 +152,19 @@ TYPE ID COLON { } cur = CreateScope(cur, 0, 0); } L_PAREN ID { - printf("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s\n", + printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", $1,$4); CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); }R_PAREN ASSIGN sblock | ID { TableNode *node = table_lookup(getAncestor(cur), $1); if (node == NULL) { - printf("null check\n"); + printdebug("null check"); } if (node == NULL) { - printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); } else { setStartLine(node, @1.first_line); @@ -174,15 +174,15 @@ TYPE ID COLON { }AS L_PAREN { TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); if (parameter == NULL) { - printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); + printdebug("function defined with as, but parameter is not a record at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(parameter) != TYPE_RECORD){ - printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); + printdebug("function defined with as, but parameter is not a record at line %d, column %d", @1.first_line, @1.first_column); }else { for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ CreateEntry(cur, entry, NULL, NULL); } } - } idlist {printf("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d\n", + } idlist {printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", $1,$6);} R_PAREN ASSIGN sblock ; @@ -200,7 +200,7 @@ idlist: entry = getNextEntry(entry); } if (getNextEntry(entry) == NULL) { - printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); } addName(entry, $1); } COMMA idlist {$$ = $3 + 1;} @@ -211,7 +211,7 @@ idlist: entry = getNextEntry(entry); } if (getNextEntry(entry) != NULL) { - printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); } addName(entry, $1); $$ = 1; @@ -222,7 +222,7 @@ idlist: sblock: L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE | L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock - {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE + {printdebug("seen sblock with dblock");} statement_list {cur = getParent(cur);} R_BRACE ; dblock: @@ -234,14 +234,14 @@ declaration_list: ; declaration: - id_or_types COLON ID {printf("ID/TYPE: %s, ID: %s\n", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } + id_or_types COLON ID {printdebug("ID/TYPE: %s, ID: %s", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } ; id_or_types: - ID {printf("string of id is %s in ID pattern of id_or_type rule.\n"); $$ = $1;} - //{printf("string of id is %s in ID pattern of id_or_type rule. Type passed up the tree is %s.\n",$1,getType(look_up(cur,$1))); $$ = getType(look_up(cur,$1));} - | types {printf("string of type is %s in types pattern of id_or_type rule.\n",$1);} {$$ = $1;} - //{printf("string of type is %s in types pattern of id_or_type rule. That is passed up the tree.\n",$1);} {$$ = $1;} + ID {printdebug("string of id is %s in ID pattern of id_or_type rule."); $$ = $1;} + //{printdebug("string of id is %s in ID pattern of id_or_type rule. Type passed up the tree is %s.",$1,getType(look_up(cur,$1))); $$ = getType(look_up(cur,$1));} + | types {printdebug("string of type is %s in types pattern of id_or_type rule.",$1);} {$$ = $1;} + //{printdebug("string of type is %s in types pattern of id_or_type rule. That is passed up the tree.",$1);} {$$ = $1;} ; ; @@ -255,13 +255,13 @@ statement_list: compound_statement: WHILE L_PAREN expression R_PAREN sblock | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock - | sblock //{printf("seen a compound statement rule\n");} + | sblock //{printdebug("seen a compound statement rule");} ; simple_statement: assignable ASSIGN expression {if(strcmp($1, $3) == 0){ } else { - printf("Mismatch at line %d and column%d\n", @2.first_line, @2.first_column); + printdebug("Mismatch at line %d and column%d", @2.first_line, @2.first_column); }} | RETURN expression @@ -278,77 +278,77 @@ rec_op : DOT expression: - constant {printf("constant expression\n");} {$$ = $1;} + constant {printdebug("constant expression");} {$$ = $1;} - | SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");if(strcmp($2,"integer") != 0) - {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column); + | SUB_OR_NEG expression %prec UMINUS {printdebug("negative expression");if(strcmp($2,"integer") != 0) + {printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column); $$=strdup("undefined");}else{$$=$2;}} - | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); - printf("mismatch at line %d and column %d. Invalid type being negated is %s\n", + | NOT expression {printdebug("not expression"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); + printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,$2);}} | expression ADD expression - {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + {printdebug("add expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression SUB_OR_NEG expression - {printf("sub or neg expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + {printdebug("sub or neg expression");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression MUL expression - {printf("multiply expression\n"); + {printdebug("multiply expression"); if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression DIV expression - {printf("divide expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + {printdebug("divide expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression REM expression - {printf("remainder expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + {printdebug("remainder expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression AND expression - {printf("AND expression\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + {printdebug("AND expression");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression OR expression - {printf("OR\n");if(strcmp($1,$3)==0 && + {printdebug("OR");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression LESS_THAN expression - {printf("less than expression\n");if(strcmp($1,$3)==0 && + {printdebug("less than expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} - | expression EQUAL_TO expression {printf("equals check expression\n"); + | expression EQUAL_TO expression {printdebug("equals check expression"); if(strcmp($1,$3)==0){$$=strdup("Boolean");} else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s\n", + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} - | assignable {printf("assignable expression. current type is %s\n",$1);$$=$1;} + | assignable {printdebug("assignable expression. current type is %s",$1);$$=$1;} - | L_PAREN expression R_PAREN {printf("paren expression. current type is %s\n",$2);$$=$2;} + | L_PAREN expression R_PAREN {printdebug("paren expression. current type is %s",$2);$$=$2;} | memOp assignable {$$ = strdup("address");} ; @@ -365,8 +365,8 @@ expression COMMA argument_list {$$ = $3 + 1;} memOp: - RESERVE {printf("reserve expression\n");} - | RELEASE {printf("release expression\n");} + RESERVE {printdebug("reserve expression");} + | RELEASE {printdebug("release expression");} ; @@ -381,15 +381,15 @@ constant: types: // Commented out T_String below - // T_STRING {printf("string of T_STRING in types is %s\n",$1);} {$$ = $1;} - T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} - | T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$1);} {$$ = $1;} - | T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$1);} {$$ = $1;} - | T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$1);} {$$ = $1;} + // T_STRING {printdebug("string of T_STRING in types is %s",$1);} {$$ = $1;} + T_INTEGER {printdebug("string of T_INTEGER in types is %s",$1);} {$$ = $1;} + | T_ADDRESS {printdebug("string of T_ADDRESS in types is %s",$1);} {$$ = $1;} + | T_CHARACTER {printdebug("string of T_CHARACTER in types is %s",$1);} {$$ = $1;} + | T_BOOLEAN {printdebug("string of T_BOOLEAN in types is %s",$1);} {$$ = $1;} ; %% void yyerror(const char *err) { - fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d\n", err,yytext,yylloc.first_line,yylloc.first_column); + fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d", err,yytext,yylloc.first_line,yylloc.first_column); } diff --git a/src/runner.c b/src/runner.c index a87b527..7c053a4 100644 --- a/src/runner.c +++ b/src/runner.c @@ -10,18 +10,18 @@ extern TableNode *chara; extern TableNode *stri; extern TableNode *boo; extern bool DEBUG; -extern char * COLOR_YELLOW; -extern char * COLOR_BLUE; -extern char * COLOR_WHITE; +extern char *COLOR_YELLOW; +extern char *COLOR_BLUE; +extern char *COLOR_WHITE; int main(int argc, char *argv[]) { - // if last argument is debug then set to true and ignore it for the rest of this file + // if last argument is debug then set to true and ignore it for the rest + // of this file if (argc > 1 && strcmp(argv[argc - 1], "-debug") == 0) { DEBUG = true; argc--; } - if (argc == 1) { fprintf(stderr, INVALID); return -1; diff --git a/src/symbol_table.c b/src/symbol_table.c index 8fa87d2..4531f1d 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -3,6 +3,7 @@ #include "symbol_table.h" +#include #include #include #include @@ -19,8 +20,43 @@ TableNode *boo; TableNode *recprime; TableNode *funtypeprime; TableNode *undefined; -// AdInfo *Undefined_function_type_info; +char *COLOR_RED = "\033[0;31m"; +char *COLOR_GREEN = "\033[0;32m"; +char *COLOR_ORANGE = "\033[0;33m"; +char *COLOR_BLUE = "\033[0;34m"; +char *COLOR_PURPLE = "\033[0;35m"; +char *COLOR_CYAN = "\033[0;36m"; +char *COLOR_LIGHTGRAY = "\033[0;37m"; +char *COLOR_DARKGRAY = "\033[1;30m"; +char *COLOR_LIGHTRED = "\033[1;31m"; +char *COLOR_LIGHTGREEN = "\033[1;32m"; +char *COLOR_YELLOW = "\033[1;33m"; +char *COLOR_LIGHTBLUE = "\033[1;34m"; +char *COLOR_LIGHTPURPLE = "\033[1;35m"; +char *COLOR_LIGHTCYAN = "\033[1;36m"; +char *COLOR_WHITE = "\033[1;37m"; + +bool DEBUG = true; + +void printdebug_impl(char *file, int line, const char *format, ...); + +void printdebug_impl(char *file, int line, const char *format, ...) { + if (DEBUG) { + printf("%s<%s> [%d]%s ", COLOR_DARKGRAY, file, line, + COLOR_WHITE); + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); + printf("\n"); + } +} + +#define printdebug(format, ...) \ + printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) + +// AdInfo *Undefined_function_type_info; typedef enum { // First 4 below are primitive types that are all encapsulated in // primitive type @@ -107,16 +143,17 @@ AdInfo *CreatePrimitiveInfo(int size) { // only gets the size of a primitive type int getPrimSize(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf( - "passed an NULL entry to getPrimSize function. Invalid.\n"); + printdebug( + "passed an NULL entry to getPrimSize function. Invalid."); return -1; } if (definition->additionalinfo == NULL) { - printf("node has NULL additionalinfo. Invalid.\n"); + printdebug("node has NULL additionalinfo. Invalid."); return -1; } if (strcmp(getType(definition), "primitive") != 0) { - printf("not checking the size of a primitive -- invalid op\n"); + printdebug( + "not checking the size of a primitive -- invalid op"); return 0; } return definition->additionalinfo->PrimAdInfo->size; @@ -136,8 +173,8 @@ int getPrimSize(TableNode *definition) { // calculated at runtime so bounds checking only needs to be done then AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { if (type == NULL || type == undefined) { - printf("passed a NULL or undefined type reference to " - "CreateArrayInfo. Invalid.\n"); + printdebug("passed a NULL or undefined type reference to " + "CreateArrayInfo. Invalid."); return NULL; } AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); @@ -151,12 +188,12 @@ AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { // This gets the number of dimensions from array info int getNumArrDim(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getNumArrDim " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getNumArrDim " + "function. Invalid."); return -1; } if (strcmp(getType(definition), "array") != 0) { - printf("not checking the dim of an array -- invalid op\n"); + printdebug("not checking the dim of an array -- invalid op"); return 0; } return definition->additionalinfo->ArrayAdInfo->numofdimensions; @@ -165,12 +202,12 @@ int getNumArrDim(TableNode *definition) { // the entry of that type TableNode *getArrType(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getArrType " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getArrType " + "function. Invalid."); return NULL; } if (strcmp(getType(definition), "array") != 0) { - printf("not checking the type of an array -- invalid op\n"); + printdebug("not checking the type of an array -- invalid op"); return undefined; } return definition->additionalinfo->ArrayAdInfo->typeofarray; @@ -193,12 +230,13 @@ AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope) { // anyways. int getRecLength(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getRecLength " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getRecLength " + "function. Invalid."); return -1; } if (strcmp(getType(definition), "record") != 0) { - printf("not checking the length of an record -- invalid op\n"); + printdebug( + "not checking the length of an record -- invalid op"); return 0; } return definition->additionalinfo->RecAdInfo->numofelements; @@ -206,13 +244,14 @@ int getRecLength(TableNode *definition) { // This gets the array. Needs to up be updated to get the scope instead SymbolTable *getRecList(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getRecList " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getRecList " + "function. Invalid."); return NULL; } if (strcmp(getType(definition), "record") != 0) { - printf("not checking the list of types of a record -- invalid " - "op\n"); + printdebug( + "not checking the list of types of a record -- invalid " + "op"); return NULL; } return definition->additionalinfo->RecAdInfo->recordScope; @@ -220,7 +259,7 @@ SymbolTable *getRecList(TableNode *definition) { TableNode *setRecSize(TableNode *tn, int n) { if (tn == NULL || tn == undefined) { - printf("passed in NULL entry for setRecSize. Invalid\n"); + printdebug("passed in NULL entry for setRecSize. Invalid"); return undefined; } tn->additionalinfo->RecAdInfo->numofelements = n; @@ -229,7 +268,8 @@ TableNode *setRecSize(TableNode *tn, int n) { int getRecSize(SymbolTable *tn) { if (tn == NULL) { - printf("passed in NULL SymbolTable for getRecSize. Invalid\n"); + printdebug( + "passed in NULL SymbolTable for getRecSize. Invalid"); return -1; } int s = 0; @@ -261,13 +301,14 @@ AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { // out in table if needed) int getStartLine(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getStartLine " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getStartLine " + "function. Invalid."); return -1; } if (strcmp(getType(definition), "primitive function") != 0) { - printf("not checking the start line of a function -- invalid " - "op\n"); + printdebug( + "not checking the start line of a function -- invalid " + "op"); return 0; } return definition->additionalinfo->FunDecAdInfo->startlinenumber; @@ -275,8 +316,9 @@ int getStartLine(TableNode *definition) { TableNode *setStartLine(TableNode *tn, int start) { if (tn == NULL || tn == undefined) { - printf("passing in a NULL or undefined entry to setStartLine. " - "invalid\n"); + printdebug( + "passing in a NULL or undefined entry to setStartLine. " + "invalid"); return undefined; } tn->additionalinfo->FunDecAdInfo->startlinenumber = start; @@ -286,13 +328,14 @@ TableNode *setStartLine(TableNode *tn, int start) { // not used or used. bool getAsKeyword(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getAsKeyword " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getAsKeyword " + "function. Invalid."); return false; } if (strcmp(getType(definition), "primitive function") != 0) { - printf("not checking if a function is called with as or not -- " - "invalid op\n"); + printdebug( + "not checking if a function is called with as or not -- " + "invalid op"); return 0; } return definition->additionalinfo->FunDecAdInfo->regularoras; @@ -300,8 +343,9 @@ bool getAsKeyword(TableNode *definition) { TableNode *setAsKeyword(TableNode *tn, bool as) { if (tn == NULL || tn == undefined) { - printf("passing in a NULL or undefined entry to setAsKeyword. " - "invalid\n"); + printdebug( + "passing in a NULL or undefined entry to setAsKeyword. " + "invalid"); return undefined; } tn->additionalinfo->FunDecAdInfo->regularoras = as; @@ -311,13 +355,13 @@ TableNode *setAsKeyword(TableNode *tn, bool as) { // stores the type of a function (parameter type and return type) AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { if (parameter == NULL || parameter == undefined) { - printf("passed a NULL or undefined parameter to " - "CreateFunctionTypeInfo. Invalid.\n"); + printdebug("passed a NULL or undefined parameter to " + "CreateFunctionTypeInfo. Invalid."); return NULL; } if (returntype == NULL || returntype == undefined) { - printf("passed a NULL or undefined return type to " - "CreateFunctionTypeInfo. Invalid.\n"); + printdebug("passed a NULL or undefined return type to " + "CreateFunctionTypeInfo. Invalid."); return NULL; } AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); @@ -330,13 +374,13 @@ AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { // returns parameter type of a function TableNode *getParameter(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getParameter " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getParameter " + "function. Invalid."); return undefined; } if (strcmp(getType(definition), "primitive function type") != 0) { - printf( - "not checking the parameter of a function -- invalid op\n"); + printdebug( + "not checking the parameter of a function -- invalid op"); return undefined; } return definition->additionalinfo->FunTypeAdInfo->parameter; @@ -344,12 +388,13 @@ TableNode *getParameter(TableNode *definition) { // returns return type of a function TableNode *getReturn(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getReturn " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getReturn " + "function. Invalid."); return NULL; } if (strcmp(getType(definition), "primitive function type") != 0) { - printf("not checking the return of a function -- invalid op\n"); + printdebug( + "not checking the return of a function -- invalid op"); return undefined; } return definition->additionalinfo->FunTypeAdInfo->returntype; @@ -389,8 +434,8 @@ SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column) { // types SymbolTable *init(SymbolTable *start) { if (start->Parent_Scope != NULL) { - printf( - "Cannot initialize a scope that is not the parent scope\n"); + printdebug( + "Cannot initialize a scope that is not the parent scope"); return NULL; } integ = (TableNode *)calloc(1, sizeof(TableNode)); @@ -504,18 +549,19 @@ TableNode* funtypeprime; */ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { if (tn == NULL || tn == undefined) { - printf("passed in an invalid table node to modify (NULL or " - "undefined).\n"); + printdebug("passed in an invalid table node to modify (NULL or " + "undefined)."); return undefined; } if (type == NULL || type == undefined) { - printf("passed in a NULL or undefined type reference to " - "populate a table node. Invalid.\n"); + printdebug("passed in a NULL or undefined type reference to " + "populate a table node. Invalid."); return undefined; } if (info == NULL) { - printf("passed in a NULL info reference to populate a table " - "node. Invalid.\n"); + printdebug( + "passed in a NULL info reference to populate a table " + "node. Invalid."); return undefined; } tn->theType = type; @@ -526,12 +572,12 @@ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { int getAdInfoType(TableNode *tn) { if (tn == NULL || tn == undefined) { - printf("passing in NULL or undefined table entry. Invalid\n"); + printdebug("passing in NULL or undefined table entry. Invalid"); return -1; } if (tn->theType == NULL || tn->theType == undefined) { - printf("Entry being passed in has a null or undefined " - "reference for theType. Invalid.\n"); + printdebug("Entry being passed in has a null or undefined " + "reference for theType. Invalid."); return -1; } if (strcmp(getName(tn), getName(integ)) == 0) { @@ -569,20 +615,21 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, AdInfo *ad) { if (table == NULL) { - printf("Null reference to table"); + printdebug("Null reference to table"); return undefined; } /* TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); if(topDef == NULL){ - printf("This type is not defined at the top level\n"); + printdebug("This type is not defined at the top level"); return NULL; } */ if (typeOf == NULL || typeOf == undefined) { - printf("This is not pointing to a proper definition (either " - "NULL or undefined)\n"); + printdebug( + "This is not pointing to a proper definition (either " + "NULL or undefined)"); return undefined; } TableNode *newEntry = (TableNode *)calloc(1, sizeof(TableNode)); @@ -602,11 +649,11 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, char *getType(TableNode *tn) { if (tn == NULL || tn == undefined) { - printf("passed a NULL or undefined table entry to getType\n"); + printdebug("passed a NULL or undefined table entry to getType"); return getName(undefined); } if (tn->theType == NULL || tn->theType == undefined) { - printf("type of entry is currently NULL or undefined type \n"); + printdebug("type of entry is currently NULL or undefined type"); return getName(undefined); } return tn->theType->theName; @@ -614,12 +661,12 @@ char *getType(TableNode *tn) { char *getName(TableNode *tn) { if (tn == NULL || tn == undefined) { - // printf("passed a NULL or undefined table entry to - // getName\n"); + // printdebug("passed a NULL or undefined table entry to + // getName"); return undefined->theName; } if (tn->theName == NULL) { - // printf("name of entry is currently NULL, undefined \n"); + // printdebug("name of entry is currently NULL, undefined"); return undefined->theName; } return tn->theName; @@ -627,34 +674,36 @@ char *getName(TableNode *tn) { int getLine(SymbolTable *st) { if (st == NULL) { - printf("passed a NULL symbol table to getLine function. " - "Invalid.\n"); + printdebug("passed a NULL symbol table to getLine function. " + "Invalid."); return -1; } return st->Line_Number; } int getColumn(SymbolTable *st) { if (st == NULL) { - printf("passed a NULL symbol table to getColumn function. " - "Invalid.\n"); + printdebug("passed a NULL symbol table to getColumn function. " + "Invalid."); return -1; } return st->Column_Number; } TableNode *addName(TableNode *tn, char *str) { if (tn == NULL || tn == undefined) { - printf("passed a Null or undefined table node to the addName " - "function. Invalid./n"); + printdebug( + "passed a Null or undefined table node to the addName " + "function. Invalid."); return undefined; } if (tn->theName != NULL) { - printf("Name doesn't look like it is empty before you change. " - "Are you sure you need to update name?/n"); + printdebug( + "Name doesn't look like it is empty before you change. " + "Are you sure you need to update name?"); return undefined; } if (str == NULL) { - printf( - "passed a NULL string to the addName function. Invalid./n"); + printdebug( + "passed a NULL string to the addName function. Invalid."); return undefined; } tn->theName = str; @@ -663,8 +712,8 @@ TableNode *addName(TableNode *tn, char *str) { SymbolTable *setLineNumber(SymbolTable *st, int line) { if (st == NULL) { - printf("passed a Null Symbol Table to the setLineNumber " - "function. Invalid./n"); + printdebug("passed a Null Symbol Table to the setLineNumber " + "function. Invalid."); return st; } st->Line_Number = line; @@ -673,8 +722,8 @@ SymbolTable *setLineNumber(SymbolTable *st, int line) { SymbolTable *setColumnNumber(SymbolTable *st, int column) { if (st == NULL) { - printf("passed a Null Symbol Table to the setColumnNumber " - "function. Invalid./n"); + printdebug("passed a Null Symbol Table to the setColumnNumber " + "function. Invalid."); return st; } st->Line_Number = column; @@ -684,7 +733,7 @@ SymbolTable *setColumnNumber(SymbolTable *st, int column) { //we use false for type defs and true for functions for parameter of typeOf TableNode* Define(SymbolTable* table, bool typeOf, char* id) { if(table ==NULL || table->Parent_Scope != NULL){ - printf("No valid table given for header defs\n"); + printdebug("No valid table given for header defs"); return NULL; } @@ -699,8 +748,8 @@ if (typeOf == 1){ newEntry->theType = funy; } if(table_lookup(table,id) != NULL){ - printf("already defined at the top level, can't define duplicate -names\n"); return NULL; + printdebug("already defined at the top level, can't define duplicate +names"); return NULL; } newEntry->theName = id; if (table->entries == NULL) { @@ -718,7 +767,7 @@ names\n"); return NULL; // only check table that is given TableNode *table_lookup(SymbolTable *table, char *x) { if (table == NULL) { - printf("passed in empty scope. error.\n"); + printdebug("passed in empty scope. error."); return undefined; } TableNode *entrie = table->entries; @@ -732,16 +781,17 @@ TableNode *table_lookup(SymbolTable *table, char *x) { // check current table and all parents TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { - printf("passed in empty scope. error.\n"); + printdebug("passed in empty scope. error."); return undefined; } TableNode *ret = table_lookup(table, x); if (ret != NULL && ret != undefined) { return ret; } - printf("could not find %s in scope that started at line %d and column " - "%d so moving up a scope\n", - x, getLine(table), getColumn(table)); + printdebug( + "could not find %s in scope that started at line %d and column " + "%d so moving up a scope", + x, getLine(table), getColumn(table)); return look_up(table->Parent_Scope, x); } /* @@ -958,7 +1008,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { // get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { if (table == NULL) { - printf("passing a NULL reference to getAncestor. Invalid.\n"); + printdebug("passing a NULL reference to getAncestor. Invalid."); return NULL; } if (table->Parent_Scope == NULL) { @@ -1005,11 +1055,11 @@ bool typeCheck(char *firstID, char *secondID) { TableNode *entry1 = look_up(cur, firstID); TableNode *entry2 = look_up(cur, secondID); if (entry1 == NULL || entry1 == undefined) { - printf("first type not defined\n"); + printdebug("first type not defined"); return false; } if (entry2 == NULL || entry2 == undefined) { - printf("second type not defined\n"); + printdebug("second type not defined"); return false; } if (table_lookup(getAncestor(cur), getType(look_up(cur, firstID))) == @@ -1052,36 +1102,11 @@ TableNode *getNextEntry(TableNode *tn) { return tn->next; } char* String = "STRING"; char* X = "X"; SymbolTable* Second = CreateScope(NULL, 2,2); - printf("Line number is %d, Column number of scope is - %d\n",Second->Line_Number,Second->Column_Number); TableNode* First_Entry = + printdebug("Line number is %d, Column number of scope is + %d",Second->Line_Number,Second->Column_Number); TableNode* First_Entry = CreateEntry(Second,String,X); - printf("The type of the first entry is %s\n",First_Entry->theType); + printdebug("The type of the first entry is %s",First_Entry->theType); return 0; } - */ - -char *getLineStr(); -char *COLOR_RED = "\033[0;31m"; -char *COLOR_GREEN = "\033[0;32m"; -char *COLOR_ORANGE = "\033[0;33m"; -char *COLOR_BLUE = "\033[0;34m"; -char *COLOR_PURPLE = "\033[0;35m"; -char *COLOR_CYAN = "\033[0;36m"; -char *COLOR_LIGHTGRAY = "\033[0;37m"; -char *COLOR_DARKGRAY = "\033[1;30m"; -char *COLOR_LIGHTRED = "\033[1;31m"; -char *COLOR_LIGHTGREEN = "\033[1;32m"; -char *COLOR_YELLOW = "\033[1;33m"; -char *COLOR_LIGHTBLUE = "\033[1;34m"; -char *COLOR_LIGHTPURPLE = "\033[1;35m"; -char *COLOR_LIGHTCYAN = "\033[1;36m"; -char *COLOR_WHITE = "\033[1;37m"; - -bool DEBUG = false; - -char *getLineStr(int d) { - char *new_text = malloc(100); - sprintf(new_text, "%s[%d]%s ", COLOR_DARKGRAY, d, COLOR_WHITE); - return new_text; -} \ No newline at end of file + */ \ No newline at end of file From 0593673d89c0419be1e2843d4ee3e17c6fb39c08 Mon Sep 17 00:00:00 2001 From: Partho Date: Mon, 31 Mar 2025 12:32:36 -0400 Subject: [PATCH 20/38] fixed the NULL checks for the incorrect ORs --- src/grammar.y | 2 +- src/symbol_table.c | 237 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 183 insertions(+), 56 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 6421c42..b44f502 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -124,7 +124,7 @@ definition: TYPE ID COLON { printdebug("Currently see a record definition for %s", $2); tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); - if (table_lookup(getAncestor(cur), $2) == NULL) { + if (table_lookup(getAncestor(cur), $2) == undefined) { printdebug("rec not found "); } }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); diff --git a/src/symbol_table.c b/src/symbol_table.c index 4531f1d..e1efdfb 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -37,7 +37,7 @@ char *COLOR_LIGHTPURPLE = "\033[1;35m"; char *COLOR_LIGHTCYAN = "\033[1;36m"; char *COLOR_WHITE = "\033[1;37m"; -bool DEBUG = true; +bool DEBUG = false; void printdebug_impl(char *file, int line, const char *format, ...); @@ -142,11 +142,16 @@ AdInfo *CreatePrimitiveInfo(int size) { // only gets the size of a primitive type int getPrimSize(TableNode *definition) { - if (definition == NULL || definition == undefined) { + if (definition == NULL) { printdebug( "passed an NULL entry to getPrimSize function. Invalid."); return -1; } + if (definition == undefined) { + printdebug( + "passed an undefined entry to getPrimSize function. Invalid."); + return -1; + } if (definition->additionalinfo == NULL) { printdebug("node has NULL additionalinfo. Invalid."); return -1; @@ -172,8 +177,18 @@ int getPrimSize(TableNode *definition) { // type stored in the array per professor, the actual size of the array is // calculated at runtime so bounds checking only needs to be done then AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { - if (type == NULL || type == undefined) { - printdebug("passed a NULL or undefined type reference to " + if (type == NULL) { + printdebug("passed a NULL reference to " + "CreateArrayInfo. Invalid."); + return NULL; + } + if (type == undefined) { + printdebug("passed an undefined reference to " + "CreateArrayInfo. Invalid."); + return NULL; + } + if (type == undefined) { + printdebug("passed a undefined type reference to " "CreateArrayInfo. Invalid."); return NULL; } @@ -187,8 +202,13 @@ AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { } // This gets the number of dimensions from array info int getNumArrDim(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getNumArrDim " + if (definition == NULL) { + printdebug("passed an NULL entry to getNumArrDim " + "function. Invalid."); + return -1; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getNumArrDim " "function. Invalid."); return -1; } @@ -201,8 +221,13 @@ int getNumArrDim(TableNode *definition) { // This gets the type stored in an array from arrtype. It returns a reference to // the entry of that type TableNode *getArrType(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getArrType " + if (definition == NULL) { + printdebug("passed an NULL entry to getArrType " + "function. Invalid."); + return NULL; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getArrType " "function. Invalid."); return NULL; } @@ -229,8 +254,13 @@ AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope) { // Perhaps this may not be needed since we need to iterate over all elements // anyways. int getRecLength(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getRecLength " + if (definition == NULL) { + printdebug("passed an NULL entry to getRecLength " + "function. Invalid."); + return -1; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getRecLength " "function. Invalid."); return -1; } @@ -243,8 +273,13 @@ int getRecLength(TableNode *definition) { } // This gets the array. Needs to up be updated to get the scope instead SymbolTable *getRecList(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getRecList " + if (definition == NULL) { + printdebug("passed a NULL entry to getRecList " + "function. Invalid."); + return NULL; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getRecList " "function. Invalid."); return NULL; } @@ -258,10 +293,14 @@ SymbolTable *getRecList(TableNode *definition) { } TableNode *setRecSize(TableNode *tn, int n) { - if (tn == NULL || tn == undefined) { + if (tn == NULL) { printdebug("passed in NULL entry for setRecSize. Invalid"); return undefined; } + if (tn == undefined) { + printdebug("passed in undefined entry for setRecSize. Invalid"); + return undefined; + } tn->additionalinfo->RecAdInfo->numofelements = n; return tn; } @@ -300,8 +339,13 @@ AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { // gets the line at which the function was first defined. (Can be used to print // out in table if needed) int getStartLine(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getStartLine " + if (definition == NULL) { + printdebug("passed a NULL entry to getStartLine " + "function. Invalid."); + return -1; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getStartLine " "function. Invalid."); return -1; } @@ -315,9 +359,15 @@ int getStartLine(TableNode *definition) { } TableNode *setStartLine(TableNode *tn, int start) { - if (tn == NULL || tn == undefined) { + if (tn == NULL) { printdebug( - "passing in a NULL or undefined entry to setStartLine. " + "passing in a NULL entry to setStartLine. " + "invalid"); + return undefined; + } + if (tn == undefined) { + printdebug( + "passing in an undefined entry to setStartLine. " "invalid"); return undefined; } @@ -327,8 +377,13 @@ TableNode *setStartLine(TableNode *tn, int start) { // checks if "as" keyword was used for function definition. Either 0 or 1 for // not used or used. bool getAsKeyword(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getAsKeyword " + if (definition == NULL) { + printdebug("passed a NULL entry to getAsKeyword " + "function. Invalid."); + return false; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getAsKeyword " "function. Invalid."); return false; } @@ -342,9 +397,15 @@ bool getAsKeyword(TableNode *definition) { } TableNode *setAsKeyword(TableNode *tn, bool as) { - if (tn == NULL || tn == undefined) { + if (tn == NULL) { printdebug( - "passing in a NULL or undefined entry to setAsKeyword. " + "passing in a NULL entry to setAsKeyword. " + "invalid"); + return undefined; + } + if (tn == undefined) { + printdebug( + "passing in an undefined entry to setAsKeyword. " "invalid"); return undefined; } @@ -354,13 +415,23 @@ TableNode *setAsKeyword(TableNode *tn, bool as) { // stores the type of a function (parameter type and return type) AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { - if (parameter == NULL || parameter == undefined) { - printdebug("passed a NULL or undefined parameter to " + if (parameter == NULL) { + printdebug("passed a NULL parameter to " "CreateFunctionTypeInfo. Invalid."); return NULL; } - if (returntype == NULL || returntype == undefined) { - printdebug("passed a NULL or undefined return type to " + if (parameter == undefined) { + printdebug("passed an undefined parameter to " + "CreateFunctionTypeInfo. Invalid."); + return NULL; + } + if (returntype == NULL) { + printdebug("passed a NULL return type to " + "CreateFunctionTypeInfo. Invalid."); + return NULL; + } + if (returntype == undefined) { + printdebug("passed an undefined return type to " "CreateFunctionTypeInfo. Invalid."); return NULL; } @@ -373,8 +444,13 @@ AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { } // returns parameter type of a function TableNode *getParameter(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getParameter " + if (definition == NULL) { + printdebug("passed a NULL entry to getParameter " + "function. Invalid."); + return undefined; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getParameter " "function. Invalid."); return undefined; } @@ -387,8 +463,13 @@ TableNode *getParameter(TableNode *definition) { } // returns return type of a function TableNode *getReturn(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getReturn " + if (definition == NULL) { + printdebug("passed a NULL entry to getReturn " + "function. Invalid."); + return NULL; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getReturn " "function. Invalid."); return NULL; } @@ -548,13 +629,21 @@ TableNode* recprime; TableNode* funtypeprime; */ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { - if (tn == NULL || tn == undefined) { - printdebug("passed in an invalid table node to modify (NULL or " - "undefined)."); + if (tn == NULL) { + printdebug("passed in an NULL table node to populateTypeAndInfo."); return undefined; } - if (type == NULL || type == undefined) { - printdebug("passed in a NULL or undefined type reference to " + if (tn == undefined) { + printdebug("passed in an undefined table node to populateTypeAndInfo"); + return undefined; + } + if (type == NULL) { + printdebug("passed in a NULL type reference to " + "populate a table node. Invalid."); + return undefined; + } + if (type == undefined) { + printdebug("passed in an undefined type reference to " "populate a table node. Invalid."); return undefined; } @@ -571,13 +660,22 @@ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { } int getAdInfoType(TableNode *tn) { - if (tn == NULL || tn == undefined) { - printdebug("passing in NULL or undefined table entry. Invalid"); + if (tn == NULL) { + printdebug("passing in NULL table entry to getAdInfoType. Invalid"); return -1; } - if (tn->theType == NULL || tn->theType == undefined) { - printdebug("Entry being passed in has a null or undefined " - "reference for theType. Invalid."); + if (tn == undefined) { + printdebug("passing in undefined table entry to getAdInfoType. Invalid"); + return -1; + } + if (tn->theType == NULL) { + printdebug("Entry being passed in has a null" + "reference for theType to getAdInfoType. Invalid."); + return -1; + } + if (tn->theType == undefined) { + printdebug("Entry being passed in an undefined " + "reference for theType to getAdInfoType. Invalid."); return -1; } if (strcmp(getName(tn), getName(integ)) == 0) { @@ -626,10 +724,14 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, return NULL; } */ - if (typeOf == NULL || typeOf == undefined) { + if (typeOf == NULL) { printdebug( - "This is not pointing to a proper definition (either " - "NULL or undefined)"); + "Passing an NULL Type Node to Create Entry"); + return undefined; + } + if (typeOf == undefined) { + printdebug( + "Passing an undefined Type Node to Create Entry"); return undefined; } TableNode *newEntry = (TableNode *)calloc(1, sizeof(TableNode)); @@ -648,21 +750,32 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, } char *getType(TableNode *tn) { - if (tn == NULL || tn == undefined) { - printdebug("passed a NULL or undefined table entry to getType"); + if (tn == NULL) { + printdebug("passed a NULL table entry to getType"); return getName(undefined); } - if (tn->theType == NULL || tn->theType == undefined) { - printdebug("type of entry is currently NULL or undefined type"); + if (tn == undefined) { + printdebug("passed an undefined table entry to getType"); + return getName(undefined); + } + if (tn->theType == NULL) { + printdebug("type of entry is currently NULL type"); + return getName(undefined); + } + if (tn->theType == undefined) { + printdebug("type of entry is currently undefined type"); return getName(undefined); } return tn->theType->theName; } char *getName(TableNode *tn) { - if (tn == NULL || tn == undefined) { - // printdebug("passed a NULL or undefined table entry to - // getName"); + if (tn == NULL) { + printdebug("passed a NULL table entry to getName"); + return undefined->theName; + } + if (tn == undefined) { + printdebug("passed an undefined table entry to getName"); return undefined->theName; } if (tn->theName == NULL) { @@ -689,9 +802,15 @@ int getColumn(SymbolTable *st) { return st->Column_Number; } TableNode *addName(TableNode *tn, char *str) { - if (tn == NULL || tn == undefined) { + if (tn == NULL) { printdebug( - "passed a Null or undefined table node to the addName " + "passed a Null table node to the addName " + "function. Invalid."); + return undefined; + } + if (tn == undefined) { + printdebug( + "passed an undefined table node to the addName " "function. Invalid."); return undefined; } @@ -1054,12 +1173,20 @@ bool typeCheck(char *firstID, char *secondID) { TableNode *entry1 = look_up(cur, firstID); TableNode *entry2 = look_up(cur, secondID); - if (entry1 == NULL || entry1 == undefined) { - printdebug("first type not defined"); + if (entry1 == NULL) { + printdebug("first type is NULL in type check. Invalid."); return false; } - if (entry2 == NULL || entry2 == undefined) { - printdebug("second type not defined"); + if (entry1 == undefined) { + printdebug("first type is undefined in type check. Invalid."); + return false; + } + if (entry2 == NULL) { + printdebug("second type is NULL in type check. Invalid."); + return false; + } + if (entry2 == undefined) { + printdebug("second type is undefined in type check. Invalid."); return false; } if (table_lookup(getAncestor(cur), getType(look_up(cur, firstID))) == From 188c7344655ea4d9495004e9eb848a1e8e6eaca6 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 31 Mar 2025 17:38:37 -0400 Subject: [PATCH 21/38] small changes, segfault issue found --- src/grammar.y | 4 +-- src/symbol_table.c | 63 ++++++++++++++++++++++++---------------------- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index b44f502..94fd0a9 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -121,7 +121,7 @@ prototype: L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; definition: -TYPE ID COLON { + TYPE ID COLON { printdebug("Currently see a record definition for %s", $2); tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); if (table_lookup(getAncestor(cur), $2) == undefined) { @@ -238,7 +238,7 @@ declaration: ; id_or_types: - ID {printdebug("string of id is %s in ID pattern of id_or_type rule."); $$ = $1;} + ID {printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = $1;} //{printdebug("string of id is %s in ID pattern of id_or_type rule. Type passed up the tree is %s.",$1,getType(look_up(cur,$1))); $$ = getType(look_up(cur,$1));} | types {printdebug("string of type is %s in types pattern of id_or_type rule.",$1);} {$$ = $1;} //{printdebug("string of type is %s in types pattern of id_or_type rule. That is passed up the tree.",$1);} {$$ = $1;} diff --git a/src/symbol_table.c b/src/symbol_table.c index e1efdfb..6421002 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -148,8 +148,8 @@ int getPrimSize(TableNode *definition) { return -1; } if (definition == undefined) { - printdebug( - "passed an undefined entry to getPrimSize function. Invalid."); + printdebug("passed an undefined entry to getPrimSize function. " + "Invalid."); return -1; } if (definition->additionalinfo == NULL) { @@ -360,15 +360,13 @@ int getStartLine(TableNode *definition) { TableNode *setStartLine(TableNode *tn, int start) { if (tn == NULL) { - printdebug( - "passing in a NULL entry to setStartLine. " - "invalid"); + printdebug("passing in a NULL entry to setStartLine. " + "invalid"); return undefined; } if (tn == undefined) { - printdebug( - "passing in an undefined entry to setStartLine. " - "invalid"); + printdebug("passing in an undefined entry to setStartLine. " + "invalid"); return undefined; } tn->additionalinfo->FunDecAdInfo->startlinenumber = start; @@ -398,15 +396,13 @@ bool getAsKeyword(TableNode *definition) { TableNode *setAsKeyword(TableNode *tn, bool as) { if (tn == NULL) { - printdebug( - "passing in a NULL entry to setAsKeyword. " - "invalid"); + printdebug("passing in a NULL entry to setAsKeyword. " + "invalid"); return undefined; } if (tn == undefined) { - printdebug( - "passing in an undefined entry to setAsKeyword. " - "invalid"); + printdebug("passing in an undefined entry to setAsKeyword. " + "invalid"); return undefined; } tn->additionalinfo->FunDecAdInfo->regularoras = as; @@ -630,11 +626,13 @@ TableNode* funtypeprime; */ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { if (tn == NULL) { - printdebug("passed in an NULL table node to populateTypeAndInfo."); + printdebug( + "passed in an NULL table node to populateTypeAndInfo."); return undefined; } if (tn == undefined) { - printdebug("passed in an undefined table node to populateTypeAndInfo"); + printdebug( + "passed in an undefined table node to populateTypeAndInfo"); return undefined; } if (type == NULL) { @@ -661,11 +659,13 @@ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { int getAdInfoType(TableNode *tn) { if (tn == NULL) { - printdebug("passing in NULL table entry to getAdInfoType. Invalid"); + printdebug( + "passing in NULL table entry to getAdInfoType. Invalid"); return -1; } if (tn == undefined) { - printdebug("passing in undefined table entry to getAdInfoType. Invalid"); + printdebug("passing in undefined table entry to getAdInfoType. " + "Invalid"); return -1; } if (tn->theType == NULL) { @@ -725,26 +725,27 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, } */ if (typeOf == NULL) { - printdebug( - "Passing an NULL Type Node to Create Entry"); + printdebug("Passing an NULL Type Node to Create Entry"); return undefined; } if (typeOf == undefined) { - printdebug( - "Passing an undefined Type Node to Create Entry"); + printdebug("Passing an undefined Type Node to Create Entry"); return undefined; } + TableNode *newEntry = (TableNode *)calloc(1, sizeof(TableNode)); newEntry->theType = typeOf /*topDef*/; newEntry->theName = id; newEntry->additionalinfo = ad; if (table->entries == NULL) { table->entries = newEntry; + printdebug("[CreateEntry] Adding %s to the symbol table", id); return newEntry; } else { TableNode *oldEntry = table->entries; table->entries = newEntry; newEntry->next = oldEntry; + printdebug("[CreateEntry] Adding %s to the symbol table", id); return newEntry; } } @@ -779,7 +780,7 @@ char *getName(TableNode *tn) { return undefined->theName; } if (tn->theName == NULL) { - // printdebug("name of entry is currently NULL, undefined"); + printdebug("name of entry is currently NULL, undefined"); return undefined->theName; } return tn->theName; @@ -803,15 +804,13 @@ int getColumn(SymbolTable *st) { } TableNode *addName(TableNode *tn, char *str) { if (tn == NULL) { - printdebug( - "passed a Null table node to the addName " - "function. Invalid."); + printdebug("passed a Null table node to the addName " + "function. Invalid."); return undefined; } if (tn == undefined) { - printdebug( - "passed an undefined table node to the addName " - "function. Invalid."); + printdebug("passed an undefined table node to the addName " + "function. Invalid."); return undefined; } if (tn->theName != NULL) { @@ -1220,7 +1219,11 @@ ListOfTable *getChildren(SymbolTable *st) { return st->Children_Scope; } SymbolTable *getFirstChild(ListOfTable *lt) { return lt->table; } ListOfTable *getRestOfChildren(ListOfTable *lt) { return lt->next; } TableNode *getFirstEntry(SymbolTable *st) { return st->entries; } -TableNode *getNextEntry(TableNode *tn) { return tn->next; } + +// Segfaults when passed an invalid table node! +TableNode *getNextEntry(TableNode *tn) { return tn; } + + // uncomment the below main function along with the headers above for a simple // standalone test of table and entry creation From c61a87634c452ae09aef3a1b68b50f404cdab3ed Mon Sep 17 00:00:00 2001 From: Partho Date: Mon, 31 Mar 2025 20:31:53 -0400 Subject: [PATCH 22/38] fixed NULL check from getNextEntry --- src/symbol_table.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 6421002..a4cee49 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1221,7 +1221,17 @@ ListOfTable *getRestOfChildren(ListOfTable *lt) { return lt->next; } TableNode *getFirstEntry(SymbolTable *st) { return st->entries; } // Segfaults when passed an invalid table node! -TableNode *getNextEntry(TableNode *tn) { return tn; } +TableNode *getNextEntry(TableNode *tn) { + if (tn == NULL) { + printdebug("passed a NULL table node to getNextEntry"); + return undefined; + } + if (tn == undefined) { + printdebug("passed an undefined table node to getNextEntry"); + return undefined; + } + return tn->next; + } // uncomment the below main function along with the headers above for a simple From 5e01b93af835f7a20d345419d6b57cf415f5418a Mon Sep 17 00:00:00 2001 From: Partho Date: Mon, 31 Mar 2025 20:42:17 -0400 Subject: [PATCH 23/38] edited while loops in grammar to not look for comparison to NULL. Undefined instead --- src/grammar.y | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 94fd0a9..352c2ea 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -196,7 +196,7 @@ function_declaration: idlist: ID { TableNode *entry = getFirstEntry(cur); - while (getName(entry) != NULL) { + while (strcmp(getName(entry),"undefined") != 0) { entry = getNextEntry(entry); } if (getNextEntry(entry) == NULL) { @@ -207,7 +207,7 @@ idlist: | ID { TableNode *entry = getFirstEntry(cur); - while (getName(entry) != NULL) { + while (strcmp(getName(entry),"undefined") != 0) { entry = getNextEntry(entry); } if (getNextEntry(entry) != NULL) { From fac92f62f731f7fa5a4f10d5dcfd384be1c4fb64 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 31 Mar 2025 21:18:21 -0400 Subject: [PATCH 24/38] segfaults fixed. need to verify what is being passed to functions. --- src/symbol_table.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index a4cee49..e68c886 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -968,10 +968,24 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { }*/ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { + if (table == NULL) { + printdebug( + "%s[FATAL] passed in NULL table to print_symbol_table", + COLOR_RED); + return; + } + + if (table->Parent_Scope != NULL) { + printdebug("%s[WARNING] passed in a non-top level scope to " + "print_symbol_table", + COLOR_ORANGE); + } + if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); } + TableNode *entrie = table->entries; fprintf(file_ptr, "-----------------:--------:--------:----------------" "------:---------" @@ -1213,7 +1227,19 @@ bool typeCheck(char *firstID, char *secondID) { return false; } -SymbolTable *getParent(SymbolTable *st) { return st->Parent_Scope; } +SymbolTable *getParent(SymbolTable *st) { + if (st == NULL) { + printdebug("passed a NULL symbol table to getParent function. " + "Invalid."); + return NULL; + } + if (st->Parent_Scope == NULL) { + printdebug("passed a top level scope to getParent function. " + "Invalid."); + return NULL; + } + return st->Parent_Scope; +} ListOfTable *getChildren(SymbolTable *st) { return st->Children_Scope; } SymbolTable *getFirstChild(ListOfTable *lt) { return lt->table; } @@ -1222,17 +1248,16 @@ TableNode *getFirstEntry(SymbolTable *st) { return st->entries; } // Segfaults when passed an invalid table node! TableNode *getNextEntry(TableNode *tn) { - if (tn == NULL) { + if (tn == NULL) { printdebug("passed a NULL table node to getNextEntry"); return undefined; - } - if (tn == undefined) { + } + if (tn == undefined) { printdebug("passed an undefined table node to getNextEntry"); return undefined; - } - return tn->next; } - + return tn->next; +} // uncomment the below main function along with the headers above for a simple // standalone test of table and entry creation From 5bd68ddb85bb114106865876cad69d3c04a502ee Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 1 Apr 2025 17:02:24 -0400 Subject: [PATCH 25/38] verifying grammar --- src/grammar.y | 61 +++++++++++++++++----------- src/runner.c | 9 ---- src/runner.h | 2 - src/symbol_table.c | 15 +++++-- tests/sprint2/test/sp2_library.alpha | 8 ++-- 5 files changed, 52 insertions(+), 43 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 352c2ea..4b36a61 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -267,16 +267,30 @@ simple_statement: | RETURN expression ; -assignable: - ID {$$ = getType(look_up(cur,$1));} - | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} //add array case here - | assignable rec_op ID {if(undefined != table_lookup(getRecList(look_up(cur, $1)), $3)){ - {$$ = getName(table_lookup(getRecList(look_up(cur, $1)), $3));}};} - ; - rec_op : DOT + + + +/////////// VERIFIED UP UNTIL THIS POINT + +// assignable needs more code- specifically for arrays, records and ablock checks + + + + + +ablock: + L_PAREN argument_list {$$ = $2;} R_PAREN + ; + +argument_list: + expression COMMA argument_list {$$ = $3 + 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} + | expression {$$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} + ; + +// will ALWAYS be a TYPE expression: constant {printdebug("constant expression");} {$$ = $1;} @@ -341,8 +355,8 @@ expression: | expression EQUAL_TO expression {printdebug("equals check expression"); if(strcmp($1,$3)==0){$$=strdup("Boolean");} - else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| - strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} + //else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| + // strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} @@ -353,17 +367,16 @@ expression: | memOp assignable {$$ = strdup("address");} ; - -ablock: -L_PAREN argument_list {$$ = $2;} R_PAREN +// prolly right, check back with me later +// add array case +// include type check for ablock in arrays - ablock is always the int of the elements in array/rec +assignable: + ID {$$ = getType(look_up(cur,$1)); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} + | assignable ablock {$$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1);} // add array case + | assignable rec_op ID {if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)){ + {$$ = getName(table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3));}}; printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1);} ; -argument_list: -expression COMMA argument_list {$$ = $3 + 1;} -| expression {$$ = 1;} - ; - - memOp: RESERVE {printdebug("reserve expression");} | RELEASE {printdebug("release expression");} @@ -371,12 +384,12 @@ memOp: constant: - C_STRING {$$ = $1;} - | C_INTEGER {$$ = "integer";} - | C_NULL {$$ = $1;} - | C_CHARACTER {$$ = $1;} - | C_TRUE {$$ = $1;} - | C_FALSE {$$ = $1;} + C_STRING {$$ = $1; printdebug("string of C_STRING in constant is %s",$1);} + | C_INTEGER {$$ = "integer"; printdebug("string of C_INTEGER in constant is integer");} + | C_NULL {$$ = $1; printdebug("string of C_NULL in constant is %s",$1);} + | C_CHARACTER {$$ = $1; printdebug("string of C_CHARACTER in constant is %s",$1);} + | C_TRUE {$$ = $1; printdebug("string of C_TRUE in constant is %s",$1);} + | C_FALSE {$$ = $1; printdebug("string of C_FALSE in constant is %s",$1);} ; types: diff --git a/src/runner.c b/src/runner.c index 7c053a4..c6f94a3 100644 --- a/src/runner.c +++ b/src/runner.c @@ -223,13 +223,4 @@ int is_alpha_file(char *alpha, int file_len) { return -1; // not alpha file } return 0; // is alpha file -} - -void enter_scope(int line, int column) { cur = CreateScope(cur, line, column); } -void exit_scope() { - if (cur->Parent_Scope == NULL) { - printf("Can't close top"); - return; - } - cur = cur->Parent_Scope; } \ No newline at end of file diff --git a/src/runner.h b/src/runner.h index d378be5..9678609 100644 --- a/src/runner.h +++ b/src/runner.h @@ -40,8 +40,6 @@ SymbolTable *cur; // int main(int argc, char* argv[]); char *is_tok(int argc, char *argv[]); // int is_alpha_file(char *file, int file_len); -void enter_scope(int, int); -void exit_scope(void); FILE *alpha_file; FILE *tok_flag = NULL; diff --git a/src/symbol_table.c b/src/symbol_table.c index e68c886..29d34a1 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -512,7 +512,7 @@ SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column) { SymbolTable *init(SymbolTable *start) { if (start->Parent_Scope != NULL) { printdebug( - "Cannot initialize a scope that is not the parent scope"); + "%s[FATAL] Cannot initialize a scope that is not the parent scope", COLOR_RED); return NULL; } integ = (TableNode *)calloc(1, sizeof(TableNode)); @@ -979,6 +979,9 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { printdebug("%s[WARNING] passed in a non-top level scope to " "print_symbol_table", COLOR_ORANGE); + printdebug("%sParent of's: line %d, column %d", + COLOR_ORANGE, table->Parent_Scope->Line_Number, table->Parent_Scope->Column_Number); + return; } if (table->Parent_Scope == NULL) { @@ -1100,13 +1103,13 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf(file_ptr, "%-17s: %06d : :%-21s: %-28s\n", entrie->theName, current_scope, - getType(entrie), "Function"); + getType(entrie), "User Defined"); } else { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", entrie->theName, current_scope, parant_scope, getType(entrie), - "Function"); + "User Defined"); } } if (getAdInfoType(entrie) == TYPE_UNDEFINED) { @@ -1145,6 +1148,12 @@ SymbolTable *getAncestor(SymbolTable *table) { } if (table->Parent_Scope == NULL) { // if table has no parent, return itself + printdebug("already at top scope!"); + if (table == cur) { + printdebug("passed in the current scope"); + } else { + printdebug("passed in a different scope"); + } return table; } else { // call function recursively to grab ancestor diff --git a/tests/sprint2/test/sp2_library.alpha b/tests/sprint2/test/sp2_library.alpha index 9bacd6c..866857c 100644 --- a/tests/sprint2/test/sp2_library.alpha +++ b/tests/sprint2/test/sp2_library.alpha @@ -7,9 +7,9 @@ You should #include this file at the start of your alpha file. Some useful types are defined below. *) type string: 1 -> character -type BooleanXBoolean: [Boolean: x, y] -type characterXcharacter: [character: x, y] -type integerXinteger: [integer: x, y] +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] type Boolean2Boolean: Boolean -> Boolean type integer2integer: integer -> integer @@ -25,6 +25,4 @@ type address2integer: address -> integer external function printInteger: integer2integer external function printCharacter: character2integer external function printBoolean: Boolean2integer -external function reserve: integer2address -external function release: address2integer function entry: string2integer From d56d836b8bdb577929df8ae6ba8880a0470c41c3 Mon Sep 17 00:00:00 2001 From: Annie Date: Tue, 1 Apr 2025 21:08:16 -0400 Subject: [PATCH 26/38] checking number of args in array ablock --- src/grammar.y | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 4b36a61..8eff344 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -282,7 +282,7 @@ rec_op : ablock: - L_PAREN argument_list {$$ = $2;} R_PAREN +L_PAREN argument_list R_PAREN {$$ = $2; printdebug("ablock is %d", $$);} ; argument_list: @@ -372,7 +372,19 @@ expression: // include type check for ablock in arrays - ablock is always the int of the elements in array/rec assignable: ID {$$ = getType(look_up(cur,$1)); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} - | assignable ablock {$$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1);} // add array case + | assignable ablock { + int type = getAdInfoType(look_up(cur, $1)); + if (type == TYPE_FUNCTION_TYPE) { + $$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); + } else if (type == TYPE_ARRAY) { + if (getNumArrDim(look_up(cur, $1)) != $2) { + printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $2, @2.first_line, @2.first_column); + } + $$ = $1; + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); + } + } | assignable rec_op ID {if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)){ {$$ = getName(table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3));}}; printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1);} ; From db2268284bd59a838a7003825d142bc5332a94c8 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Wed, 2 Apr 2025 11:05:45 -0400 Subject: [PATCH 27/38] more debug messages, new type check for array and rec --- src/grammar.y | 17 +++++++++++++---- src/symbol_table.c | 9 --------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 8eff344..e4185c8 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -259,10 +259,19 @@ compound_statement: ; simple_statement: - assignable ASSIGN expression {if(strcmp($1, $3) == 0){ - } else { - printdebug("Mismatch at line %d and column%d", @2.first_line, @2.first_column); - }} + assignable ASSIGN expression + { + if(strcmp($1, $3) == 0) { + printdebug("Passed standard type check; assignable = expression"); + } else if((strcmp($1, "rec") == 0) && (strcmp($3, "address") == 0)) { + printdebug("Passed rec type check; rec = address"); + } else if((strcmp($1, "array") == 0) && (strcmp($3, "address") == 0)) { + printdebug("Passed array type check; array = address"); + } else { + printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); + printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, $1, $3, COLOR_WHITE); + } + } | RETURN expression ; diff --git a/src/symbol_table.c b/src/symbol_table.c index 29d34a1..6551c1d 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -975,15 +975,6 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { return; } - if (table->Parent_Scope != NULL) { - printdebug("%s[WARNING] passed in a non-top level scope to " - "print_symbol_table", - COLOR_ORANGE); - printdebug("%sParent of's: line %d, column %d", - COLOR_ORANGE, table->Parent_Scope->Line_Number, table->Parent_Scope->Column_Number); - return; - } - if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); From a81e3e410f0cf770f99d23ae85fdd488cf2103dd Mon Sep 17 00:00:00 2001 From: Annie Date: Wed, 2 Apr 2025 11:15:53 -0400 Subject: [PATCH 28/38] need to test function call and array type checking --- src/grammar.y | 95 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 30 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index e4185c8..ba66d6b 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -141,7 +141,7 @@ definition: } | ID { TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == NULL) { + if (node == undefined) { printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); @@ -158,25 +158,26 @@ definition: }R_PAREN ASSIGN sblock | ID { TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == NULL) { + if (node == undefined) { printdebug("null check"); } - if (node == NULL) { + if (node == undefined) { printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); } else { setStartLine(node, @1.first_line); - setAsKeyword(node, false); + setAsKeyword(node, true); } cur = CreateScope(cur, 0, 0); }AS L_PAREN { TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); - if (parameter == NULL) { - printdebug("function defined with as, but parameter is not a record at line %d, column %d", @1.first_line, @1.first_column); + if (parameter == undefined) { + printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(parameter) != TYPE_RECORD){ - printdebug("function defined with as, but parameter is not a record at line %d, column %d", @1.first_line, @1.first_column); + printdebug("record: %s., primitive: %s.", getName(parameter), getName(recprime)); + printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); }else { for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ CreateEntry(cur, entry, NULL, NULL); @@ -187,6 +188,7 @@ definition: ; + function_declaration: FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} | EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);} @@ -203,7 +205,7 @@ idlist: printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); } addName(entry, $1); - } COMMA idlist {$$ = $3 + 1;} + } COMMA idlist {$$ = $4 + 1;} | ID { TableNode *entry = getFirstEntry(cur); @@ -259,19 +261,10 @@ compound_statement: ; simple_statement: - assignable ASSIGN expression - { - if(strcmp($1, $3) == 0) { - printdebug("Passed standard type check; assignable = expression"); - } else if((strcmp($1, "rec") == 0) && (strcmp($3, "address") == 0)) { - printdebug("Passed rec type check; rec = address"); - } else if((strcmp($1, "array") == 0) && (strcmp($3, "address") == 0)) { - printdebug("Passed array type check; array = address"); - } else { - printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); - printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, $1, $3, COLOR_WHITE); - } - } + assignable ASSIGN expression {if(strcmp($1, $3) == 0){ + } else { + printdebug("Mismatch at line %d and column%d", @2.first_line, @2.first_column); + }} | RETURN expression ; @@ -295,8 +288,13 @@ L_PAREN argument_list R_PAREN {$$ = $2; printdebug("ablock is %d", ; argument_list: - expression COMMA argument_list {$$ = $3 + 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} - | expression {$$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} + expression COMMA argument_list { + CreateEntry(cur, NULL, $1, NULL); + $$ = $3 + 1; + printdebug("[ARGUMENT_LIST] argument list is %d", $$);} + | expression { + CreateEntry(cur, NULL, $1, NULL); + $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} ; // will ALWAYS be a TYPE @@ -381,19 +379,56 @@ expression: // include type check for ablock in arrays - ablock is always the int of the elements in array/rec assignable: ID {$$ = getType(look_up(cur,$1)); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} - | assignable ablock { - int type = getAdInfoType(look_up(cur, $1)); - if (type == TYPE_FUNCTION_TYPE) { + | assignable { + cur = CreateScope(cur, -1,-1); + }ablock { + int type = getAdInfoType(look_up(getParent(cur), $1)); + if (type == TYPE_FUNCTION_DECLARATION) { + if (getAsKeyword(look_up(getParent(cur), $1))) { + TableNode *param = getParameter(look_up(getParent(cur), $1)); + SymbolTable *recList = getRecList(param); + TableNode *lastCheckedRef = getFirstEntry(recList); + TableNode *lastCheckedAct = getFirstEntry(cur); + while (getNextEntry(lastCheckedRef) != NULL) { + lastCheckedRef = getNextEntry(lastCheckedRef); + } + //this isn't very efficient, but will hopefully work + while (lastCheckedAct != NULL && lastCheckedRef != NULL) { + if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) { + printdebug("expected %s expression in function call but got %s at line %d and column %d",getName(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); + } + lastCheckedAct = getNextEntry(lastCheckedAct); + TableNode *tn = getFirstEntry(recList); + while (getNextEntry(tn) != lastCheckedRef) { + tn = getNextEntry(tn); + } + lastCheckedRef = tn; + } + + } else { + char *expected = getName(getParameter(look_up(getParent(cur), $1))); + char *actual = getName(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); + } + } + $$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); } else if (type == TYPE_ARRAY) { - if (getNumArrDim(look_up(cur, $1)) != $2) { - printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $2, @2.first_line, @2.first_column); - } + if (getNumArrDim(look_up(getParent(cur), $1)) != $2) { + printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $2, @2.first_line, @2.first_column); + } + for (TableNode *tn = getFirstEntry(cur); tn != NULL; tn = getNextEntry(tn)) { + if (strcmp(getName(tn), "integer") != 0) { + printdebug("expected only integer expressions in array ablock at line %d column %d", @3.first_line, @3.first_column); + } + } $$ = $1; printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); } - } + cur = getParent(cur); + } | assignable rec_op ID {if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)){ {$$ = getName(table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3));}}; printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1);} ; From 53a4d060b6d31ad6f11848497a6364fd4d3fd018 Mon Sep 17 00:00:00 2001 From: Annie Date: Wed, 2 Apr 2025 11:23:00 -0400 Subject: [PATCH 29/38] added back scarlett's simple statement work --- src/grammar.y | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index ba66d6b..6edd68f 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -261,14 +261,22 @@ compound_statement: ; simple_statement: - assignable ASSIGN expression {if(strcmp($1, $3) == 0){ - } else { - printdebug("Mismatch at line %d and column%d", @2.first_line, @2.first_column); - }} + assignable ASSIGN expression + { + if(strcmp($1, $3) == 0) { + printdebug("Passed standard type check; assignable = expression"); + } else if((strcmp($1, "rec") == 0) && (strcmp($3, "address") == 0)) { + printdebug("Passed rec type check; rec = address"); + } else if((strcmp($1, "array") == 0) && (strcmp($3, "address") == 0)) { + printdebug("Passed array type check; array = address"); + } else { + printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); + printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, $1, $3, COLOR_WHITE); + } + } | RETURN expression ; - rec_op : DOT From d05b6f456c45d45c6d91ee4d20e98cf2cf231269 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Wed, 2 Apr 2025 11:54:13 -0400 Subject: [PATCH 30/38] rebase --- tests/sprint2/test/sp2_carls_mistake.alpha | 2 ++ .../test/sp3_carls_second_mistake.alpha | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/sprint3/test/sp3_carls_second_mistake.alpha diff --git a/tests/sprint2/test/sp2_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha index f2b3703..75fa12f 100644 --- a/tests/sprint2/test/sp2_carls_mistake.alpha +++ b/tests/sprint2/test/sp2_carls_mistake.alpha @@ -1,6 +1,7 @@ type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer +type arr : 1 -> integer function foo : T1 function bar1 : T2 @@ -23,5 +24,6 @@ entry(arg) := { w.y := 7; result := bar1(w); (* pass w (a rec type value) to bar1 *) result := bar2(5,7); (* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *) + arr(3); return 0; } diff --git a/tests/sprint3/test/sp3_carls_second_mistake.alpha b/tests/sprint3/test/sp3_carls_second_mistake.alpha new file mode 100644 index 0000000..9eb4864 --- /dev/null +++ b/tests/sprint3/test/sp3_carls_second_mistake.alpha @@ -0,0 +1,25 @@ +type string: 1 -> character +type a_of_s: 1 -> string + +(* maybe some other type definitions *) + +entry(arg) := { + [ string: one_name; string: another_name; a_of_s: many_names ] + one_name := "a string literal"; + another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *) + another_name(0) := 'C'; + another_name(1) := 'a'; + another_name(2) := 'r'; + another_name(3) := 'l'; + a_of_s := reserve a_of_s(3); + a_of_s(0) := one_name; + a_of_s(1) := another_name; + many_names(2) := reserve many_names(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *) + many_names(2)(0) := "P"; + many_names(2)(1) := "a"; + many_names(2)(2) := "r"; + many_names(2)(3) := "t"; + many_names(2)(4) := "h"; + many_names(2)(5) := "o"; + return 0; +} \ No newline at end of file From f4b31ee835c854680997f80916a1a2321c14d7b4 Mon Sep 17 00:00:00 2001 From: Annie Date: Wed, 2 Apr 2025 12:59:38 -0400 Subject: [PATCH 31/38] type checking for non as function calls might be working --- src/grammar.y | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 6edd68f..2db7495 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -173,10 +173,11 @@ definition: cur = CreateScope(cur, 0, 0); }AS L_PAREN { TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); + printdebug("%s", getType(parameter)); if (parameter == undefined) { printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(parameter) != TYPE_RECORD){ - printdebug("record: %s., primitive: %s.", getName(parameter), getName(recprime)); + printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime)); printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); }else { for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ @@ -297,11 +298,11 @@ L_PAREN argument_list R_PAREN {$$ = $2; printdebug("ablock is %d", argument_list: expression COMMA argument_list { - CreateEntry(cur, NULL, $1, NULL); + CreateEntry(cur, look_up(cur, $1), "", NULL); $$ = $3 + 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} | expression { - CreateEntry(cur, NULL, $1, NULL); + CreateEntry(cur, look_up(cur, $1), "", NULL); $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} ; @@ -402,8 +403,8 @@ assignable: } //this isn't very efficient, but will hopefully work while (lastCheckedAct != NULL && lastCheckedRef != NULL) { - if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) { - printdebug("expected %s expression in function call but got %s at line %d and column %d",getName(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); + if (strcmp(getType(lastCheckedAct), getName(lastCheckedRef)) != 0) { + printdebug("expected %s expression in function call but got %s at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); } lastCheckedAct = getNextEntry(lastCheckedAct); TableNode *tn = getFirstEntry(recList); @@ -415,7 +416,7 @@ assignable: } else { char *expected = getName(getParameter(look_up(getParent(cur), $1))); - char *actual = getName(getFirstEntry(cur)); + 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); } From 692025412e7877fdfe1578b85afe54238532f3d5 Mon Sep 17 00:00:00 2001 From: Partho Date: Wed, 2 Apr 2025 13:16:56 -0400 Subject: [PATCH 32/38] fixed getAdInfo function --- src/symbol_table.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 6551c1d..b896306 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -66,10 +66,10 @@ typedef enum { // TYPE_ADDRESS, // Type String is an array of char enclosed in double quotes per lexer TYPE_STRING = 1, - // Array can be multidimensional. Information should be stored here - TYPE_ARRAY = 2, + // Array can be multidimensional. Information should be stored here. This is the type of the array + TYPE_ARRAY_TYPE = 2, // Record is user defined types - TYPE_RECORD = 3, + TYPE_RECORD_TYPE = 3, // Declaring what type a particular function is without as TYPE_FUNCTION_DECLARATION = 4, // Declaring what type a particular function is with as @@ -82,7 +82,9 @@ typedef enum { TYPE_PRIMITIVE = 6, // likely NULL TYPE_ALL_ELSE = 7, - TYPE_UNDEFINED = 8 + TYPE_UNDEFINED = 8, + TYPE_RECORD = 9, + TYPE_ARRAY = 10 } types; @@ -688,13 +690,13 @@ int getAdInfoType(TableNode *tn) { return TYPE_PRIMITIVE; } if (strcmp(getName(tn), getName(stri)) == 0) { - return TYPE_ARRAY; + return TYPE_ARRAY_TYPE; } if (strcmp(getName(tn), getName(boo)) == 0) { return TYPE_PRIMITIVE; } if (strcmp(getName(tn), getName(recprime)) == 0) { - return TYPE_RECORD; + return TYPE_RECORD_TYPE; } if (strcmp(getName(tn), getName(funtypeprime)) == 0) { return TYPE_FUNCTION_TYPE; @@ -705,6 +707,21 @@ int getAdInfoType(TableNode *tn) { if (strcmp(getName(tn), getName(undefined)) == 0) { return TYPE_UNDEFINED; } else { + if(strcmp(getType(tn), getName(funtypeprime))==0){ + printdebug("passed in a function to getAdInfoType"); + return TYPE_FUNCTION_DECLARATION; + } + if(strcmp(getType(tn), getName(arrayprim))==0){ + printdebug("passed in an array to getAdInfoType"); + return TYPE_ARRAY; + } + if(strcmp(getType(tn), getName(recprime))==0){ + printdebug("passed in a record to getAdInfoType"); + return TYPE_RECORD; + } + printdebug( + "passed in an entry that is not a primitive type, array, " + "or record. Invalid."); return TYPE_FUNCTION_DECLARATION; } } From 20c372f134ac2846121fc844db115145b6ac44d5 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Wed, 2 Apr 2025 13:19:37 -0400 Subject: [PATCH 33/38] more type check fixes --- src/grammar.y | 72 +++++++++++-------- .../test/sp3_carls_second_mistake.alpha | 18 ++--- 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 2db7495..4ac0f0d 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -266,13 +266,20 @@ simple_statement: { if(strcmp($1, $3) == 0) { printdebug("Passed standard type check; assignable = expression"); - } else if((strcmp($1, "rec") == 0) && (strcmp($3, "address") == 0)) { - printdebug("Passed rec type check; rec = address"); - } else if((strcmp($1, "array") == 0) && (strcmp($3, "address") == 0)) { - printdebug("Passed array type check; array = address"); + } else if((strcmp(getType(look_up(cur, $1)), "array") == 0) && (strcmp($3, "address") == 0)) { + printdebug("%s[☺] Passed array type check; %s = %s", COLOR_GREEN, $1, $3); + } else if((strcmp(getType(look_up(cur, $1)), "record") == 0) && (strcmp($3, "address") == 0)) { + printdebug("%s[☺] Passed address type check; %s = %s", COLOR_GREEN, $1, $3); + } else if((strcmp(getType(look_up(cur, $1)), "function type primitive") == 0) && (strcmp($3, "address") == 0)) { + printdebug("%s[☺] Passed function type primitive type check; %s = %s", COLOR_GREEN, $1, $3); + // } else if () { + + // } else if(strcmp(getType(table_lookup(cur, $1)), getType(table_lookup(cur, $3))) == 0) { + // printdebug("%s[] Passed double lookup type check; %s = %s", COLOR_GREEN, $1, $3); } else { printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, $1, $3, COLOR_WHITE); + printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType(look_up(cur, $1))); } } @@ -387,32 +394,35 @@ expression: // add array case // include type check for ablock in arrays - ablock is always the int of the elements in array/rec assignable: - ID {$$ = getType(look_up(cur,$1)); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} - | assignable { - cur = CreateScope(cur, -1,-1); - }ablock { - int type = getAdInfoType(look_up(getParent(cur), $1)); - if (type == TYPE_FUNCTION_DECLARATION) { - if (getAsKeyword(look_up(getParent(cur), $1))) { - TableNode *param = getParameter(look_up(getParent(cur), $1)); - SymbolTable *recList = getRecList(param); - TableNode *lastCheckedRef = getFirstEntry(recList); - TableNode *lastCheckedAct = getFirstEntry(cur); - while (getNextEntry(lastCheckedRef) != NULL) { - lastCheckedRef = getNextEntry(lastCheckedRef); - } - //this isn't very efficient, but will hopefully work - while (lastCheckedAct != NULL && lastCheckedRef != NULL) { - if (strcmp(getType(lastCheckedAct), getName(lastCheckedRef)) != 0) { - printdebug("expected %s expression in function call but got %s at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); - } - lastCheckedAct = getNextEntry(lastCheckedAct); - TableNode *tn = getFirstEntry(recList); - while (getNextEntry(tn) != lastCheckedRef) { - tn = getNextEntry(tn); - } - lastCheckedRef = tn; - } + ID {$$ = getType(look_up(cur,$1)); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} + | assignable + { + cur = CreateScope(cur, -1,-1); + } + ablock + { + int type = getAdInfoType(look_up(getParent(cur), $1)); + if (type == TYPE_FUNCTION_DECLARATION) { + if (getAsKeyword(look_up(getParent(cur), $1))) { + TableNode *param = getParameter(look_up(getParent(cur), $1)); + SymbolTable *recList = getRecList(param); + TableNode *lastCheckedRef = getFirstEntry(recList); + TableNode *lastCheckedAct = getFirstEntry(cur); + while (getNextEntry(lastCheckedRef) != NULL) { + lastCheckedRef = getNextEntry(lastCheckedRef); + } + //this isn't very efficient, but will hopefully work + while (lastCheckedAct != NULL && lastCheckedRef != NULL) { + if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) { + printdebug("expected %s expression in function call but got %s at line %d and column %d",getName(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); + } + lastCheckedAct = getNextEntry(lastCheckedAct); + TableNode *tn = getFirstEntry(recList); + while (getNextEntry(tn) != lastCheckedRef) { + tn = getNextEntry(tn); + } + lastCheckedRef = tn; + } } else { char *expected = getName(getParameter(look_up(getParent(cur), $1))); @@ -433,7 +443,7 @@ assignable: printdebug("expected only integer expressions in array ablock at line %d column %d", @3.first_line, @3.first_column); } } - $$ = $1; + $$ = getName(getArrType(look_up(getParent(cur), $1))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); } cur = getParent(cur); diff --git a/tests/sprint3/test/sp3_carls_second_mistake.alpha b/tests/sprint3/test/sp3_carls_second_mistake.alpha index 9eb4864..26c64d2 100644 --- a/tests/sprint3/test/sp3_carls_second_mistake.alpha +++ b/tests/sprint3/test/sp3_carls_second_mistake.alpha @@ -11,15 +11,15 @@ entry(arg) := { another_name(1) := 'a'; another_name(2) := 'r'; another_name(3) := 'l'; - a_of_s := reserve a_of_s(3); - a_of_s(0) := one_name; - a_of_s(1) := another_name; + many_names := reserve many_names(3); + many_names(0) := one_name; + many_names(1) := another_name; many_names(2) := reserve many_names(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *) - many_names(2)(0) := "P"; - many_names(2)(1) := "a"; - many_names(2)(2) := "r"; - many_names(2)(3) := "t"; - many_names(2)(4) := "h"; - many_names(2)(5) := "o"; + many_names(2)(0) := 'P'; + many_names(2)(1) := 'a'; + many_names(2)(2) := 'r'; + many_names(2)(3) := 't'; + many_names(2)(4) := 'h'; + many_names(2)(5) := 'o'; return 0; } \ No newline at end of file From 77c4106b1b3faeb6b58eadb0eb5e50a81d9f14c7 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Wed, 2 Apr 2025 15:03:29 -0400 Subject: [PATCH 34/38] latest --- src/grammar.y | 88 +++++++++++-------- src/symbol_table.c | 18 ++-- .../test/sp3_carls_second_mistake.alpha | 2 +- 3 files changed, 63 insertions(+), 45 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 4ac0f0d..0ad9cea 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -132,7 +132,9 @@ definition: | TYPE ID COLON C_INTEGER ARROW id_or_types {printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, $6, $4); - CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} + CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6))); + printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, $6); + } | function_declaration | TYPE ID COLON id_or_types ARROW id_or_types { printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", @@ -237,8 +239,12 @@ declaration_list: ; declaration: - id_or_types COLON ID {printdebug("ID/TYPE: %s, ID: %s", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } - ; + id_or_types COLON ID + { + printdebug("ID/TYPE: %s, ID: %s", $1, $3) ; + CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); + } + ; id_or_types: ID {printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = $1;} @@ -394,15 +400,21 @@ expression: // add array case // include type check for ablock in arrays - ablock is always the int of the elements in array/rec assignable: - ID {$$ = getType(look_up(cur,$1)); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} - | assignable + ID { + $$ = getType(look_up(cur,$1)); + printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} + | assignable + { + printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); cur = CreateScope(cur, -1,-1); } - ablock - { + ablock { int type = getAdInfoType(look_up(getParent(cur), $1)); + printdebug("%stype is %d", COLOR_PURPLE, type); + if (type == TYPE_FUNCTION_DECLARATION) { + printdebug("%sEntering function call", COLOR_LIGHTGREEN); if (getAsKeyword(look_up(getParent(cur), $1))) { TableNode *param = getParameter(look_up(getParent(cur), $1)); SymbolTable *recList = getRecList(param); @@ -414,7 +426,7 @@ assignable: //this isn't very efficient, but will hopefully work while (lastCheckedAct != NULL && lastCheckedRef != NULL) { if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) { - printdebug("expected %s expression in function call but got %s at line %d and column %d",getName(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); + printdebug("expected %s expression in function call but got %s at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); } lastCheckedAct = getNextEntry(lastCheckedAct); TableNode *tn = getFirstEntry(recList); @@ -424,33 +436,39 @@ assignable: lastCheckedRef = tn; } - } else { - char *expected = getName(getParameter(look_up(getParent(cur), $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); - } - } - - $$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); - } else if (type == TYPE_ARRAY) { - if (getNumArrDim(look_up(getParent(cur), $1)) != $2) { - printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $2, @2.first_line, @2.first_column); - } - for (TableNode *tn = getFirstEntry(cur); tn != NULL; tn = getNextEntry(tn)) { - if (strcmp(getName(tn), "integer") != 0) { - printdebug("expected only integer expressions in array ablock at line %d column %d", @3.first_line, @3.first_column); - } - } - $$ = getName(getArrType(look_up(getParent(cur), $1))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); - } - cur = getParent(cur); - } - | assignable rec_op ID {if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)){ - {$$ = getName(table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3));}}; printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1);} - ; + } else { + char *expected = getName(getParameter(look_up(getParent(cur), $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); + } + } + $$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); + + } else if (type == TYPE_ARRAY_TYPE) { + printdebug("%sEntering array call", COLOR_LIGHTGREEN); + if (getNumArrDim(look_up(getParent(cur), $1)) != $2) { + printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $2, @2.first_line, @2.first_column); + } + // for (TableNode *tn = getFirstEntry(cur); tn != NULL; tn = getNextEntry(tn)) { + // if (strcmp(getName(tn), "integer") != 0) { + // printdebug("expected only integer expressions in array ablock at line %d column %d", @3.first_line, @3.first_column); + // } + // } + $$ = getName(getArrType(look_up(getParent(cur), $1))); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); + } + cur = getParent(cur); + } + | assignable rec_op ID + { + if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)) { + $$ = getName(table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)); + } + printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1); + } + ; memOp: RESERVE {printdebug("reserve expression");} diff --git a/src/symbol_table.c b/src/symbol_table.c index b896306..1dc6e31 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -702,7 +702,7 @@ int getAdInfoType(TableNode *tn) { return TYPE_FUNCTION_TYPE; } if (strcmp(getName(tn), getName(arrayprim)) == 0) { - return TYPE_ARRAY; + return TYPE_ARRAY_TYPE; // changed from TYPE_ARRAY cuz } if (strcmp(getName(tn), getName(undefined)) == 0) { return TYPE_UNDEFINED; @@ -713,7 +713,7 @@ int getAdInfoType(TableNode *tn) { } if(strcmp(getType(tn), getName(arrayprim))==0){ printdebug("passed in an array to getAdInfoType"); - return TYPE_ARRAY; + return TYPE_ARRAY_TYPE; } if(strcmp(getType(tn), getName(recprime))==0){ printdebug("passed in a record to getAdInfoType"); @@ -1004,8 +1004,8 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { int parant_scope = 0; int current_scope = 0; if (table->Parent_Scope != NULL) { - parant_scope = table->Parent_Scope->Line_Number * 1000 + - table->Parent_Scope->Column_Number; + parant_scope = getParent(table)->Line_Number * 1000 + + getParent(table)->Column_Number; current_scope = table->Line_Number * 1000 + table->Column_Number; } else { @@ -1015,8 +1015,8 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", current_scope, parant_scope, "", "Empty Scope"); } - for (; entrie != NULL; entrie = entrie->next) { - if (getAdInfoType(entrie) == TYPE_ARRAY) { + for (; entrie != NULL; entrie = getNextEntry(entrie)) { + if (getAdInfoType(entrie) == TYPE_ARRAY_TYPE) { if (parant_scope == 0) { fprintf(file_ptr, @@ -1136,13 +1136,13 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } } } - if (table->Children_Scope != NULL) { - ListOfTable *node = table->Children_Scope; + if (getChildren(table) != NULL) { + ListOfTable *node = getChildren(table); for (; node != NULL; node = node->next) { print_symbol_table(node->table, file_ptr); } } - if (table->Parent_Scope == NULL) { + if (getParent(table) == NULL) { fprintf(file_ptr, "-----------------:--------:--------:--------" "--------------:-------" "----------------------\n"); diff --git a/tests/sprint3/test/sp3_carls_second_mistake.alpha b/tests/sprint3/test/sp3_carls_second_mistake.alpha index 26c64d2..6d1d614 100644 --- a/tests/sprint3/test/sp3_carls_second_mistake.alpha +++ b/tests/sprint3/test/sp3_carls_second_mistake.alpha @@ -20,6 +20,6 @@ entry(arg) := { many_names(2)(2) := 'r'; many_names(2)(3) := 't'; many_names(2)(4) := 'h'; - many_names(2)(5) := 'o'; + 0(2)(5) := 'o'; return 0; } \ No newline at end of file From 3186d363ed65dd275a0622f96e49cbda83ae7e6f Mon Sep 17 00:00:00 2001 From: Partho Date: Wed, 2 Apr 2025 20:31:00 -0400 Subject: [PATCH 35/38] fixed print symbol table to not print scopes used as flags --- src/symbol_table.c | 8 ++++++++ test | 0 tests/sprint2/test/sp2_carls_mistake.alpha | 1 - 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 test diff --git a/src/symbol_table.c b/src/symbol_table.c index 1dc6e31..1a879cd 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1139,7 +1139,15 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (getChildren(table) != NULL) { ListOfTable *node = getChildren(table); for (; node != NULL; node = node->next) { + if((node->table) == NULL){ print_symbol_table(node->table, file_ptr); + }else{ + if ((node->table)->Line_Number == -1){ + continue; + }else{ + print_symbol_table(node->table, file_ptr); + } + } } } if (getParent(table) == NULL) { diff --git a/test b/test new file mode 100644 index 0000000..e69de29 diff --git a/tests/sprint2/test/sp2_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha index 75fa12f..2f4c1ef 100644 --- a/tests/sprint2/test/sp2_carls_mistake.alpha +++ b/tests/sprint2/test/sp2_carls_mistake.alpha @@ -24,6 +24,5 @@ entry(arg) := { w.y := 7; result := bar1(w); (* pass w (a rec type value) to bar1 *) result := bar2(5,7); (* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *) - arr(3); return 0; } From 3d063525105eca49c1c49fa743747bd90a2ed92c Mon Sep 17 00:00:00 2001 From: Scarlett Date: Thu, 3 Apr 2025 16:37:53 -0400 Subject: [PATCH 36/38] New grammar formatting rules applied. --- src/grammar.y | 761 +++++++++++++++++++++++++-------------- src/lexicalStructure.lex | 38 +- src/symbol_table.c | 33 +- test | 0 4 files changed, 535 insertions(+), 297 deletions(-) delete mode 100644 test diff --git a/src/grammar.y b/src/grammar.y index 0ad9cea..b3f2334 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -2,38 +2,52 @@ /* Syntax Analyzer with Bison (3.8.2) */ /* The Translators - Spring 2025 */ +// ----- THIS FILE MUST BE FORMATTED CORRECTLY FOR READABILITY ----- // + +// ✏️ FORMATTING RULES: +// 1️⃣ Use 4 spaces for indentation. +// 2️⃣ Grammar rules (terminals and nonterminals) should always be on their own line. +// 3️⃣ Grammar rules and C-blocks should always begin 8 spaces in. +// 4️⃣ Rule end-markers (;, |) should always be 4 spaces in. +// 5️⃣ C-blocks should always be clearly defined and follow clang formatting rules. +// 6️⃣ 1-line if/for/while statements must be wrapped in curly braces. +// 7️⃣ DO NOT USE TABS. EVER. + +// Please ask Scarlett if you are unsure of how to format something. Thanks! 😀 + %{ - #include - #include "../src/symbol_table.c" - #include - extern int yylex(void); - void yyerror(const char *err); - extern char* yytext; - extern int yyleng; - extern int yychar; - extern SymbolTable * cur; - //char* cur_value; - //char* cur_type; - int token_tracker; - extern int line_number; - extern int column_number; - extern FILE * yyin; - extern TableNode* funprime; - extern TableNode* arrayprim; - extern TableNode* recprime; - extern TableNode* funtypeprime; - extern TableNode* integ; - extern TableNode* addr; - extern TableNode* chara; - extern TableNode* stri; - extern TableNode* boo; - TableNode * tn; + #include + #include "../src/symbol_table.c" + #include + extern int yylex(void); + void yyerror(const char *err); + extern char* yytext; + extern int yyleng; + extern int yychar; + extern SymbolTable * cur; + //char* cur_value; + //char* cur_type; + int token_tracker; + extern int line_number; + extern int column_number; + extern FILE * yyin; + extern TableNode* funprime; + extern TableNode* arrayprim; + extern TableNode* recprime; + extern TableNode* funtypeprime; + extern TableNode* integ; + extern TableNode* addr; + extern TableNode* chara; + extern TableNode* stri; + extern TableNode* boo; + TableNode * tn; %} -//%define api.location.type {location_t} + %locations + %union { - int integ; - char * words; + int integ; + char * words; } %type idlist @@ -102,174 +116,253 @@ %precedence DOT %precedence RESERVE RELEASE - - %% program: - prototype_or_definition_list - ; + prototype_or_definition_list + ; + + prototype_or_definition_list: - prototype prototype_or_definition_list - | definition prototype_or_definition_list - | prototype - | definition - ; + prototype prototype_or_definition_list + | definition prototype_or_definition_list + | prototype + | definition + ; + + prototype: - L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; + L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; + + definition: - TYPE ID COLON { - printdebug("Currently see a record definition for %s", $2); - tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); - if (table_lookup(getAncestor(cur), $2) == undefined) { - printdebug("rec not found "); - } - }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); - cur = getParent(cur);} - | TYPE ID COLON C_INTEGER ARROW id_or_types - {printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", - $2, $6, $4); - CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6))); - printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, $6); + TYPE ID COLON + { + printdebug("Currently see a record definition for %s", $2); + tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); + if (table_lookup(getAncestor(cur), $2) == undefined) { + printdebug("rec not found "); + } } - | function_declaration - | TYPE ID COLON id_or_types ARROW id_or_types { - printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", - $2, $4, $6); - CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); + dblock + { + setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); + cur = getParent(cur); + } + + | TYPE ID COLON C_INTEGER ARROW id_or_types + { + printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, $6, $4); + CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6))); + printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, $6); + } + + | function_declaration + + | TYPE ID COLON id_or_types ARROW id_or_types + { + printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", $2, $4, $6); + CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); } - | ID { - TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == undefined) { - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); - }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + + | ID + { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == undefined) { + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, false); + } + cur = CreateScope(cur, 0, 0); + } + L_PAREN ID + { + printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", $1,$4); + CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); + } + R_PAREN ASSIGN sblock + + | ID + { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == undefined) { + printdebug("null check"); + } + if (node == undefined) { + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, true); + } + cur = CreateScope(cur, 0, 0); + } + AS L_PAREN + { + TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); + printdebug("%s", getType(parameter)); + if (parameter == undefined) { + printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); + } else if(getAdInfoType(parameter) != TYPE_RECORD) { + printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime)); + printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); + } else { + for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)) { + CreateEntry(cur, entry, NULL, NULL); } - else { - setStartLine(node, @1.first_line); - setAsKeyword(node, false); - } - cur = CreateScope(cur, 0, 0); - } L_PAREN ID { - printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", - $1,$4); - CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); - }R_PAREN ASSIGN sblock - | ID { - TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == undefined) { - printdebug("null check"); - } - if (node == undefined) { - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); - }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); - } - else { - setStartLine(node, @1.first_line); - setAsKeyword(node, true); - } - cur = CreateScope(cur, 0, 0); - }AS L_PAREN { - TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); - printdebug("%s", getType(parameter)); - if (parameter == undefined) { - printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); - }else if(getAdInfoType(parameter) != TYPE_RECORD){ - printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime)); - printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); - }else { - for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ - CreateEntry(cur, entry, NULL, NULL); - } - } - } idlist {printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", - $1,$6);} R_PAREN ASSIGN sblock - ; + } + } + idlist + { + printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", $1,$6); + } + R_PAREN ASSIGN sblock + ; function_declaration: - FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} - | EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);} - ; + FUNCTION ID COLON ID + { + CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); + } + + | EXTERNAL FUNCTION ID COLON ID + { + CreateEntry(cur, look_up(cur, $5), $3, NULL); + } + ; + idlist: - ID { - TableNode *entry = getFirstEntry(cur); - while (strcmp(getName(entry),"undefined") != 0) { - entry = getNextEntry(entry); - } - if (getNextEntry(entry) == NULL) { - printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); - } - addName(entry, $1); - } COMMA idlist {$$ = $4 + 1;} - | ID { - - TableNode *entry = getFirstEntry(cur); - while (strcmp(getName(entry),"undefined") != 0) { - entry = getNextEntry(entry); - } - if (getNextEntry(entry) != NULL) { - printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); - } - addName(entry, $1); - $$ = 1; - } - ; + ID + { + TableNode *entry = getFirstEntry(cur); + while (strcmp(getName(entry),"undefined") != 0) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) == NULL) { + printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); + } + addName(entry, $1); + } + COMMA idlist + { + $$ = $4 + 1; + } + + | ID + { + TableNode *entry = getFirstEntry(cur); + while (strcmp(getName(entry),"undefined") != 0) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) != NULL) { + printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); + } + addName(entry, $1); + $$ = 1; + } + ; sblock: -L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE - | L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock - {printdebug("seen sblock with dblock");} statement_list {cur = getParent(cur);} R_BRACE - ; + L_BRACE + { + if (getLine(cur) != 0 && getColumn(cur)) { + cur = CreateScope(cur,@1.first_line,@1.first_column); + } + } + statement_list + { + cur = getParent(cur); + } + R_BRACE + + | L_BRACE + { + if (getLine(cur) != 0 && getColumn(cur)) { + cur = CreateScope(cur,@1.first_line,@1.first_column); + } + } + dblock + { + printdebug("seen sblock with dblock"); + } + statement_list + { + cur = getParent(cur); + } + R_BRACE + ; + + dblock: - L_BRACKET declaration_list R_BRACKET; + L_BRACKET declaration_list R_BRACKET; + + declaration_list: - declaration SEMI_COLON declaration_list - | declaration - ; + declaration SEMI_COLON declaration_list + | declaration + ; + + declaration: - id_or_types COLON ID + id_or_types COLON ID { printdebug("ID/TYPE: %s, ID: %s", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } ; + + id_or_types: - ID {printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = $1;} - //{printdebug("string of id is %s in ID pattern of id_or_type rule. Type passed up the tree is %s.",$1,getType(look_up(cur,$1))); $$ = getType(look_up(cur,$1));} - | types {printdebug("string of type is %s in types pattern of id_or_type rule.",$1);} {$$ = $1;} - //{printdebug("string of type is %s in types pattern of id_or_type rule. That is passed up the tree.",$1);} {$$ = $1;} - ; - ; + ID + { + printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = $1; + } + + | types + { + printdebug("string of type is %s in types pattern of id_or_type rule.",$1); + $$ = $1; + } + ; + + statement_list: - compound_statement statement_list - | compound_statement - | simple_statement SEMI_COLON statement_list - | simple_statement SEMI_COLON - ; + compound_statement statement_list + | compound_statement + | simple_statement SEMI_COLON statement_list + | simple_statement SEMI_COLON + ; + + compound_statement: - WHILE L_PAREN expression R_PAREN sblock - | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock - | sblock //{printdebug("seen a compound statement rule");} - ; + WHILE L_PAREN expression R_PAREN sblock + | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock + | sblock + ; + + simple_statement: - assignable ASSIGN expression - { + assignable ASSIGN expression + { if(strcmp($1, $3) == 0) { printdebug("Passed standard type check; assignable = expression"); } else if((strcmp(getType(look_up(cur, $1)), "array") == 0) && (strcmp($3, "address") == 0)) { @@ -287,114 +380,194 @@ simple_statement: printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, $1, $3, COLOR_WHITE); printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType(look_up(cur, $1))); } - } + } - | RETURN expression - ; -rec_op : - DOT + | RETURN expression + ; - -/////////// VERIFIED UP UNTIL THIS POINT - -// assignable needs more code- specifically for arrays, records and ablock checks - - +rec_op: + DOT ablock: -L_PAREN argument_list R_PAREN {$$ = $2; printdebug("ablock is %d", $$);} - ; + L_PAREN argument_list R_PAREN + { + $$ = $2; + printdebug("ablock is %d", $$); + } + ; + + argument_list: - expression COMMA argument_list { - CreateEntry(cur, look_up(cur, $1), "", NULL); - $$ = $3 + 1; - printdebug("[ARGUMENT_LIST] argument list is %d", $$);} - | expression { - CreateEntry(cur, look_up(cur, $1), "", NULL); - $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} - ; + expression COMMA argument_list + { + CreateEntry(cur, look_up(cur, $1), "", NULL); + $$ = $3 + 1; + printdebug("[ARGUMENT_LIST] argument list is %d", $$); + } + + | expression + { + CreateEntry(cur, look_up(cur, $1), "", NULL); + $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); + } + ; + + // will ALWAYS be a TYPE expression: - constant {printdebug("constant expression");} {$$ = $1;} + constant + { + printdebug("constant expression"); + $$ = $1; + } - | SUB_OR_NEG expression %prec UMINUS {printdebug("negative expression");if(strcmp($2,"integer") != 0) - {printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column); - $$=strdup("undefined");}else{$$=$2;}} + | SUB_OR_NEG expression %prec UMINUS + { + printdebug("negative expression"); + if(strcmp($2,"integer") != 0) { + printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column); + $$=strdup("undefined"); + } else { + $$=$2; + } + } - | NOT expression {printdebug("not expression"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); - printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", - @1.first_line,@1.first_column,$2);}} + | NOT expression + { + printdebug("not expression"); + if(strcmp($2,"Boolean")==0) { + $$=$2; + } else { + $$=strdup("undefined"); + printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,$2); + } + } - | expression ADD expression - {printdebug("add expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression ADD expression + { + printdebug("add expression"); + if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) { + $$=strdup("integer"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression SUB_OR_NEG expression - {printdebug("sub or neg expression");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression SUB_OR_NEG expression + { + printdebug("sub or neg expression"); + if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0) { + $$=strdup("integer"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression MUL expression - {printdebug("multiply expression"); - if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression MUL expression + { + printdebug("multiply expression"); + if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0) { + $$=strdup("integer"); + } else{ + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression DIV expression - {printdebug("divide expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression DIV expression + { + printdebug("divide expression"); + if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) { + $$=strdup("integer"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression REM expression - {printdebug("remainder expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression REM expression + { + printdebug("remainder expression"); + if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) { + $$=strdup("integer"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression AND expression - {printdebug("AND expression");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression AND expression + { + printdebug("AND expression"); + if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0) { + $$=strdup("Boolean"); + } else{ + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression OR expression - {printdebug("OR");if(strcmp($1,$3)==0 && - strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression OR expression + { + printdebug("OR"); + if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0) { + $$=strdup("Boolean"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression LESS_THAN expression - {printdebug("less than expression");if(strcmp($1,$3)==0 && - strcmp($1,"integer")==0){$$=strdup("Boolean");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression LESS_THAN expression + { + printdebug("less than expression"); + if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) { + $$=strdup("Boolean"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression EQUAL_TO expression {printdebug("equals check expression"); - if(strcmp($1,$3)==0){$$=strdup("Boolean");} - //else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| - // strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s", - @2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} + | expression EQUAL_TO expression + { + printdebug("equals check expression"); + if(strcmp($1,$3)==0) { + $$=strdup("Boolean"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | assignable {printdebug("assignable expression. current type is %s",$1);$$=$1;} + | assignable + { + printdebug("assignable expression. current type is %s",$1); + $$=$1; + } + + | L_PAREN expression R_PAREN + { + printdebug("paren expression. current type is %s",$2); + $$=$2; + } + + | memOp assignable + { + $$ = strdup("address"); + } + + ; - | L_PAREN expression R_PAREN {printdebug("paren expression. current type is %s",$2);$$=$2;} - | memOp assignable {$$ = strdup("address");} - ; // prolly right, check back with me later // add array case @@ -403,13 +576,16 @@ assignable: ID { $$ = getType(look_up(cur,$1)); - printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} + printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1); + } + | assignable { printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); cur = CreateScope(cur, -1,-1); } - ablock { + ablock + { int type = getAdInfoType(look_up(getParent(cur), $1)); printdebug("%stype is %d", COLOR_PURPLE, type); @@ -434,8 +610,7 @@ assignable: tn = getNextEntry(tn); } lastCheckedRef = tn; - } - + } } else { char *expected = getName(getParameter(look_up(getParent(cur), $1))); char *actual = getType(getFirstEntry(cur)); @@ -443,6 +618,7 @@ assignable: printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); } } + $$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); @@ -451,16 +627,12 @@ assignable: if (getNumArrDim(look_up(getParent(cur), $1)) != $2) { printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $2, @2.first_line, @2.first_column); } - // for (TableNode *tn = getFirstEntry(cur); tn != NULL; tn = getNextEntry(tn)) { - // if (strcmp(getName(tn), "integer") != 0) { - // printdebug("expected only integer expressions in array ablock at line %d column %d", @3.first_line, @3.first_column); - // } - // } $$ = getName(getArrType(look_up(getParent(cur), $1))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); } cur = getParent(cur); } + | assignable rec_op ID { if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)) { @@ -468,34 +640,97 @@ assignable: } printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1); } + ; + + memOp: - RESERVE {printdebug("reserve expression");} - | RELEASE {printdebug("release expression");} - ; + RESERVE + { + printdebug("reserve expression"); + } + + | RELEASE + { + printdebug("release expression"); + } + + ; constant: - C_STRING {$$ = $1; printdebug("string of C_STRING in constant is %s",$1);} - | C_INTEGER {$$ = "integer"; printdebug("string of C_INTEGER in constant is integer");} - | C_NULL {$$ = $1; printdebug("string of C_NULL in constant is %s",$1);} - | C_CHARACTER {$$ = $1; printdebug("string of C_CHARACTER in constant is %s",$1);} - | C_TRUE {$$ = $1; printdebug("string of C_TRUE in constant is %s",$1);} - | C_FALSE {$$ = $1; printdebug("string of C_FALSE in constant is %s",$1);} - ; + C_STRING + { + $$ = $1; + printdebug("string of C_STRING in constant is %s",$1); + } + + | C_INTEGER + { + $$ = "integer"; + printdebug("string of C_INTEGER in constant is integer"); + } + + | C_NULL + { + $$ = $1; + printdebug("string of C_NULL in constant is %s",$1); + } + + | C_CHARACTER + { + $$ = $1; + printdebug("string of C_CHARACTER in constant is %s",$1); + } + + | C_TRUE + { + $$ = $1; + printdebug("string of C_TRUE in constant is %s",$1); + } + + | C_FALSE + { + $$ = $1; + printdebug("string of C_FALSE in constant is %s",$1); + } + + ; + + types: - // Commented out T_String below - // T_STRING {printdebug("string of T_STRING in types is %s",$1);} {$$ = $1;} - T_INTEGER {printdebug("string of T_INTEGER in types is %s",$1);} {$$ = $1;} - | T_ADDRESS {printdebug("string of T_ADDRESS in types is %s",$1);} {$$ = $1;} - | T_CHARACTER {printdebug("string of T_CHARACTER in types is %s",$1);} {$$ = $1;} - | T_BOOLEAN {printdebug("string of T_BOOLEAN in types is %s",$1);} {$$ = $1;} - ; + T_INTEGER + { + $$ = $1; + printdebug("string of T_INTEGER in types is %s",$1); + } + + | T_ADDRESS + { + $$ = $1; + printdebug("string of T_ADDRESS in types is %s",$1); + } + + | T_CHARACTER + { + $$ = $1; + printdebug("string of T_CHARACTER in types is %s",$1); + } + + | T_BOOLEAN + { + $$ = $1; + printdebug("string of T_BOOLEAN in types is %s",$1); + } + + ; %% + + void yyerror(const char *err) { - fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d", err,yytext,yylloc.first_line,yylloc.first_column); + fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d", err,yytext,yylloc.first_line,yylloc.first_column); } diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index b43c979..920cdc4 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -5,25 +5,25 @@ %option header-file="flex.h" %option yylineno %{ - #include - #include "../tmp/grammar.tab.h" - #include "../src/symbol_table.h" - #ifndef DEBUG - #define DEBUG 0 - #endif - extern SymbolTable * cur; - extern FILE* tok_flag; - extern void incr(int lnum,int cnum, int tok); - extern void print_tok(int tok); - - int line_number = 1, column_number = 1; - int yycolumn = 1; - #define YY_USER_ACTION { \ - yylloc.first_line = yylineno; \ - yylloc.last_line = yylineno; \ - yylloc.first_column = yycolumn; \ - yylloc.last_column = yycolumn + yyleng - 1; \ - yycolumn += yyleng; } + #include + #include "../tmp/grammar.tab.h" + #include "../src/symbol_table.h" + #ifndef DEBUG + #define DEBUG 0 + #endif + extern SymbolTable * cur; + extern FILE* tok_flag; + extern void incr(int lnum,int cnum, int tok); + extern void print_tok(int tok); + + int line_number = 1, column_number = 1; + int yycolumn = 1; + #define YY_USER_ACTION { \ + yylloc.first_line = yylineno; \ + yylloc.last_line = yylineno; \ + yylloc.first_column = yycolumn; \ + yylloc.last_column = yycolumn + yyleng - 1; \ + yycolumn += yyleng; } %} STARCOM [^\*]|\*+[^\)\*]+ diff --git a/src/symbol_table.c b/src/symbol_table.c index 1a879cd..97b4eac 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -66,7 +66,8 @@ typedef enum { // TYPE_ADDRESS, // Type String is an array of char enclosed in double quotes per lexer TYPE_STRING = 1, - // Array can be multidimensional. Information should be stored here. This is the type of the array + // Array can be multidimensional. Information should be stored here. + // This is the type of the array TYPE_ARRAY_TYPE = 2, // Record is user defined types TYPE_RECORD_TYPE = 3, @@ -84,7 +85,7 @@ typedef enum { TYPE_ALL_ELSE = 7, TYPE_UNDEFINED = 8, TYPE_RECORD = 9, - TYPE_ARRAY = 10 + TYPE_ARRAY = 10 } types; @@ -513,8 +514,9 @@ SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column) { // types SymbolTable *init(SymbolTable *start) { if (start->Parent_Scope != NULL) { - printdebug( - "%s[FATAL] Cannot initialize a scope that is not the parent scope", COLOR_RED); + printdebug("%s[FATAL] Cannot initialize a scope that is not " + "the parent scope", + COLOR_RED); return NULL; } integ = (TableNode *)calloc(1, sizeof(TableNode)); @@ -707,15 +709,15 @@ int getAdInfoType(TableNode *tn) { if (strcmp(getName(tn), getName(undefined)) == 0) { return TYPE_UNDEFINED; } else { - if(strcmp(getType(tn), getName(funtypeprime))==0){ + if (strcmp(getType(tn), getName(funtypeprime)) == 0) { printdebug("passed in a function to getAdInfoType"); return TYPE_FUNCTION_DECLARATION; } - if(strcmp(getType(tn), getName(arrayprim))==0){ + if (strcmp(getType(tn), getName(arrayprim)) == 0) { printdebug("passed in an array to getAdInfoType"); - return TYPE_ARRAY_TYPE; + return TYPE_ARRAY_TYPE; } - if(strcmp(getType(tn), getName(recprime))==0){ + if (strcmp(getType(tn), getName(recprime)) == 0) { printdebug("passed in a record to getAdInfoType"); return TYPE_RECORD; } @@ -1139,13 +1141,14 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (getChildren(table) != NULL) { ListOfTable *node = getChildren(table); for (; node != NULL; node = node->next) { - if((node->table) == NULL){ - print_symbol_table(node->table, file_ptr); - }else{ - if ((node->table)->Line_Number == -1){ - continue; - }else{ - print_symbol_table(node->table, file_ptr); + if ((node->table) == NULL) { + print_symbol_table(node->table, file_ptr); + } else { + if ((node->table)->Line_Number == -1) { + continue; + } else { + print_symbol_table(node->table, + file_ptr); } } } diff --git a/test b/test deleted file mode 100644 index e69de29..0000000 From 4e862d54a4285d856dd53ba880b83b6d9e54674a Mon Sep 17 00:00:00 2001 From: Scarlett Date: Thu, 3 Apr 2025 18:29:43 -0400 Subject: [PATCH 37/38] Header files updated --- src/grammar.y | 29 +---- src/lexicalStructure.lex | 2 +- src/runner.c | 13 +-- src/runner.h | 46 ++++++-- src/symbol_table.c | 235 +-------------------------------------- src/symbol_table.h | 118 ++++++++++++++------ 6 files changed, 132 insertions(+), 311 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index b3f2334..63f2034 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -11,35 +11,16 @@ // 4️⃣ Rule end-markers (;, |) should always be 4 spaces in. // 5️⃣ C-blocks should always be clearly defined and follow clang formatting rules. // 6️⃣ 1-line if/for/while statements must be wrapped in curly braces. -// 7️⃣ DO NOT USE TABS. EVER. +// 7️⃣ Comments should always be above rules +// 8️⃣ DO NOT USE TABS. EVER. // Please ask Scarlett if you are unsure of how to format something. Thanks! 😀 %{ - #include #include "../src/symbol_table.c" - #include - extern int yylex(void); + void yyerror(const char *err); - extern char* yytext; - extern int yyleng; - extern int yychar; - extern SymbolTable * cur; - //char* cur_value; - //char* cur_type; int token_tracker; - extern int line_number; - extern int column_number; - extern FILE * yyin; - extern TableNode* funprime; - extern TableNode* arrayprim; - extern TableNode* recprime; - extern TableNode* funtypeprime; - extern TableNode* integ; - extern TableNode* addr; - extern TableNode* chara; - extern TableNode* stri; - extern TableNode* boo; TableNode * tn; %} @@ -144,7 +125,7 @@ definition: printdebug("Currently see a record definition for %s", $2); tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); if (table_lookup(getAncestor(cur), $2) == undefined) { - printdebug("rec not found "); + printdebug("rec not found"); } } dblock @@ -196,7 +177,7 @@ definition: } if (node == undefined) { printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); - } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + } else if (getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); } else { setStartLine(node, @1.first_line); diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index 920cdc4..00b5a4d 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -4,8 +4,8 @@ %option noyywrap %option header-file="flex.h" %option yylineno + %{ - #include #include "../tmp/grammar.tab.h" #include "../src/symbol_table.h" #ifndef DEBUG diff --git a/src/runner.c b/src/runner.c index c6f94a3..5f903c3 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2,17 +2,6 @@ /* The Translators - Spring 2025 */ #include "runner.h" -extern TableNode *funprime; -extern TableNode *arrayprim; -extern TableNode *integ; -extern TableNode *addr; -extern TableNode *chara; -extern TableNode *stri; -extern TableNode *boo; -extern bool DEBUG; -extern char *COLOR_YELLOW; -extern char *COLOR_BLUE; -extern char *COLOR_WHITE; int main(int argc, char *argv[]) { // if last argument is debug then set to true and ignore it for the rest @@ -91,10 +80,12 @@ void incr(int lnum, int cnum, int tok) { // column_number += yyleng; // } } + void print_tok(int tok) { fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number, tok, yytext); } + int run(FILE *alpha) { int token; top = cur = init(CreateScope(NULL, 1, 1)); diff --git a/src/runner.h b/src/runner.h index 9678609..cc573c5 100644 --- a/src/runner.h +++ b/src/runner.h @@ -25,30 +25,56 @@ #include #include "../tmp/flex.h" -#include "symbol_table.h" -// #include "typedefs.h" #include "../tmp/grammar.tab.h" +#include "symbol_table.h" extern int line_number, column_number; extern char *yytext; extern FILE *yyin; -int arg; +extern bool DEBUG; SymbolTable *top; SymbolTable *cur; -// int main(int argc, char* argv[]); -char *is_tok(int argc, char *argv[]); -// int is_alpha_file(char *file, int file_len); - FILE *alpha_file; FILE *tok_flag = NULL; FILE *st_flag = NULL; +bool DEBUG = false; int no_flag = 0; +int arg; + +TableNode *funprime; +TableNode *arrayprim; +TableNode *integ; +TableNode *addr; +TableNode *chara; +TableNode *stri; +TableNode *boo; +TableNode *recprime; +TableNode *funtypeprime; +TableNode *undefined; int main(int argc, char *argv[]); +int check_flag(char *arg, char *alpha); +void incr(int lnum, int cnum, int tok); +void print_tok(int tok); +int run(FILE *alpha); +bool is_help(char *input); int new_file(char *arg, char *alpha); int is_alpha_file(char *alpha, int file_len); -bool is_help(char *input); -int run(FILE *alpha); -int check_flag(char *arg, char *alpha); + +char *COLOR_RED = "\033[0;31m"; +char *COLOR_GREEN = "\033[0;32m"; +char *COLOR_ORANGE = "\033[0;33m"; +char *COLOR_BLUE = "\033[0;34m"; +char *COLOR_PURPLE = "\033[0;35m"; +char *COLOR_CYAN = "\033[0;36m"; +char *COLOR_LIGHTGRAY = "\033[0;37m"; +char *COLOR_DARKGRAY = "\033[1;30m"; +char *COLOR_LIGHTRED = "\033[1;31m"; +char *COLOR_LIGHTGREEN = "\033[1;32m"; +char *COLOR_YELLOW = "\033[1;33m"; +char *COLOR_LIGHTBLUE = "\033[1;34m"; +char *COLOR_LIGHTPURPLE = "\033[1;35m"; +char *COLOR_LIGHTCYAN = "\033[1;36m"; +char *COLOR_WHITE = "\033[1;37m"; \ No newline at end of file diff --git a/src/symbol_table.c b/src/symbol_table.c index 97b4eac..f458769 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -3,44 +3,6 @@ #include "symbol_table.h" -#include -#include -#include -#include -char *typey = "type"; -char *funy = "function"; -TableNode *funprime; -TableNode *arrayprim; -extern SymbolTable *cur; -TableNode *integ; -TableNode *addr; -TableNode *chara; -TableNode *stri; -TableNode *boo; -TableNode *recprime; -TableNode *funtypeprime; -TableNode *undefined; - -char *COLOR_RED = "\033[0;31m"; -char *COLOR_GREEN = "\033[0;32m"; -char *COLOR_ORANGE = "\033[0;33m"; -char *COLOR_BLUE = "\033[0;34m"; -char *COLOR_PURPLE = "\033[0;35m"; -char *COLOR_CYAN = "\033[0;36m"; -char *COLOR_LIGHTGRAY = "\033[0;37m"; -char *COLOR_DARKGRAY = "\033[1;30m"; -char *COLOR_LIGHTRED = "\033[1;31m"; -char *COLOR_LIGHTGREEN = "\033[1;32m"; -char *COLOR_YELLOW = "\033[1;33m"; -char *COLOR_LIGHTBLUE = "\033[1;34m"; -char *COLOR_LIGHTPURPLE = "\033[1;35m"; -char *COLOR_LIGHTCYAN = "\033[1;36m"; -char *COLOR_WHITE = "\033[1;37m"; - -bool DEBUG = false; - -void printdebug_impl(char *file, int line, const char *format, ...); - void printdebug_impl(char *file, int line, const char *format, ...) { if (DEBUG) { printf("%s<%s> [%d]%s ", COLOR_DARKGRAY, file, line, @@ -53,87 +15,6 @@ void printdebug_impl(char *file, int line, const char *format, ...) { } } -#define printdebug(format, ...) \ - printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) - -// AdInfo *Undefined_function_type_info; -typedef enum { - // First 4 below are primitive types that are all encapsulated in - // primitive type - // TYPE_INTEGER, - // TYPE_CHARACTER, - // TYPE_BOOLEAN, - // TYPE_ADDRESS, - // Type String is an array of char enclosed in double quotes per lexer - TYPE_STRING = 1, - // Array can be multidimensional. Information should be stored here. - // This is the type of the array - TYPE_ARRAY_TYPE = 2, - // Record is user defined types - TYPE_RECORD_TYPE = 3, - // Declaring what type a particular function is without as - TYPE_FUNCTION_DECLARATION = 4, - // Declaring what type a particular function is with as - // TYPE_AS_FUNCTION_DECLARATION, - // Declaring what type a function is (what the parameters and output - // are) - TYPE_FUNCTION_TYPE = 5, - // The Type being pointed to by the first 4 above that only stores the - // size - TYPE_PRIMITIVE = 6, - // likely NULL - TYPE_ALL_ELSE = 7, - TYPE_UNDEFINED = 8, - TYPE_RECORD = 9, - TYPE_ARRAY = 10 - -} types; - -/* put in symbol_table.h -typedef struct{ - int size; if(strcmp(getType(tn),getName(integ))==0){ - return - } -}primitive_info; - -typedef struct{ - int length; - char* location; -}string_info; - -typedef struct{ - int numofdimensions; - //the above value tells you how long the below array is. For example if num -of dimensions is 5, I can store 1,3,2,5,9 to define > int* sizesofdimensions; - TableNode* typeofarray; -}array_info; - -typedef struct{ - //similar to above we define a record to hold the number of elements and an -array of tablenodes (types) that it contains in the order specified by the user - int numofelements; - TableNode* listoftypes; -}record_info; - -typedef struct{ - int startlinenumber; - bool regularoras; -}function_declaration_info; - -typedef struct{ - TableNode* parameter; - TableNode* returntype; -}function_type_info; - -typedef union { - PrimAdInfo* primitive_info; - ArrayAdInfo* array_info; - RecAdInfo* record_info; - StringAdInfo* string_info; - FunDecAdInfo* func_dec_info; - FunTypeAdInfo* func_type_info; - }AdInfo; -*/ // primitive additional info only stores the size of that type AdInfo *CreatePrimitiveInfo(int size) { @@ -167,19 +48,10 @@ int getPrimSize(TableNode *definition) { return definition->additionalinfo->PrimAdInfo->size; } -// probably don't need the below structure since can create from an array -/*string_info* CreateStringInfo(int length, char* loc){ - string_info* stringy = (string_info*)malloc(sizeof(string_info)); - stringy.length=length; - char* location = loc; - return stringy; -} -*/ - // Only information stored in array info is the number of dimensions and the // type stored in the array per professor, the actual size of the array is // calculated at runtime so bounds checking only needs to be done then -AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { +AdInfo *CreateArrayInfo(int dim, TableNode *type) { if (type == NULL) { printdebug("passed a NULL reference to " "CreateArrayInfo. Invalid."); @@ -866,41 +738,7 @@ SymbolTable *setColumnNumber(SymbolTable *st, int column) { st->Line_Number = column; return st; } -/* -//we use false for type defs and true for functions for parameter of typeOf -TableNode* Define(SymbolTable* table, bool typeOf, char* id) { -if(table ==NULL || table->Parent_Scope != NULL){ - printdebug("No valid table given for header defs"); - return NULL; -} - - TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode)); - -//possible issues with referencing text instead of heap -if(typeOf == 0){ - newEntry->theType = typey; -} -if (typeOf == 1){ - newEntry->theType = funy; -} -if(table_lookup(table,id) != NULL){ - printdebug("already defined at the top level, can't define duplicate -names"); return NULL; -} - newEntry->theName = id; - if (table->entries == NULL) { - table->entries = newEntry; - return newEntry; - } else { - TableNode* oldEntry = table->entries; - table->entries = newEntry; - newEntry->next = oldEntry; - return newEntry; - } - -} -*/ // only check table that is given TableNode *table_lookup(SymbolTable *table, char *x) { if (table == NULL) { @@ -915,6 +753,7 @@ TableNode *table_lookup(SymbolTable *table, char *x) { } return undefined; } + // check current table and all parents TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { @@ -931,60 +770,7 @@ TableNode *look_up(SymbolTable *table, char *x) { x, getLine(table), getColumn(table)); return look_up(table->Parent_Scope, x); } -/* -void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - if (table->Parent_Scope == NULL) { - fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", - "SCOPE", "PARENT", "TYPE", "Extra annotation"); - } - TableNode *entrie = table->entries; - fprintf(file_ptr, "-----------------:--------:--------:----------------" - "------:---------" - "--------------------\n"); - int parant_scope = 0; - int current_scope = 0; - if (table->Parent_Scope != NULL) { - parant_scope = table->Parent_Scope->Line_Number * 1000 + - table->Parent_Scope->Column_Number; - current_scope = - table->Line_Number * 1000 + table->Column_Number; - } else { - current_scope = 1001; - } - if (entrie == NULL) { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", - current_scope, parant_scope, "", "Empty Scope"); - } - for (; entrie != NULL; entrie = entrie->next) { - if (parant_scope == 0) { - /*have to update if (strcmp(entrie->theType->theName, - "function primitive") || - strcmp(entrie->theType->theName, - "array")) { - } - fprintf(file_ptr, - "%-17s: %06d : : %-21s: %-28s\n", - entrie->theName, current_scope, - entrie->theType->theName, "Extra annotation"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - entrie->theType->theName, "Extra annotation"); - } - } - if (table->Children_Scope != NULL) { - ListOfTable *node = table->Children_Scope; - for (; node != NULL; node = node->next) { - print_symbol_table(node->table, file_ptr); - } - } - if (table->Parent_Scope == NULL) { - fprintf(file_ptr, "-----------------:--------:--------:--------" - "--------------:-------" - "----------------------\n"); - } -}*/ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (table == NULL) { @@ -1286,20 +1072,3 @@ TableNode *getNextEntry(TableNode *tn) { } return tn->next; } - -// uncomment the below main function along with the headers above for a simple -// standalone test of table and entry creation - -/* - int main(){ - char* String = "STRING"; - char* X = "X"; - SymbolTable* Second = CreateScope(NULL, 2,2); - printdebug("Line number is %d, Column number of scope is - %d",Second->Line_Number,Second->Column_Number); TableNode* First_Entry = - CreateEntry(Second,String,X); - - printdebug("The type of the first entry is %s",First_Entry->theType); - return 0; - } - */ \ No newline at end of file diff --git a/src/symbol_table.h b/src/symbol_table.h index de37098..5f87b5b 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -1,3 +1,4 @@ +#include #include #include #include @@ -9,26 +10,12 @@ typedef struct { int size; } primitive_info; -/*This structure can be subsumed into the structure below (1-d array of chars) -typedef struct{ - //shouldn't need to store any values since would be compiled at runtime - //int length; - //char* location; -}string_info; -*/ - typedef struct { int numofdimensions; - // the above value tells you how long the below array is. For example if - // num of dimensions is 5, I can store 1,3,2,5,9 to define > int* - // arr; shouldn't need to store any values (like sizes of dimenions or - // the location int* sizesofdimensions; do have to store type of array struct TableNode *typeofarray; } array_info; typedef struct { - // similar to above we define a record to hold the number of elements - // and an array of tablenodes (types) that it contains in the > int numofelements; struct SymbolTable *recordScope; } record_info; @@ -47,19 +34,16 @@ typedef union { primitive_info *PrimAdInfo; array_info *ArrayAdInfo; record_info *RecAdInfo; - // string_info* StringAdInfo; function_declaration_info *FunDecAdInfo; function_type_info *FunTypeAdInfo; } AdInfo; typedef struct ListOfTable { struct SymbolTable *table; - // struct ListOfTable* prev; struct ListOfTable *next; } ListOfTable; typedef struct TableNode { - // reference to the type entry that this is struct TableNode *theType; char *theName; AdInfo *additionalinfo; @@ -74,30 +58,100 @@ typedef struct SymbolTable { int Column_Number; } SymbolTable; +typedef enum { + TYPE_STRING = 1, + TYPE_ARRAY_TYPE = 2, + TYPE_RECORD_TYPE = 3, + TYPE_FUNCTION_DECLARATION = 4, + TYPE_FUNCTION_TYPE = 5, + TYPE_PRIMITIVE = 6, + TYPE_ALL_ELSE = 7, + TYPE_UNDEFINED = 8, + TYPE_RECORD = 9, + TYPE_ARRAY = 10 +} types; + +AdInfo *CreatePrimitiveInfo(int size); +int getPrimSize(TableNode *definition); +AdInfo *CreateArrayInfo(int dim, TableNode *type); +int getNumArrDim(TableNode *definition); +TableNode *getArrType(TableNode *definition); +AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope); +int getRecLength(TableNode *definition); +SymbolTable *getRecList(TableNode *definition); +TableNode *setRecSize(TableNode *tn, int n); +int getRecSize(SymbolTable *tn); +AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular); +int getStartLine(TableNode *definition); +TableNode *setStartLine(TableNode *tn, int start); +bool getAsKeyword(TableNode *definition); +TableNode *setAsKeyword(TableNode *tn, bool as); +AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype); +TableNode *getParameter(TableNode *definition); +TableNode *getReturn(TableNode *definition); SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column); +SymbolTable *init(SymbolTable *start); +TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info); +int getAdInfoType(TableNode *tn); +TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, + AdInfo *ad); +char *getType(TableNode *tn); +char *getName(TableNode *tn); +int getLine(SymbolTable *st); +int getColumn(SymbolTable *st); +TableNode *addName(TableNode *tn, char *str); +SymbolTable *setLineNumber(SymbolTable *st, int line); +SymbolTable *setColumnNumber(SymbolTable *st, int column); TableNode *table_lookup(SymbolTable *table, char *x); TableNode *look_up(SymbolTable *table, char *x); void print_symbol_table(SymbolTable *table, FILE *file_ptr); - SymbolTable *getAncestor(SymbolTable *table); +SymbolTable *removeEntry(SymbolTable *scope, char *search); +bool typeCheck(char *firstID, char *secondID); SymbolTable *getParent(SymbolTable *st); ListOfTable *getChildren(SymbolTable *st); SymbolTable *getFirstChild(ListOfTable *lt); ListOfTable *getRestOfChildren(ListOfTable *lt); TableNode *getFirstEntry(SymbolTable *st); TableNode *getNextEntry(TableNode *tn); -SymbolTable *init(SymbolTable *scope); -int getPrimSize(TableNode *definition); -int getNumArrDim(TableNode *definition); -TableNode *getArrType(TableNode *definition); -int getRecLength(TableNode *definition); -SymbolTable *getRecList(TableNode *definition); -int getStartLine(TableNode *definition); -bool getAsKeyword(TableNode *definition); -TableNode *getParameter(TableNode *definition); -TableNode *getReturn(TableNode *definition); -char *getType(TableNode *tn); -char *getName(TableNode *tn); -int getLine(SymbolTable *st); -int getColumn(SymbolTable *st); +void printdebug_impl(char *file, int line, const char *format, ...); +#define printdebug(format, ...) \ + printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) + +extern int yylex(void); +extern char *yytext; +extern int yyleng; +extern int yychar; +extern SymbolTable *cur; +extern int line_number; +extern int column_number; +extern FILE *yyin; +extern bool DEBUG; + +extern TableNode *funprime; +extern TableNode *arrayprim; +extern TableNode *integ; +extern TableNode *addr; +extern TableNode *chara; +extern TableNode *stri; +extern TableNode *boo; +extern TableNode *recprime; +extern TableNode *funtypeprime; +extern TableNode *undefined; + +extern char *COLOR_RED; +extern char *COLOR_GREEN; +extern char *COLOR_ORANGE; +extern char *COLOR_BLUE; +extern char *COLOR_PURPLE; +extern char *COLOR_CYAN; +extern char *COLOR_LIGHTGRAY; +extern char *COLOR_DARKGRAY; +extern char *COLOR_LIGHTRED; +extern char *COLOR_LIGHTGREEN; +extern char *COLOR_YELLOW; +extern char *COLOR_LIGHTBLUE; +extern char *COLOR_LIGHTPURPLE; +extern char *COLOR_LIGHTCYAN; +extern char *COLOR_WHITE; \ No newline at end of file From d1aa7f7e0f570d7ac63e687039f8f0cb88e93fe7 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 4 Apr 2025 15:42:50 -0400 Subject: [PATCH 38/38] =?UTF-8?q?Ready=20for=20Dev!=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/grammar.y | 18 ++++++++-- src/runner.c | 14 ++++++-- src/symbol_table.c | 55 ++++++++++++++--------------- tests/sprint2/test/sp2_llnode.alpha | 1 + 4 files changed, 55 insertions(+), 33 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 63f2034..7b925f6 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -196,7 +196,7 @@ definition: printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); } else { for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)) { - CreateEntry(cur, entry, NULL, NULL); + CreateEntry(cur, entry->theType, NULL, NULL); } } } @@ -258,8 +258,11 @@ idlist: sblock: L_BRACE { - if (getLine(cur) != 0 && getColumn(cur)) { + if (getLine(cur) != 0) { cur = CreateScope(cur,@1.first_line,@1.first_column); + } else { + setLineNumber(cur, @1.first_line); + setColumnNumber(cur,@1.first_line); } } statement_list @@ -288,7 +291,16 @@ sblock: dblock: - L_BRACKET declaration_list R_BRACKET; + L_BRACKET + { + if(getLine(cur)==0) { + setLineNumber(cur, @1.first_line); + setColumnNumber(cur,@1.first_line); + } else { + cur = CreateScope(cur,@1.first_line,@1.first_column); + } + } + declaration_list R_BRACKET; diff --git a/src/runner.c b/src/runner.c index 5f903c3..578fa22 100644 --- a/src/runner.c +++ b/src/runner.c @@ -134,7 +134,16 @@ int run(FILE *alpha) { if (st_flag != NULL) { yyparse(); - print_symbol_table(getAncestor(cur), st_flag); + + if (cur == NULL) { + printdebug("%s[FATAL] cur is null", COLOR_LIGHTRED); + } + + if (top == NULL) { + printdebug("%s[FATAL] top is null", COLOR_LIGHTRED); + } + + print_symbol_table(top, st_flag); fclose(st_flag); if (yyin != NULL) { fclose(yyin); @@ -144,7 +153,8 @@ int run(FILE *alpha) { yyparse(); FILE *f = fdopen(1, "w"); - print_symbol_table(getAncestor(cur), f); + + print_symbol_table(top, f); fclose(f); if (yyin != NULL) { diff --git a/src/symbol_table.c b/src/symbol_table.c index f458769..f749b00 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -186,7 +186,7 @@ int getRecSize(SymbolTable *tn) { "passed in NULL SymbolTable for getRecSize. Invalid"); return -1; } - int s = 0; + int s = 1; TableNode *cur = getFirstEntry(tn); if (cur != NULL) { while (getNextEntry(cur) != NULL) { @@ -772,7 +772,6 @@ TableNode *look_up(SymbolTable *table, char *x) { } void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - if (table == NULL) { printdebug( "%s[FATAL] passed in NULL table to print_symbol_table", @@ -781,14 +780,14 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } if (table->Parent_Scope == NULL) { - fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", + fprintf(file_ptr, "%-25s: %-6s : %-6s : %-25s: %-30s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); } TableNode *entrie = table->entries; - fprintf(file_ptr, "-----------------:--------:--------:----------------" - "------:---------" - "--------------------\n"); + fprintf(file_ptr, + "-------------------------:--------:--------:------------------" + "--------:------------------------------\n"); int parant_scope = 0; int current_scope = 0; if (table->Parent_Scope != NULL) { @@ -800,7 +799,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { current_scope = 1001; } if (entrie == NULL) { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", + fprintf(file_ptr, "%-25s: %06d : %06d : %-25s: %-30s\n", "", current_scope, parant_scope, "", "Empty Scope"); } for (; entrie != NULL; entrie = getNextEntry(entrie)) { @@ -808,8 +807,8 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (parant_scope == 0) { fprintf(file_ptr, - "%-17s: %06d : : %-21d -> " - "%-21s: %-28s\n", + "%-25s: %06d : : %d -> %-20s: " + "%-30s\n", entrie->theName, current_scope, entrie->additionalinfo->ArrayAdInfo ->numofdimensions, @@ -818,8 +817,8 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { "Type of Array"); } else { fprintf(file_ptr, - "%-17s: %06d : %06d : %-21d -> %-21s: " - "%-28s\n", + "%-25s: %06d : : %d -> %-20s: " + "%-30s\n", entrie->theName, current_scope, parant_scope, entrie->additionalinfo->ArrayAdInfo @@ -833,16 +832,16 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (parant_scope == 0) { fprintf(file_ptr, - "%-17s: %06d : :%-21s: " - "elements-%-28d\n", + "%-25s: %06d : : %-25s: " + "elements-%-30d\n", entrie->theName, current_scope, "record", entrie->additionalinfo->RecAdInfo ->numofelements); } else { fprintf(file_ptr, - "%-17s: %06d : %06d : %-21s: " - "elements-%-28d\n", + "%-25s: %06d : %06d : %-25s: " + "elements-%-30d\n", entrie->theName, current_scope, parant_scope, "record", entrie->additionalinfo->RecAdInfo @@ -854,14 +853,14 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf( file_ptr, - "%-17s: %06d : :%-21s: size-%-28d " + "%-25s: %06d : : %-25s: size-%d " "bytes\n", entrie->theName, current_scope, "Primitive", entrie->additionalinfo->PrimAdInfo->size); } else { fprintf( file_ptr, - "%-17s: %06d : %06d : %-21s: size-%-28d " + "%-25s: %06d : %06d : %-25s: size-%-30d " "bytes\n", entrie->theName, current_scope, parant_scope, "Primitive", @@ -872,8 +871,8 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (parant_scope == 0) { fprintf(file_ptr, - "%-17s: %06d : : %-21s -> " - "%-21s: %-28s\n", + "%-25s: %06d : : %-25s -> " + "%-25s: %-30s\n", entrie->theName, current_scope, entrie->additionalinfo->FunTypeAdInfo ->parameter->theName, @@ -882,8 +881,8 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { "Type of Function"); } else { fprintf(file_ptr, - "%-17s: %06d : %06d : %-21s -> %-21s: " - "%-28s\n", + "%-25s: %06d : %06d : %-25s -> %-21s: " + "%-30s\n", entrie->theName, current_scope, parant_scope, entrie->additionalinfo->FunTypeAdInfo @@ -897,12 +896,12 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (parant_scope == 0) { fprintf(file_ptr, - "%-17s: %06d : :%-21s: %-28s\n", + "%-25s: %06d : : %-25s: %-30s\n", entrie->theName, current_scope, getType(entrie), "User Defined"); } else { fprintf(file_ptr, - "%-17s: %06d : %06d : %-21s: %-28s\n", + "%-25s: %06d : %06d : %-25s: %-30s\n", entrie->theName, current_scope, parant_scope, getType(entrie), "User Defined"); @@ -912,12 +911,12 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (parant_scope == 0) { fprintf(file_ptr, - "%-17s: %06d : :%-21s: %-28s\n", + "%-25s: %06d : : %-25s: %-30s\n", entrie->theName, current_scope, "undefined", "undefined entry"); } else { fprintf(file_ptr, - "%-17s: %06d : %06d : %-21s: %-28s\n", + "%-25s: %06d : %06d : %-25s: %-30s\n", entrie->theName, current_scope, parant_scope, "undefined", "undefined entry"); @@ -940,9 +939,9 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } } if (getParent(table) == NULL) { - fprintf(file_ptr, "-----------------:--------:--------:--------" - "--------------:-------" - "----------------------\n"); + fprintf(file_ptr, + "-------------------------:--------:--------:----------" + "----------------:------------------------------\n"); } } // get top most symbol table diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index 6b4912e..43007ef 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -9,6 +9,7 @@ function foo : T1 function bar1 : T2 function bar2 : T2 function make_list : list + make_list(a) := { [integer:orig_a; address: ret; address: curr; address: temp] if (a < 0 | a = 0) then {