diff --git a/Makefile b/Makefile index fe8f769..8649a5c 100644 --- a/Makefile +++ b/Makefile @@ -41,9 +41,8 @@ test-s1: test-s2: chmod +x ./check.sh - $(foreach test, $(TESTS-S2), ./$(EXE) -tok $(test);) + $(foreach test, $(TESTS-S2), ./$(EXE) -st $(test);) ./check.sh - $(foreach test, $(TESTS-S2), ./$(EXE) $(test);) clean: rm -f *.o diff --git a/check.sh b/check.sh index b8b138c..f325421 100755 --- a/check.sh +++ b/check.sh @@ -5,6 +5,11 @@ # The Translators - Spring 2025 # TOK_DIR="out" +RED='\033[0;31m' +GREEN='\033[0;32m' +WHITE='\033[0m' +PURPLE='\033[0;35m' +ORANGE='\033[0;33m' if [[ ! -d "$TOK_DIR" ]]; then echo "Directory $TOK_DIR does not exist." @@ -19,9 +24,15 @@ for file in "$TOK_DIR"/*; do exp="./tests/sprint$num/expected/$filename.expected" if [[ -f "$exp" ]]; then - echo -e "--------------------------------------------" - echo -e "Checking $file...\n" - diff --color=always "$file" "$exp" - echo -e "--------------------------------------------\n" + 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 diff --git a/src/grammar.y b/src/grammar.y index 3e9bc44..758b35d 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -2,21 +2,30 @@ /* 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; + #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; %} //%define api.location.type {location_t} %locations @@ -26,6 +35,9 @@ } +%type assignable +%type expression +%type constant %type id_or_types %type types %token ID 101 @@ -34,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 @@ -110,7 +122,9 @@ definition: TYPE ID COLON dblock | TYPE ID COLON constant ARROW ID | function_declaration - | TYPE ID COLON id_or_types ARROW id_or_types + | 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 ; @@ -143,7 +157,7 @@ declaration_list: ; declaration: - id_or_types COLON ID {CreateEntry(cur,$1,$3); } + id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } ; id_or_types: @@ -179,23 +193,33 @@ rec_op : DOT expression: - - constant {printf("constant expression\n");} - | SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");} - | NOT expression {printf("not expression\n");} + 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");} | expression SUB_OR_NEG expression {printf("subtract expression\n");} | expression MUL expression {printf("multiply expression\n");} | expression DIV expression {printf("division expression\n");} | expression REM expression {printf("remainder expression\n");} + | expression AND expression {printf("and expression\n");} + | expression OR expression {printf("or expression\n");} - | expression LESS_THAN expression {printf("less than expression\n");} - | expression EQUAL_TO expression {printf("equals check expression\n");} - | assignable {printf("assignable expression\n");} - | L_PAREN expression R_PAREN {printf("paren expression\n");} - | memOp assignable - ; + + | 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|| + 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");} + ; ablock: @@ -215,17 +239,18 @@ memOp: constant: - C_STRING - | C_INTEGER - | C_NULL - | C_CHARACTER - | C_TRUE - | C_FALSE + C_STRING {$$ = $1;} + | C_INTEGER {$$ = $1;} + | C_NULL {$$ = $1;} + | C_CHARACTER {$$ = $1;} + | C_TRUE {$$ = $1;} + | C_FALSE {$$ = $1;} ; -types: - 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;} +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;} @@ -234,31 +259,5 @@ types: %% 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\n", err,yytext,yylloc.first_line,yylloc.first_column); } -/* -int main(int argc, char * argv[]) { - token_tracker = 1; - cur=CreateScope(NULL,1,1); - //int a; - FILE * fp; - if(argc > 1){ - fp = fopen(argv[1], "r"); - yyin = fp; - } else { - fp = stdin; - yyin = fp; - } - yyparse(); - //while ((a = yyparse() != EOF){ - // token_tracker++; - //printf("%d = a: yytext = %s: yychar = %d, token number: %d\n", a, yytext, yychar,token_tracker); - //if(yytext[0] == '\n'){ - FILE* f = fdopen(1,"w"); - print_symbol_table(getAncestor(cur),f); - fclose(f); - // break; - //} - //} - return 0; -} */ diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index eac2840..24eaa78 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -72,9 +72,9 @@ 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(yytext);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);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);return C_STRING;}} +{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;}} +'{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;*/}} "(" {if(DEBUG) {printf( "L_PAREN: %s (%d)\n", yytext, L_PAREN);} else {if(tok_flag != NULL){print_tok(L_PAREN);}incr(line_number,column_number,L_PAREN);return L_PAREN;}} @@ -84,9 +84,9 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "{" {if(DEBUG) {printf( "L_BRACE: %s (%d)\n", yytext, L_BRACE);} else {if(tok_flag != NULL){print_tok(L_BRACE);}incr(line_number,column_number,L_BRACE);return L_BRACE;}} "}" {if(DEBUG) {printf( "R_BRACE: %s (%d)\n", yytext, R_BRACE);} else {if(tok_flag != NULL){print_tok(R_BRACE);}incr(line_number,column_number,R_BRACE);return R_BRACE;}} -"true" {if(DEBUG) {printf( "C_TRUE: %s (%d)\n", yytext, C_TRUE);} else {if(tok_flag != NULL){print_tok(C_TRUE);}incr(line_number,column_number,C_TRUE);yylval.words = strdup(yytext);return C_TRUE;}} -"false" {if(DEBUG) {printf( "C_FALSE: %s (%d)\n", yytext, C_FALSE);} else {if(tok_flag != NULL){print_tok(C_FALSE);}incr(line_number,column_number,C_FALSE);yylval.words = strdup(yytext);return C_FALSE;}} -"null" {if(DEBUG) {printf( "C_NULL: %s (%d)\n", yytext, C_NULL);} else {if(tok_flag != NULL){print_tok(C_NULL);}incr(line_number,column_number,C_NULL);yylval.words = strdup(yytext);return C_NULL;}} +"true" {if(DEBUG) {printf( "C_TRUE: %s (%d)\n", yytext, C_TRUE);} else {if(tok_flag != NULL){print_tok(C_TRUE);}incr(line_number,column_number,C_TRUE);yylval.words = strdup("Boolean");return C_TRUE;}} +"false" {if(DEBUG) {printf( "C_FALSE: %s (%d)\n", yytext, C_FALSE);} else {if(tok_flag != NULL){print_tok(C_FALSE);}incr(line_number,column_number,C_FALSE);yylval.words = strdup("Boolean");return C_FALSE;}} +"null" {if(DEBUG) {printf( "C_NULL: %s (%d)\n", yytext, C_NULL);} else {if(tok_flag != NULL){print_tok(C_NULL);}incr(line_number,column_number,C_NULL);yylval.words = strdup("address");return C_NULL;}} {ID} {if(DEBUG) {printf( "ID: %s (%d)\n", yytext, ID);} else {if(tok_flag != NULL){print_tok(ID);}incr(line_number,column_number,ID);yylval.words = strdup(yytext); return ID;}} diff --git a/src/runner.c b/src/runner.c index 2110d23..68198f8 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2,6 +2,13 @@ /* 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; int main(int argc, char *argv[]) { if (argc == 1) { @@ -22,13 +29,16 @@ int main(int argc, char *argv[]) { } else { - if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) != 0) { + if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) != + 0) { fprintf(stderr, INVALID); return -1; } else { for (int i = 1; i < argc - 1; i++) { if (check_flag(argv[i], argv[argc - 1]) != 0) { - fprintf(stderr, "INVALID FLAG(S): Use -help to view valid inputs \n"); + fprintf(stderr, + "INVALID FLAG(S): Use -help to " + "view valid inputs \n"); return -1; } } @@ -57,25 +67,26 @@ int check_flag(char *arg, char *alpha) { } } -void incr(int lnum,int cnum, int tok){ - //if (tok == COMMENT) { - for (int i = 0; i < yyleng; i++) { - if (yytext[i] == '\n') { - line_number++; - column_number = 0; - } - column_number++; - } -// }else{ -// column_number += yyleng; -// } +void incr(int lnum, int cnum, int tok) { + // if (tok == COMMENT) { + for (int i = 0; i < yyleng; i++) { + if (yytext[i] == '\n') { + line_number++; + column_number = 0; + } + column_number++; + } + // }else{ + // column_number += yyleng; + // } } -void print_tok(int tok){ -fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number,tok, yytext); +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 = CreateScope(NULL, 1, 1); + top = cur = init(CreateScope(NULL, 1, 1)); // If file is not found if (alpha == NULL) { @@ -87,10 +98,11 @@ int run(FILE *alpha) { // TOK FLAG if (tok_flag != NULL) { while (0 != (token = yylex())) { - //if (tok_flag != NULL) { - // fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number, - // token, yytext); - //} + // if (tok_flag != NULL) { + // fprintf(tok_flag, "%d %d %3d \"%s\"\n", + // line_number, column_number, + // token, yytext); + // } /*if (token == COMMENT) { for (int i = 0; i < yyleng; i++) { if (yytext[i] == '\n') { @@ -103,9 +115,10 @@ int run(FILE *alpha) { } if (token == 1999) { printf( - "On line number %d and column number %d we have an invalid " - "character:%s\n", - line_number, column_number, yytext); + "On line number %d and column + number %d we have an invalid " "character:%s\n", + line_number, column_number, + yytext); } column_number += yyleng; */ } @@ -118,8 +131,13 @@ int run(FILE *alpha) { } if (st_flag != NULL) { - // output symbol table, file pointer is - // print_symbol_table(top,st_flag); + yyparse(); + print_symbol_table(getAncestor(cur), st_flag); + fclose(st_flag); + if (yyin != NULL) { + fclose(yyin); + } + return 0; } yyparse(); @@ -165,14 +183,15 @@ int new_file(char *arg, char *alpha) { } else if (strcmp(arg, "-st") == 0) { type_len = ST_LEN; } else { - fprintf(stderr, "INVALID FLAG: Use -help to view valid inputs\n"); + fprintf(stderr, + "INVALID FLAG: Use -help to view valid inputs\n"); return -1; } // calculate lengths int basename_len = strlen(basename); char *file_name = - calloc(basename_len - ALPHA_OFFSET + type_len + 2, sizeof(char)); + calloc(basename_len - ALPHA_OFFSET + type_len + 2, sizeof(char)); // coy filename and add extension strncpy(file_name, basename, basename_len - ALPHA_OFFSET); @@ -188,15 +207,14 @@ int new_file(char *arg, char *alpha) { } int is_alpha_file(char *alpha, int file_len) { - if (strcmp(".alpha", alpha + sizeof(char) * (file_len - ALPHA_OFFSET)) != 0) { - return -1; // not alpha file + if (strcmp(".alpha", + alpha + sizeof(char) * (file_len - ALPHA_OFFSET)) != 0) { + return -1; // not alpha file } - return 0; // is alpha file + return 0; // is alpha file } -void enter_scope(int line, int column) { - cur = CreateScope(cur, line, column); -} +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"); diff --git a/src/runner.h b/src/runner.h index 9f66407..d378be5 100644 --- a/src/runner.h +++ b/src/runner.h @@ -5,14 +5,18 @@ #define TOK_LEN 3 #define ST_LEN 2 #define HELP \ - "HELP:\nHow to run the alpha compiler:\n./alpha [options] program\nValid " \ - "options:\n-tok output the token number, token, line number, and column " \ - "number for each of the tokens to the .tok file\n-st output the symbol " \ - "table for the program to the .st file\n-help print this message and exit " \ - "the alpha compiler\n" + "HELP:\nHow to run the alpha compiler:\n./alpha [options] " \ + "program\nValid " \ + "options:\n-tok output the token number, token, line number, and " \ + "column " \ + "number for each of the tokens to the .tok file\n-st output the " \ + "symbol " \ + "table for the program to the .st file\n-help print this message " \ + "and exit " \ + "the alpha compiler\n" #define SET_FLAG 1 // Used to set flags for arg types -#define INVALID \ - "INVALID INPUT: Include a .alpha file or use -help for more inputs \n" +#define INVALID \ + "INVALID INPUT: Include a .alpha file or use -help for more inputs \n" #include #include @@ -22,7 +26,7 @@ #include "../tmp/flex.h" #include "symbol_table.h" -//#include "typedefs.h" +// #include "typedefs.h" #include "../tmp/grammar.tab.h" extern int line_number, column_number; diff --git a/src/symbol_table.c b/src/symbol_table.c index 4369551..205bcbe 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -6,10 +6,244 @@ #include #include #include -char * typey = "type"; -char * funy = "function"; -SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { - SymbolTable* table = (SymbolTable*)malloc(sizeof(SymbolTable)); +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; + +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, + // Array can be multidimensional. Information should be stored here + TYPE_ARRAY, + // Record is user defined types + TYPE_RECORD, + // Declaring what type a particular function is without as + TYPE_FUNCTION_DECLARATION, + // 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, + // The Type being pointed to by the first 4 above that only stores the + // size + TYPE_PRIMITIVE, + //likely NULL + TYPE_ALL_ELSE + +} 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) { + + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->PrimAdInfo = (primitive_info *)malloc(sizeof(primitive_info)); + info->PrimAdInfo->size = size; + return info; +} + +// only gets the size of a primitive type +int getPrimSize(TableNode *definition) { + if (strcmp(getType(definition), "primitive") != 0) { + printf("not checking the size of a primitive -- invalid op\n"); + return 0; + } + 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 *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->ArrayAdInfo = (array_info *)malloc(sizeof(array_info)); + info->ArrayAdInfo->numofdimensions = dim; + info->ArrayAdInfo->typeofarray = type; + // avoiding storing any types like below + // int* dimensionsizes = loc; + return info; +} +// This gets the number of dimensions from array info +int getNumArrDim(TableNode *definition) { + if (strcmp(getType(definition), "array") != 0) { + printf("not checking the dim of an array -- invalid op\n"); + return 0; + } + return definition->additionalinfo->ArrayAdInfo->numofdimensions; +} +// 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 (strcmp(getType(definition), "array") != 0) { + printf("not checking the type of an array -- invalid op\n"); + return NULL; + } + return definition->additionalinfo->ArrayAdInfo->typeofarray; +} + +// Record type currently stores the number of elements as well as the types, in +// order, of what make up that type in an array. Unfortunately this second part +// should probably instead be replaced by a reference to a scope in which those +// elements are found. +AdInfo *CreateRecordInfo(int length, TableNode *typesarray) { + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->RecAdInfo = (record_info *)malloc(sizeof(record_info)); + info->RecAdInfo->numofelements = length; + // replace below with reference to a scope, not an array + info->RecAdInfo->listoftypes = typesarray; + return info; +} +// This gets the number of elements that make up a record. +// Perhaps this may not be needed since we need to iterate over all elements +// anyways. +int getRecLength(TableNode *definition) { + if (strcmp(getType(definition), "record") != 0) { + printf("not checking the length of an record -- invalid op\n"); + return 0; + } + return definition->additionalinfo->RecAdInfo->numofelements; +} +// This gets the array. Needs to up be updated to get the scope instead +TableNode *getRecList(TableNode *definition) { + if (strcmp(getType(definition), "record") != 0) { + printf("not checking the list of types of a record -- invalid " + "op\n"); + return NULL; + } + return definition->additionalinfo->RecAdInfo->listoftypes; +} + +// 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 +// multiple inputs Below function also has the line number where the function is +// first defined +AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->FunDecAdInfo = (function_declaration_info *)malloc( + sizeof(function_declaration_info)); + info->FunDecAdInfo->startlinenumber = line; + info->FunDecAdInfo->regularoras = asorregular; + return info; +} +// 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) { + printf("not checking the start line of a function -- invalid " + "op\n"); + return 0; + } + return definition->additionalinfo->FunDecAdInfo->startlinenumber; +} +// 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) { + printf("not checking if a function is called with as or not -- " + "invalid op\n"); + return NULL; + } + return definition->additionalinfo->FunDecAdInfo->regularoras; +} +// stores the type of a function (parameter type and return type) +AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->FunTypeAdInfo = + (function_type_info *)malloc(sizeof(function_type_info)); + info->FunTypeAdInfo->parameter = parameter; + info->FunTypeAdInfo->returntype = returntype; + return info; +} +// returns parameter type of a function +TableNode *getParameter(TableNode *definition) { + if (strcmp(getType(definition), "function type primitive") != 0) { + printf( + "not checking the parameter of a function -- invalid op\n"); + return NULL; + } + return definition->additionalinfo->FunTypeAdInfo->parameter; +} +// returns return type of a function +TableNode *getReturn(TableNode *definition) { + if (strcmp(getType(definition), "function type primitive") != 0) { + printf("not checking the return of a function -- invalid op\n"); + return NULL; + } + return definition->additionalinfo->FunTypeAdInfo->returntype; +} + +// creates a new scope (not the top scope though) +SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column) { + SymbolTable *table = (SymbolTable *)malloc(sizeof(SymbolTable)); table->Line_Number = Line; table->Column_Number = Column; table->Parent_Scope = ParentScope; @@ -17,16 +251,18 @@ SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { table->entries = NULL; if (ParentScope != NULL) { if (ParentScope->Children_Scope == NULL) { - ListOfTable* newEntry = (ListOfTable*)malloc(sizeof(ListOfTable)); + ListOfTable *newEntry = + (ListOfTable *)malloc(sizeof(ListOfTable)); newEntry->next = NULL; // newEntry->prev = NULL; newEntry->table = table; ParentScope->Children_Scope = newEntry; } else { - ListOfTable* newEntry = (ListOfTable*)malloc(sizeof(ListOfTable)); + ListOfTable *newEntry = + (ListOfTable *)malloc(sizeof(ListOfTable)); // newEntry->prev = NULL; newEntry->table = table; - ListOfTable* oldEntry = ParentScope->Children_Scope; + ListOfTable *oldEntry = ParentScope->Children_Scope; ParentScope->Children_Scope = newEntry; newEntry->next = oldEntry; } @@ -34,38 +270,190 @@ SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { return table; } -//create entry just for things below top level scope -TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id) { +// create entry just for things below top level scope +// This function defines the integer, address, character, and bool primitive +// types +SymbolTable *init(SymbolTable *start) { + if (start->Parent_Scope != NULL) { + printf( + "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)); + // TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); + start->entries = integ; + integ->next = addr; + addr->next = chara; + chara->next = stri; + stri->next = boo; + // boo->next = arr; + boo->next = NULL; -if(table ==NULL /*|| table->Parent_Scope == NULL*/){ - printf("Null reference to table given for create entry or given top level scope which is invalid\n"); - return NULL; + integ->theName = "integer"; + addr->theName = "address"; + chara->theName = "character"; + boo->theName = "Boolean"; + stri->theName = "string"; + // arr->theName= "array" + + // root TableNode that all are pointing to but not in table + // This is only to solve the issue that all entries must have a name and + // a type and the type must point to an actual table entry Again, this + // primitive table entry isn't in the top scope. It is outside the top + // scope and is only there to facilitate the fact that these are + // primitive + TableNode *prime = (TableNode *)malloc(sizeof(TableNode)); + prime->theName = "primitive"; + prime->theType = NULL; + prime->additionalinfo = NULL; + prime->next = NULL; + + // not sure exatly how to get array types to look right so using a dummy + // Table Node below and updating the print symbol table function to + // access the additional information to print for array types, similar + // to function types when printing symbol table, if array is seen + arrayprim = (TableNode *)malloc(sizeof(TableNode)); + arrayprim->theName = "array"; + arrayprim->theType = NULL; + arrayprim->additionalinfo = NULL; + prime->next = NULL; + + // funprime = CreateEntry(NULL,NULL,strdup("function primitive"),NULL); + + // similar workaround to arrays above + funprime = (TableNode *)malloc(sizeof(TableNode)); + funprime->theName = "primitive function"; + funprime->theType = NULL; + funprime->additionalinfo = NULL; + funprime->next = NULL; + + // record + recprime = (TableNode *)malloc(sizeof(TableNode)); + recprime->theName = "record"; + recprime->theType = NULL; + recprime->additionalinfo = NULL; + recprime->next = NULL; + + funtypeprime = (TableNode *)malloc(sizeof(TableNode)); + funtypeprime->theName = "primitive function type"; + funtypeprime->theType = NULL; + funtypeprime->additionalinfo = NULL; + funtypeprime->next = NULL; + + integ->theType = prime; + addr->theType = prime; + chara->theType = prime; + stri->theType = arrayprim; + boo->theType = prime; + // arr->theType=arrayprim; + + // filling in all the values for the additional info for initial types + // These numbers below for create primitive specifically are supposed to + // be the size of these primitive types. We can change these if needed + // to not be hard coded numbers as a reminder, stri below is defined as + // a one dimensional array of characters + integ->additionalinfo = CreatePrimitiveInfo(4); + addr->additionalinfo = CreatePrimitiveInfo(8); + chara->additionalinfo = CreatePrimitiveInfo(1); + stri->additionalinfo = CreateArrayInfo(1, chara); + boo->additionalinfo = CreatePrimitiveInfo(1); + // addr->additionalinfo = CreatePrimitiveInfo(8); + + start->Line_Number = 1; + start->Column_Number = 1; + start->Parent_Scope = NULL; + start->Children_Scope = NULL; + + return start; } -/*TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); -if(topDef == NULL){ - printf("This type is not defined at the top level\n"); - return NULL; -}*/ - TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode)); - //newEntry->theType = topDef->theName; - newEntry->theType=typeOf; - 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; - } +/* +TableNode* integ; +TableNode* addr; +TableNode* chara; +TableNode* stri; +TableNode* boo; +TableNode* recprime; +TableNode* funtypeprime; +*/ + +int getAdInfoType(TableNode* tn){ + if(strcmp(getType(tn),getName(integ))==0){ + return TYPE_PRIMITIVE; + } + if(strcmp(getType(tn),getName(addr))==0){ + return TYPE_PRIMITIVE; + } + if(strcmp(getType(tn),getName(chara))==0){ + return TYPE_PRIMITIVE; + } + if(strcmp(getType(tn),getName(stri))==0){ + return TYPE_ARRAY; + } + if(strcmp(getType(tn),getName(boo))==0){ + return TYPE_PRIMITIVE; + } + if(strcmp(getType(tn),getName(recprime))==0){ + return TYPE_RECORD; + } + if(strcmp(getType(tn),getName(funtypeprime))==0){ + return TYPE_FUNCTION_TYPE; + } + if(strcmp(getType(tn),getName(arrayprim))==0){ + return TYPE_ARRAY; + } + else{ + return TYPE_FUNCTION_DECLARATION; + } } +TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, + AdInfo *ad) { + + if (table == NULL) { + printf("Null reference to table"); + return NULL; + } + /* + TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); + if(topDef == NULL){ + printf("This type is not defined at the top level\n"); + return NULL; + } + */ + if (typeOf == NULL) { + printf("This is not pointing to a proper definition\n"); + return NULL; + } + TableNode *newEntry = (TableNode *)malloc(sizeof(TableNode)); + newEntry->theType = typeOf /*topDef*/; + newEntry->theName = id; + newEntry->additionalinfo = ad; + if (table->entries == NULL) { + table->entries = newEntry; + return newEntry; + } else { + TableNode *oldEntry = table->entries; + table->entries = newEntry; + newEntry->next = oldEntry; + return newEntry; + } +} + +char *getType(TableNode *tn) { return tn->theType->theName; } +char *getName(TableNode *tn) { return tn->theName; } +int getLine(SymbolTable *st) { return st->Line_Number; } +int getColumn(SymbolTable *st) { return st->Column_Number; } + +/* //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"); - return NULL; + printf("No valid table given for header defs\n"); + return NULL; } @@ -73,14 +461,14 @@ if(table ==NULL || table->Parent_Scope != NULL){ //possible issues with referencing text instead of heap if(typeOf == 0){ - newEntry->theType = typey; + newEntry->theType = typey; } if (typeOf == 1){ - newEntry->theType = funy; + newEntry->theType = funy; } if(table_lookup(table,id) != NULL){ - printf("already defined at the top level, can't define duplicate names\n"); - return NULL; + printf("already defined at the top level, can't define duplicate +names\n"); return NULL; } newEntry->theName = id; if (table->entries == NULL) { @@ -94,9 +482,9 @@ if(table_lookup(table,id) != NULL){ } } - -TableNode* table_lookup(SymbolTable* table, char* x) { - TableNode* entrie = table->entries; +*/ +TableNode *table_lookup(SymbolTable *table, char *x) { + TableNode *entrie = table->entries; for (; entrie != NULL; entrie = entrie->next) { if (!strcmp(entrie->theName, x)) { return entrie; @@ -104,63 +492,71 @@ TableNode* table_lookup(SymbolTable* table, char* x) { } return NULL; } -TableNode* look_up(SymbolTable* table, char* x) { +TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { return NULL; } - TableNode* ret = table_lookup(table, x); + TableNode *ret = table_lookup(table, x); if (ret != NULL) { return ret; } return look_up(table->Parent_Scope, x); } -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"); + fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", + "SCOPE", "PARENT", "TYPE", "Extra annotation"); } - TableNode* entrie = table->entries; - fprintf(file_ptr, - "-----------------:--------:--------:----------------------:---------" - "--------------------\n"); + 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; + 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"); + 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) { - fprintf(file_ptr, "%-17s: %06d : : %-21s: %-28s\n", - entrie->theName, current_scope, entrie->theType, - "Extra annotation"); + /*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, "Extra annotation"); + 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; + 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, "-----------------:--------:--------:--------" + "--------------:-------" + "----------------------\n"); } } -SymbolTable* getAncestor(SymbolTable* table) { +SymbolTable *getAncestor(SymbolTable *table) { if (table->Parent_Scope == NULL) { // if table has no parent, return itself return table; @@ -170,17 +566,78 @@ SymbolTable* getAncestor(SymbolTable* table) { } } -SymbolTable* getParent(SymbolTable* st) { return st->Parent_Scope; } +SymbolTable *removeEntry(SymbolTable *scope, char *search) { -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; } -char* getType(TableNode* tn) { return tn->theType; } -char* getName(TableNode* tn) { return tn->theName; } -int getLine(SymbolTable* st) { return st->Line_Number; } -int getColumn(SymbolTable* st) { return st->Column_Number; } + if (scope == NULL) { + return NULL; + } + if (scope->entries == NULL) { + return scope; + } + + TableNode *prev = NULL; + TableNode *now = scope->entries; + + while (now != NULL) { + if (strcmp(getName(now), search) == 0) { + if (prev == NULL) { + scope->entries = getNextEntry(now); + return scope; + } else { + prev->next = now->next; + return scope; + } + } + prev = now; + now = now->next; + } + return scope; +} + +bool typeCheck(char *firstID, char *secondID) { + + TableNode *entry1 = look_up(cur, firstID); + TableNode *entry2 = look_up(cur, secondID); + if (entry1 == NULL) { + printf("first type not defined\n"); + return false; + } + if (entry2 == NULL) { + printf("second type not defined\n"); + return false; + } + if (table_lookup(getAncestor(cur), getType(look_up(cur, firstID))) == + table_lookup(getAncestor(cur), getType(look_up(cur, secondID)))) { + if (strcmp(getType(look_up(cur, firstID)), "array") == 0) { + if (look_up(cur, firstID) + ->additionalinfo->ArrayAdInfo + ->numofdimensions == + look_up(cur, secondID) + ->additionalinfo->ArrayAdInfo + ->numofdimensions && + look_up(cur, firstID) + ->additionalinfo->ArrayAdInfo + ->typeofarray == + look_up(cur, secondID) + ->additionalinfo->ArrayAdInfo + ->typeofarray) { + return true; + } else { + return false; + } + } + return true; + } + return false; +} + +SymbolTable *getParent(SymbolTable *st) { return st->Parent_Scope; } + +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; } // uncomment the below main function along with the headers above for a simple // standalone test of table and entry creation diff --git a/src/symbol_table.h b/src/symbol_table.h index 03028ad..84b3e5a 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -3,40 +3,101 @@ #include #include +struct TableNode; + +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 TableNode *listoftypes; +} record_info; + +typedef struct { + int startlinenumber; + bool regularoras; +} function_declaration_info; + +typedef struct { + struct TableNode *parameter; + struct TableNode *returntype; +} function_type_info; + +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 SymbolTable *table; // struct ListOfTable* prev; - struct ListOfTable* next; + struct ListOfTable *next; } ListOfTable; typedef struct TableNode { - char* theType; - char* theName; - struct TableNode* next; + // reference to the type entry that this is + struct TableNode *theType; + char *theName; + AdInfo *additionalinfo; + struct TableNode *next; } TableNode; typedef struct SymbolTable { - TableNode* entries; - struct SymbolTable* Parent_Scope; - struct ListOfTable* Children_Scope; + TableNode *entries; + struct SymbolTable *Parent_Scope; + struct ListOfTable *Children_Scope; int Line_Number; int Column_Number; } SymbolTable; -SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column); -TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id); -TableNode* table_lookup(SymbolTable* table, char* x); -TableNode* look_up(SymbolTable* table, char* x); -void print_symbol_table(SymbolTable* table, FILE* file_ptr); +SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, 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* getParent(SymbolTable* st); -ListOfTable* getChildren(SymbolTable* st); -SymbolTable* getFirstChild(ListOfTable* lt); -ListOfTable* getRestOfChildren(ListOfTable* lt); -TableNode* getFirstEntry(SymbolTable* st); -TableNode* getNextEntry(TableNode* tn); -char* getType(TableNode* tn); -char* getName(TableNode* tn); -int getLine(SymbolTable* st); -int getColumn(SymbolTable* st); +SymbolTable *getAncestor(SymbolTable *table); +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); +TableNode *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); diff --git a/tests/sprint1/expected/sp1_comment_fix1.expected b/tests/sprint1/expected/sp1_comment_fix1.expected index 07d66e1..de45b77 100644 --- a/tests/sprint1/expected/sp1_comment_fix1.expected +++ b/tests/sprint1/expected/sp1_comment_fix1.expected @@ -1 +1 @@ - daskmskdfm \ No newline at end of file +1 1 700 "(***)" diff --git a/tests/sprint1/expected/sp1_comment_fix2.expected b/tests/sprint1/expected/sp1_comment_fix2.expected new file mode 100644 index 0000000..e094e9b --- /dev/null +++ b/tests/sprint1/expected/sp1_comment_fix2.expected @@ -0,0 +1,3 @@ +1 1 700 "(*(**)" +1 7 603 "*" +1 8 502 ")" diff --git a/tests/sprint1/expected/sp1_comment_issues.expected b/tests/sprint1/expected/sp1_comment_issues.expected new file mode 100644 index 0000000..0e3c0b8 --- /dev/null +++ b/tests/sprint1/expected/sp1_comment_issues.expected @@ -0,0 +1,22 @@ +1 1 700 "(*(**)" +1 7 603 "*" +1 8 502 ")" +2 1 700 "(***)" +3 1 700 "(******)" +3 9 700 "(*\kpp*********)" +4 1 501 "(" +4 2 700 "(*((*)" +4 8 502 ")" +5 1 700 "(***)" +5 6 700 "(*) +(* *)" +7 1 700 "(***)" +7 6 502 ")" +7 7 502 ")" +7 8 502 ")" +7 9 502 ")" +7 10 502 ")" +7 11 502 ")" +7 12 603 "*" +7 13 700 "(*))))))))*)" +7 25 502 ")" diff --git a/tests/sprint1/expected/sp1_comments.expected b/tests/sprint1/expected/sp1_comments.expected new file mode 100644 index 0000000..0486ed9 --- /dev/null +++ b/tests/sprint1/expected/sp1_comments.expected @@ -0,0 +1,9 @@ +1 1 700 "(* hello *)" +2 1 700 "(* hello *)" +3 1 700 "(* I'd think this is a legal "string" that contains several \n \t +escaped characters, isn't it? *)" +5 1 700 "(* \ *)" +6 1 700 "(* *)" +7 1 700 "(*{COMMENT}+ *)" +8 1 700 "(* * *)" +9 1 700 "(* (hello) *)" diff --git a/tests/sprint1/expected/sp1_general_token.expected b/tests/sprint1/expected/sp1_general_token.expected new file mode 100644 index 0000000..d50bac7 --- /dev/null +++ b/tests/sprint1/expected/sp1_general_token.expected @@ -0,0 +1,68 @@ +1 1 101 "This" +1 6 101 "is" +1 9 101 "a" +1 11 101 "test" +2 1 301 "9" +2 2 101 "combined" +2 11 301 "7" +2 12 101 "okens" +3 1 301 "12345" +4 1 301 "893247892" +5 1 101 "combined" +5 10 101 "DueToUnknownChar" +5 27 101 "_validtoken" +5 39 101 "__validtoken1" +5 53 101 "_valid_token2" +5 67 101 "validToken3_" +6 1 305 "true" +6 6 306 "false" +7 1 302 "null" +7 6 401 "while" +7 12 609 "!" +7 13 101 "wrong" +7 19 402 "if" +7 22 101 "when" +8 1 404 "else" +8 6 405 "type" +8 11 406 "function" +9 1 407 "return" +9 9 408 "external" +9 25 409 "as" +10 1 101 "string" +10 8 101 "_NOte_that_was_not_reserved" +11 1 501 "(" +11 2 503 "[" +11 3 502 ")" +11 4 504 "]" +11 5 505 "{" +11 6 506 "}" +11 7 508 ":" +11 8 507 ";" +11 9 509 "," +11 10 510 "->" +12 1 601 "+" +12 2 602 "-" +12 3 603 "*" +12 4 604 "/" +12 5 605 "%" +13 1 606 "<" +13 2 607 "=" +14 1 608 ":=" +15 2 101 "This" +15 7 101 "is" +15 10 101 "not" +15 14 101 "a" +15 16 101 "valid" +16 1 101 "String" +17 1 304 ""This is a valid String"" +18 1 609 "!" +18 2 611 "|" +19 1 612 "." +19 2 612 "." +20 1 700 "(* this is a comment *)" +21 1 501 "(" +21 2 603 "*" +21 3 101 "Not" +21 7 101 "a" +21 9 101 "comment" +22 3 610 "&" diff --git a/tests/sprint1/expected/sp1_keywords.expected b/tests/sprint1/expected/sp1_keywords.expected new file mode 100644 index 0000000..9e70321 --- /dev/null +++ b/tests/sprint1/expected/sp1_keywords.expected @@ -0,0 +1,29 @@ +1 1 401 "while" +2 1 101 "While" +3 1 101 "whiLe" +4 1 402 "if" +5 1 101 "IF" +6 1 101 "If" +7 1 101 "iF" +8 1 403 "then" +9 1 101 "Then" +10 1 101 "theN" +11 1 404 "else" +12 1 101 "eLse" +13 1 101 "elSe" +14 1 101 "Else" +15 1 405 "type" +16 1 101 "Type" +17 1 101 "tyPe" +18 1 406 "function" +19 1 101 "Function" +20 1 101 "functioN" +21 1 407 "return" +22 1 101 "Return" +23 1 101 "returN" +24 1 408 "external" +25 1 101 "External" +26 1 101 "exteRnal" +27 1 409 "as" +28 1 101 "As" +29 1 101 "aS" diff --git a/tests/sprint1/expected/sp1_operators.expected b/tests/sprint1/expected/sp1_operators.expected new file mode 100644 index 0000000..dd3eaab --- /dev/null +++ b/tests/sprint1/expected/sp1_operators.expected @@ -0,0 +1,22 @@ +1 1 601 "+" +2 1 602 "-" +3 1 603 "*" +4 1 604 "/" +6 1 605 "%" +7 1 606 "<" +9 1 607 "=" +10 1 608 ":=" +11 1 607 "=" +11 2 508 ":" +12 1 508 ":" +13 1 607 "=" +14 1 609 "!" +15 1 610 "&" +16 1 611 "|" +17 1 612 "." +18 1 101 "relEASE" +19 1 614 "release" +20 1 101 "RELEASE" +21 1 613 "reserve" +22 1 101 "RESERVE" +23 1 101 "reSERVe" diff --git a/tests/sprint1/expected/sp1_other_punc.expected b/tests/sprint1/expected/sp1_other_punc.expected new file mode 100644 index 0000000..7500378 --- /dev/null +++ b/tests/sprint1/expected/sp1_other_punc.expected @@ -0,0 +1,7 @@ +1 1 507 ";" +2 1 508 ":" +3 1 509 "," +4 1 510 "->" +5 1 510 "->" +6 1 602 "-" +6 2 510 "->" diff --git a/tests/sprint1/expected/sp1_punc_grouping.expected b/tests/sprint1/expected/sp1_punc_grouping.expected new file mode 100644 index 0000000..c58a316 --- /dev/null +++ b/tests/sprint1/expected/sp1_punc_grouping.expected @@ -0,0 +1,59 @@ +1 1 502 ")" +2 1 101 "a" +2 2 502 ")" +3 1 502 ")" +3 2 101 "a" +4 1 502 ")" +4 2 603 "*" +5 1 603 "*" +5 2 502 ")" +7 1 700 "(* jellsls + well this seems to work + + + *)" +13 1 501 "(" +14 1 101 "a" +14 2 501 "(" +15 1 501 "(" +15 2 101 "a" +16 1 501 "(" +16 2 603 "*" +17 1 603 "*" +17 2 501 "(" +20 1 505 "{" +21 1 101 "a" +21 2 505 "{" +22 1 505 "{" +22 2 101 "a" +23 1 505 "{" +23 2 603 "*" +24 1 603 "*" +24 2 505 "{" +25 1 506 "}" +26 1 101 "a" +26 2 506 "}" +27 1 506 "}" +27 2 101 "a" +28 1 506 "}" +28 2 603 "*" +29 1 603 "*" +29 2 506 "}" +33 1 503 "[" +34 1 101 "a" +34 2 503 "[" +35 1 503 "[" +35 2 101 "a" +36 1 503 "[" +36 2 603 "*" +37 1 603 "*" +37 2 503 "[" +38 1 504 "]" +39 1 101 "a" +39 2 504 "]" +40 1 504 "]" +40 2 101 "a" +41 1 504 "]" +41 2 603 "*" +42 1 603 "*" +42 2 504 "]" diff --git a/tests/sprint1/expected/sp1_real_alpha_file1.expected b/tests/sprint1/expected/sp1_real_alpha_file1.expected new file mode 100644 index 0000000..cc3f2c9 --- /dev/null +++ b/tests/sprint1/expected/sp1_real_alpha_file1.expected @@ -0,0 +1,145 @@ +1 1 405 "type" +1 6 101 "rec" +1 9 508 ":" +1 11 503 "[" +1 12 201 "integer" +1 19 508 ":" +1 21 101 "x" +1 22 507 ";" +1 24 201 "integer" +1 31 508 ":" +1 33 101 "y" +1 34 504 "]" +2 1 405 "type" +2 6 101 "T1" +2 8 508 ":" +2 10 201 "integer" +2 18 510 "->" +2 21 201 "integer" +3 1 405 "type" +3 6 101 "T2" +3 8 508 ":" +3 10 101 "rec" +3 14 510 "->" +3 17 201 "integer" +4 1 406 "function" +4 10 101 "foo" +4 14 508 ":" +4 16 101 "T1" +5 1 406 "function" +5 10 101 "bar1" +5 15 508 ":" +5 17 101 "T2" +6 1 406 "function" +6 10 101 "bar2" +6 15 508 ":" +6 17 101 "T2" +7 1 101 "foo" +7 4 501 "(" +7 5 101 "x" +7 6 502 ")" +7 8 608 ":=" +7 11 505 "{" +8 2 407 "return" +8 9 101 "x" +8 11 603 "*" +8 13 101 "x" +8 14 507 ";" +9 9 506 "}" +10 1 101 "bar1" +10 5 501 "(" +10 6 101 "a" +10 7 502 ")" +10 9 608 ":=" +10 12 505 "{" +11 9 407 "return" +11 16 101 "a" +11 17 612 "." +11 18 101 "x" +11 20 603 "*" +11 22 101 "a" +11 23 612 "." +11 24 101 "y" +11 25 507 ";" +12 9 506 "}" +13 1 101 "bar2" +13 6 409 "as" +13 9 501 "(" +13 10 101 "r" +13 11 509 "," +13 12 101 "s" +13 13 502 ")" +13 15 608 ":=" +13 18 505 "{" +14 9 407 "return" +14 16 101 "r" +14 18 603 "*" +14 20 101 "s" +14 21 507 ";" +15 9 506 "}" +16 1 101 "entry" +16 6 501 "(" +16 7 101 "arg" +16 10 502 ")" +16 12 608 ":=" +16 15 505 "{" +17 9 503 "[" +17 11 201 "integer" +17 18 508 ":" +17 20 101 "result" +17 27 507 ";" +17 29 101 "rec" +17 32 508 ":" +17 34 101 "w" +17 35 504 "]" +18 9 101 "result" +18 16 608 ":=" +18 19 101 "foo" +18 22 501 "(" +18 23 301 "5" +18 24 502 ")" +18 25 507 ";" +19 9 101 "w" +19 11 608 ":=" +19 14 613 "reserve" +19 21 501 "(" +19 22 101 "w" +19 23 502 ")" +19 24 507 ";" +19 26 700 "(* see types.alpha – reserve returns a value of type address, + which can be assigned to array and record variables + *)" +22 9 101 "w" +22 10 612 "." +22 11 101 "x" +22 13 608 ":=" +22 16 301 "5" +22 17 507 ";" +23 9 101 "w" +23 10 612 "." +23 11 101 "y" +23 13 608 ":=" +23 16 301 "7" +23 17 507 ";" +24 9 101 "result" +24 16 608 ":=" +24 19 101 "bar1" +24 23 501 "(" +24 24 101 "w" +24 25 502 ")" +24 26 507 ";" +24 28 700 "(* pass w (a rec type value) to bar1 *)" +25 9 101 "result" +25 16 608 ":=" +25 19 101 "bar2" +25 23 501 "(" +25 24 301 "5" +25 25 509 "," +25 26 301 "7" +25 27 502 ")" +25 28 507 ";" +25 30 700 "(* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *)" +27 9 407 "return" +27 16 301 "0" +27 17 507 ";" +28 1 506 "}" diff --git a/tests/sprint1/expected/sp1_real_alpha_file2.expected b/tests/sprint1/expected/sp1_real_alpha_file2.expected new file mode 100644 index 0000000..90c34a2 --- /dev/null +++ b/tests/sprint1/expected/sp1_real_alpha_file2.expected @@ -0,0 +1,100 @@ +1 1 700 "(* Type definitions *)" +2 1 405 "type" +2 6 101 "string" +2 12 508 ":" +2 14 301 "1" +2 16 510 "->" +2 19 204 "character" +3 1 405 "type" +3 6 101 "int2int" +3 13 508 ":" +3 15 201 "integer" +3 23 510 "->" +3 26 201 "integer" +4 1 405 "type" +4 6 101 "string2int" +4 16 508 ":" +4 18 101 "string" +4 25 510 "->" +4 28 201 "integer" +5 1 700 "(* Function prototypes +They use the above type definitions +*)" +8 1 406 "function" +8 10 101 "square" +8 17 508 ":" +8 19 101 "int2int" +9 1 406 "function" +9 10 101 "entry" +9 16 508 ":" +9 18 101 "string2int" +10 1 700 "(* Function definition +Functions must be declared before they are defined +*)" +13 1 101 "square" +13 7 501 "(" +13 8 101 "x" +13 9 502 ")" +13 11 608 ":=" +13 14 505 "{" +14 1 407 "return" +14 8 101 "x" +14 10 603 "*" +14 12 101 "x" +14 13 507 ";" +15 1 506 "}" +16 1 700 "(* Function definition +entry is the first function called +*)" +19 1 101 "entry" +19 6 501 "(" +19 7 101 "arg" +19 10 502 ")" +19 12 608 ":=" +19 15 505 "{" +20 1 101 "input" +20 7 607 "=" +20 9 301 "7" +20 10 507 ";" +21 1 101 "expected" +21 10 607 "=" +21 12 301 "49" +21 14 507 ";" +22 1 101 "actual" +22 8 608 ":=" +22 11 101 "square" +22 17 501 "(" +22 18 101 "input" +22 23 502 ")" +22 24 507 ";" +23 1 101 "rseult" +23 8 608 ":=" +23 11 101 "expected" +23 20 607 "=" +23 22 101 "actual" +23 28 507 ";" +24 1 407 "return" +24 8 301 "0" +24 9 507 ";" +25 1 503 "[" +25 3 201 "integer" +25 10 508 ":" +25 12 101 "input" +25 17 507 ";" +25 19 201 "integer" +25 26 508 ":" +25 28 101 "expected" +25 36 507 ";" +25 38 201 "integer" +25 45 508 ":" +25 47 101 "actual" +25 53 507 ";" +25 55 101 "boolean" +25 62 508 ":" +25 64 101 "result" +25 70 507 ";" +25 72 101 "string" +25 78 508 ":" +25 80 101 "input" +25 86 504 "]" +26 1 506 "}" diff --git a/tests/sprint1/expected/sp1_simple_int.expected b/tests/sprint1/expected/sp1_simple_int.expected new file mode 100644 index 0000000..0bcbefb --- /dev/null +++ b/tests/sprint1/expected/sp1_simple_int.expected @@ -0,0 +1,8 @@ +1 1 301 "45" +2 1 301 "123" +3 1 301 "8392" +4 1 301 "40" +4 4 301 "40" +5 2 301 "200" +5 6 301 "50" +5 9 301 "21783" diff --git a/tests/sprint1/expected/sp1_simple_literals.expected b/tests/sprint1/expected/sp1_simple_literals.expected new file mode 100644 index 0000000..788adc2 --- /dev/null +++ b/tests/sprint1/expected/sp1_simple_literals.expected @@ -0,0 +1,64 @@ +1 1 304 ""this is a string"" +1 20 301 "721398" +1 27 303 "'g'" +1 32 604 "/" +1 33 101 "n" +1 36 700 "(* should print 3 tokens before this *)" +4 1 301 "12893" +4 8 101 "this" +4 13 101 "is" +4 16 101 "not" +4 20 101 "a" +4 22 101 "string" +4 29 700 "(*one valid token before this*)" +5 1 700 "(* spacey comment here +over multiple lines +will it work? *)" +7 18 306 "false" +11 1 306 "false" +12 1 700 "(**)" +14 1 101 "nullfalse" +15 2 101 "nulltrue" +16 1 302 "null" +17 1 303 "'7'" +18 1 305 "true" +19 2 301 "189" +20 1 303 "'\t'" +21 1 303 "'"'" +22 1 303 "'/'" +23 1 303 "'\n'" +24 1 303 "'\''" +25 1 303 "'\t'" +26 1 303 "'\\'" +27 1 303 "'n'" +29 2 101 "fdsf" +30 1 700 "(*/jnewjno2893u86^ Lots of random characters /n /t '") *)" +35 1 304 ""STRINGwithnotSPaces"" +36 1 303 "' '" +38 1 304 ""J"" +39 1 304 """" +40 1 304 "" "" +42 1 304 ""{SCHAR}"" +43 1 304 ""SCHAR"" +44 1 304 ""[SCHAR]"" +45 1 304 ""FINAL: I'd think this is a legal \"string\" that contains \n \t several escaped characters, isn't it?"" +46 2 101 "I" +46 4 101 "d" +46 6 101 "think" +46 12 101 "this" +46 17 101 "is" +46 20 101 "a" +46 22 101 "legal" +46 30 101 "string" +46 39 101 "that" +46 44 101 "contains" +46 53 101 "several" +46 63 101 "n" +46 66 101 "t" +46 68 101 "escaped" +46 76 101 "characters" +46 86 509 "," +46 88 101 "isn" +46 92 101 "t" +46 94 101 "it" +47 1 101 "nullLike" diff --git a/tests/sprint1/expected/sp1_variables.expected b/tests/sprint1/expected/sp1_variables.expected new file mode 100644 index 0000000..223288a --- /dev/null +++ b/tests/sprint1/expected/sp1_variables.expected @@ -0,0 +1,13 @@ +1 1 101 "valid1" +2 1 101 "Valid2" +3 1 101 "_valid3" +4 1 101 "_valid_name_4" +5 1 101 "VALID" +6 1 301 "0" +6 2 101 "Invalid" +7 1 301 "1" +7 2 101 "invalid" +8 2 101 "invalid" +9 1 101 "invalid" +9 8 607 "=" +10 1 101 "String" diff --git a/tests/sprint2/other/calc.h b/tests/sprint2/other/calc.h deleted file mode 100644 index 2580e93..0000000 --- a/tests/sprint2/other/calc.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Function type. */ -typedef double (func_t) (double); -/* Data type for links in the chain of symbols. */ -struct symrec -{ - char *name; /* name of symbol */ - int type; /* type of symbol: either VAR or FUN */ - union - { - double var; /* value of a VAR */ - func_t *fun; /* value of a FUN */ - } value; - struct symrec *next; /* link field */ -}; -typedef struct symrec symrec; - -/* The symbol table: a chain of 'struct symrec'. */ -extern symrec *sym_table; - -symrec *putsym (char const *name, int sym_type); -symrec *getsym (char const *name); -struct init -{ - char const *name; - func_t *fun; -}; -struct init const funs[] = -{ - { "atan", atan }, - { "cos", cos }, - { "exp", exp }, - { "ln", log }, - { "sin", sin }, - { "sqrt", sqrt }, - { 0, 0 }, -}; -/* The symbol table: a chain of 'struct symrec'. */ -symrec *sym_table; -/* Put functions in table. */ -static void -init_table (void) -{ - for (int i = 0; funs[i].name; i++) - { - symrec *ptr = putsym (funs[i].name, FUN); - ptr->value.fun = funs[i].fun; - } -} diff --git a/tests/sprint2/other/test.c b/tests/sprint2/other/test.c deleted file mode 100644 index 0d9b343..0000000 --- a/tests/sprint2/other/test.c +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include "symbol_table.h" - -int main(void){ - char *prim = strdup("primitive"); - char *inte = strdup("integer"); - SymbolTable * parant = CreateScope(NULL, 1,1); - char *boole = strdup("Boolean"); - char *chare = strdup("character"); - char *str = strdup("string"); - char *arg = strdup("arg"); - char *one_to_char = strdup("1 -> character"); - char *int_to_int = strdup("integer -> integer"); - char *int2int = strdup("int2int"); - char *str_to_int = strdup("string -> integer"); - char *str2int = strdup("string2int"); - char *square = strdup("square"); - char *string2int = strdup("string2int"); - char *entry = strdup("entry"); - char *x = strdup("x"); - char *input = strdup("input"); - char *expected = strdup("expected"); - char *actual = strdup("actual"); - char *$_und_type = strdup("$_undefined_type"); - char *result = strdup("result"); - char *BOO = strdup("BOO"); - char *YAZOO = strdup("YAZOO"); - - CreateEntry(parant, prim, boole); - CreateEntry(parant, prim, chare); - CreateEntry(parant, prim, inte); - CreateEntry(parant, one_to_char, str); - CreateEntry(parant, int_to_int, int2int); - CreateEntry(parant, str_to_int, str2int); - CreateEntry(parant, int2int, square); - CreateEntry(parant, string2int, entry); - SymbolTable * child = CreateScope(parant, 14,14); - CreateEntry(child, inte, x); - SymbolTable * second = CreateScope(parant, 21,15); - CreateEntry(second, str, arg); - CreateEntry(second, inte, input); - CreateEntry(second, inte, expected); - CreateEntry(second, inte, actual); - CreateEntry(second, $_und_type, result); - SymbolTable * third = CreateScope(second, 33,44); - CreateEntry(third, BOO, arg); - CreateEntry(third, YAZOO, input); - - TableNode *ret = table_lookup(third, "arg"); - printf("%s == %s\n", ret->theName, "arg"); - - ret = table_lookup(third, "hello"); - printf("This should be nil %p != %s\n", ret, "BOO"); - - ret = look_up(second, "input"); - printf("%s == %s\n", ret->theName, "input"); - - ret = look_up(second, "square"); - printf("%s == %s\n", ret->theName, "square"); - - ret = look_up(second, "spuare"); - printf("This should be nil %p == %s\n", ret, "square"); - - print_symbol_table(parant, stderr); - free(inte); - free(boole); - free(prim); - free(str); - free(chare); - free(arg); - return 0; -} - diff --git a/tests/sprint2/other/testGrammar.y b/tests/sprint2/other/testGrammar.y deleted file mode 100644 index 04f8f17..0000000 --- a/tests/sprint2/other/testGrammar.y +++ /dev/null @@ -1,41 +0,0 @@ -%{ - #include /* For printf, etc. */ - #include /* For pow, used in the grammar. */ - #include "calc.h" /* Contains definition of 'symrec'. */ - int yylex (void); - void yyerror (char const *); -%} -%define api.value.type union /* Generate YYSTYPE from these types: */ -%token NUM /* Double precision number. */ -%token VAR FUN /* Symbol table pointer: variable/function. */ -%nterm exp -%precedence '=' -%left '-' '+' -%left '*' '/' -%precedence NEG /* negation--unary minus */ -%right '^' /* exponentiation */ -%% /* The grammar follows. */ -input: - %empty -| input line -; -line: - '\n' -| exp '\n' { printf ("%.10g\n", $1); } -| error '\n' { yyerrok; } -; -exp: - NUM -| VAR { $$ = $1->value.var; } -| VAR '=' exp { $$ = $3; $1->value.var = $3; } -| FUN '(' exp ')' { $$ = $1->value.fun ($3); } -| exp '+' exp { $$ = $1 + $3; } -| exp '-' exp { $$ = $1 - $3; } -| exp '*' exp { $$ = $1 * $3; } -| exp '/' exp { $$ = $1 / $3; } -| '-' exp %prec NEG { $$ = -$2; } -| exp '^' exp { $$ = pow ($1, $3); } -| '(' exp ')' { $$ = $2; } -; -/* End of grammar. */ -%%