diff --git a/src/main.c b/src/main.c index f0fbd70..a94af77 100644 --- a/src/main.c +++ b/src/main.c @@ -71,7 +71,7 @@ int main(int argc, char *argv[]) { printTree(syntaxTree); } #if !NO_ANALYZE - if (!Error) { + if (!Error) { if (TraceAnalyze) fprintf(listing, "\nBuilding Symbol Table...\n"); buildSymtab(syntaxTree); if (TraceAnalyze) fprintf(listing, "\nChecking Types...\n"); diff --git a/src/symtab.c b/src/symtab.c index 2b497ab..86b9f49 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -8,115 +8,99 @@ /* Kenneth C. Louden */ /****************************************************/ +#include "symtab.h" #include #include #include -#include "symtab.h" - -/* SIZE is the size of the hash table */ -#define SIZE 211 /* SHIFT is the power of two used as multiplier in hash function */ #define SHIFT 4 /* the hash function */ -static int hash ( char * key ) -{ int temp = 0; - int i = 0; - while (key[i] != '\0') - { temp = ((temp << SHIFT) + key[i]) % SIZE; - ++i; - } - return temp; +static int hash(char *key) { + int temp = 0; + int i = 0; + while (key[i] != '\0') { + temp = ((temp << SHIFT) + key[i]) % SYMTAB_SIZE; + ++i; + } + return temp; } -/* the list of line numbers of the source - * code in which a variable is referenced - */ -typedef struct LineListRec - { int lineno; - struct LineListRec * next; - } * LineList; - -/* The record in the bucket lists for - * each variable, including name, - * assigned memory location, and - * the list of line numbers in which - * it appears in the source code - */ -typedef struct BucketListRec - { char * name; - LineList lines; - int memloc ; /* memory location for variable */ - struct BucketListRec * next; - } * BucketList; - -/* the hash table */ -static BucketList hashTable[SIZE]; +Scope curr_scope(void) { + if (top_stack == -1) { + return NULL; + } else { + return scope_stack[top_stack]; + } +} /* Procedure st_insert inserts line numbers and * memory locations into the symbol table * loc = memory location is inserted only the * first time, otherwise ignored */ -void st_insert( char * name, int lineno, int loc ) -{ int h = hash(name); - BucketList l = hashTable[h]; - while ((l != NULL) && (strcmp(name,l->name) != 0)) - l = l->next; - if (l == NULL) /* variable not yet in table */ - { l = (BucketList) malloc(sizeof(struct BucketListRec)); - l->name = name; - l->lines = (LineList) malloc(sizeof(struct LineListRec)); - l->lines->lineno = lineno; - l->memloc = loc; - l->lines->next = NULL; - l->next = hashTable[h]; - hashTable[h] = l; } - else /* found in table, so just add line number */ - { LineList t = l->lines; - while (t->next != NULL) t = t->next; - t->next = (LineList) malloc(sizeof(struct LineListRec)); - t->next->lineno = lineno; - t->next->next = NULL; - } +void st_insert(char *name, int lineno, int loc) { + int h = hash(name); + BucketList l = hashTable[h]; + while ((l != NULL) && (strcmp(name, l->name) != 0)) + l = l->next; + if (l == NULL) /* variable not yet in table */ + { + l = (BucketList) malloc(sizeof(struct BucketListRec)); + l->name = name; + l->lines = (LineList) malloc(sizeof(struct LineListRec)); + l->lines->lineno = lineno; + l->memloc = loc; + l->lines->next = NULL; + l->next = hashTable[h]; + hashTable[h] = l; + } else /* found in table, so just add line number */ + { + LineList t = l->lines; + while (t->next != NULL) t = t->next; + t->next = (LineList) malloc(sizeof(struct LineListRec)); + t->next->lineno = lineno; + t->next->next = NULL; + } } /* st_insert */ /* Function st_lookup returns the memory * location of a variable or -1 if not found */ -int st_lookup ( char * name ) -{ int h = hash(name); - BucketList l = hashTable[h]; - while ((l != NULL) && (strcmp(name,l->name) != 0)) - l = l->next; - if (l == NULL) return -1; - else return l->memloc; +int st_lookup(char *name) { + int h = hash(name); + BucketList l = hashTable[h]; + while ((l != NULL) && (strcmp(name, l->name) != 0)) + l = l->next; + if (l == NULL) return -1; + else + return l->memloc; } /* Procedure printSymTab prints a formatted * listing of the symbol table contents * to the listing file */ -void printSymTab(FILE * listing) -{ int i; - fprintf(listing,"Variable Name Location Line Numbers\n"); - fprintf(listing,"------------- -------- ------------\n"); - for (i=0;ilines; - fprintf(listing,"%-14s ",l->name); - fprintf(listing,"%-8d ",l->memloc); - while (t != NULL) - { fprintf(listing,"%4d ",t->lineno); - t = t->next; +void printSymTab(FILE *listing) { + int i; + fprintf(listing, "Variable Name Location Line Numbers\n"); + fprintf(listing, "------------- -------- ------------\n"); + for (i = 0; i < SYMTAB_SIZE; ++i) { + if (hashTable[i] != NULL) { + BucketList l = hashTable[i]; + while (l != NULL) { + LineList t = l->lines; + fprintf(listing, "%-14s ", l->name); + fprintf(listing, "%-8d ", l->memloc); + while (t != NULL) { + fprintf(listing, "%4d ", t->lineno); + t = t->next; + } + fprintf(listing, "\n"); + l = l->next; + } } - fprintf(listing,"\n"); - l = l->next; - } } - } } /* printSymTab */ diff --git a/src/symtab.h b/src/symtab.h index bf30bbf..b106908 100644 --- a/src/symtab.h +++ b/src/symtab.h @@ -1,9 +1,7 @@ /****************************************************/ /* File: symtab.h */ -/* Symbol table interface for the TINY compiler */ -/* (allows only one symbol table) */ -/* Compiler Construction: Principles and Practice */ -/* Kenneth C. Louden */ +/* Symbol table interface for the CMINUS COMPILER */ +/* Modified by Yenru0 */ /****************************************************/ #ifndef _SYMTAB_H_ @@ -11,22 +9,116 @@ #include "globals.h" -/* Procedure st_insert inserts line numbers and - * memory locations into the symbol table - * loc = memory location is inserted only the - * first time, otherwise ignored - */ -void st_insert( char * name, int lineno, int loc ); +/* SYMTAB_SIZE is the size of the hash table */ +#define SYMTAB_SIZE 211 -/* Function st_lookup returns the memory - * location of a variable or -1 if not found +/* the list of line numbers of the source + * code in which a variable is referenced */ -int st_lookup ( char * name ); +typedef struct LineListRec { + int lineno; + struct LineListRec *next; +} *LineList; -/* Procedure printSymTab prints a formatted +/* The record in the bucket lists for + * each variable, including name, + * assigned memory location, and + * the list of line numbers in which + * it appears in the source code + */ +typedef struct BucketListRec { + char *name; + TreeNode *treeNode; + LineList lines; + ExpType type; + int memloc; /* memory location for variable */ + struct BucketListRec *next; +} *BucketList; + +typedef struct ScopeListRec { + char *name; + int depth; + struct ScopeListRec *parent; + BucketList hashTable[SYMTAB_SIZE]; +} *Scope; + +Scope scope_global; + +static Scope scope_list[SYMTAB_SIZE]; +static int size_list = 0; + +static Scope scope_stack[SYMTAB_SIZE]; +static int top_stack = -1; + +/** + * create a new scope with given name + * @param scope_name: name of the scope + * @return the created scope + */ +Scope scope_new(char *scope_name); +/** + * pop the current scope from the scope stack + */ +void pop_scope(void); +/** + * push a scope into the scope stack + * @param scope: the scope to be pushed + */ +void push_scope(Scope scope); +/** + * insert a scope into the scope list + */ +void insert_scope_to_list(Scope scope); +/** + * get the top of the scope stack + * @return the current scope or NULL if the stack is empty + */ +Scope curr_scope(void); + +/** + * insert a variable into the symbol table + * or update a variable if it already exists + * @param scope_name name of the scope + * @param name name of the variable + * @param type type of the variable + * @param treeNode syntax tree node + * @param lineno line number of the variable + * @param loc memory location of the variable + * @return 0 if success, -1 if failure + */ +int st_try_insert( + char *scope_name, + char *name, + ExpType type, + TreeNode *treeNode, + int loc); + +/** + * lookup a variable in the current scope + * @param name name of the variable to lookup + * @return the bucket list entry of the variable or NULL if not found + */ +BucketList st_lookup_current(char *name); + +/** + * lookup a variable from the given scope + * @param name name of the variable to lookup + * @return the bucket list entry of the variable or NULL if not found + */ +BucketList st_lookup(char *name); + +/** + * find a scope from the scope list + * @param scope_name name of the scope to find + * @return the scope or NULL if not found + */ +Scope find_scope(char *scope_name); + +/** + * Procedure printSymTab prints a formatted * listing of the symbol table contents * to the listing file */ -void printSymTab(FILE * listing); +void printSymTab(FILE *listing); #endif