diff --git a/include/Defs.h b/include/Defs.h index e2c2ee4..09e96cd 100644 --- a/include/Defs.h +++ b/include/Defs.h @@ -325,7 +325,7 @@ struct ASTNode* PrintStatement(void); int FindSymbol(char* Symbol); -int AddSymbol(char* Name, int Type, int Structure, int Size); +int AddSymbol(char* Name, int Type, int Structure, int Storage, int EndLabel, int Length); int AddFunctionSymbol(char* Name, int Type, int Structure, int EndLabel, int Size); diff --git a/src/Symbols.c b/src/Symbols.c index 267e02d..20366b1 100644 --- a/src/Symbols.c +++ b/src/Symbols.c @@ -9,15 +9,15 @@ static int GlobalSymbols = 0; -/* - * Find the position of a symbol in the symbol table. - * @Return the index into the symbol table if found, - * -1 if not found. - */ -int FindSymbol(char* Symbol) { + +int FindSymbolImpl(char* Symbol, int Storage) { int Ind; - for(Ind = 0; Ind < GlobalSymbols; Ind++) { + for(Ind = 0; Ind < (Storage == SC_GLOBAL /* Are we global scope? */ + ? CurrentGlobal /* If so, start searching at the start */ + : SYMBOLS /* Otherwise, start at the end and work backward */ + ); Ind++) { + if(*Symbol == *Symbols[Ind].Name && !strcmp(Symbol, Symbols[Ind].Name)) return Ind; } @@ -25,50 +25,93 @@ int FindSymbol(char* Symbol) { return -1; } +/* + * Find the position of a symbol in the symbol table. + * @Return the index into the symbol table if found, + * -1 if not found. + * Does not care about differentiating local or global. + * It will only be consistent. + */ +int FindSymbol(char* Symbol) { + int Res; + // Prioritise local vars + if((Res = FindSymbolImpl(Symbol, SC_LOCAL)) == -1) + // Fallback to global vars. + return FindSymbolImpl(Symbol, SC_GLOBAL); + return Res; +} + /* * Append a new entry to the table of global symbols. * @Return the index to the new entry * * Will kill the program if we run out. + * The death condition here is running into the local symbol table. * //TODO: Dump symbols on death? */ -static int NewSymbol(void) { +static int NewGlobalSymbol() { int Pos; - if((Pos = GlobalSymbols++) >= SYMBOLS) - Die("Too many symbols"); + if((Pos = (CurrentGlobal++)) >= CurrentLocal) + Die("Too many Global symbols"); return Pos; } -// TODO: this is going weird! +/* + * Append a new entry to the table of local (function-local) symbols. + * @Return the index to the new entry + * + * Will kill the program if we run out. + * The death condition here is running into the global symbol table. + * //TODO: Dump symbols on death? + */ +static int NewLocalSymbol() { + int Pos; + if((Pos = (CurrentLocal--)) <= CurrentGlobal) + Die("Too many Local symbols"); -int AddArraySymbol(char* Name, int Type, int Structure, int EndLabel, int Size) { - int Slot; - Slot = AddFunctionSymbol(Name, Type, Structure, EndLabel, Size); - return Slot; + return Pos; } -int AddFunctionSymbol(char* Name, int Type, int Structure, int EndLabel, int Size) { - int Slot; - Slot = AddSymbol(Name, Type, Structure, Size); - Symbols[Slot].EndLabel = EndLabel; - return Slot; -} - -int AddSymbol(char* Name, int Type, int Structure, int Size) { +/* + * Add a symbol to the tables, and set all the metadata. + * @param Name: The string representing the name of the symbol. + * @param Type: The return type in terms of DataTypes enum values. + * @param Structure: The type of symbol this is, in terms of StructureType enum. + * @param Storage: The storage scope of this symbol. For functions this is always SC_GLOBAL (for now). Vars and Arrays can be GLOBAL or SC_LOCAL. + * @param EndLabel: The label # to jump to to exit the function or array, where appropriate. + * @param Length: The size of the struct/array in units of 1xbase + * + * @return The ID in the symbol table that now represents this symbol. + */ +int AddSymbol(char* Name, int Type, int Structure, int Storage, int EndLabel, int Length) { int TableSlot; + int SinkOffset = 0; - if((TableSlot = FindSymbol(Name) != -1)) + if((TableSlot = FindSymbol(Name, Storage) != -1)) return TableSlot; - TableSlot = NewSymbol(); + // Instaed of spliting this up into AddLocalSymbol and AddGlobalSymbol, + // we can use this switch to avoid duplicated code. + switch(Storage) { + case SC_GLOBAL: + TableSlot = NewGlobalSymbol(); + AsGlobalSymbol(TableSlot); + break; + case SC_LOCAL: + TableSlot = NewLocalSymbol(); + SinkOffset = AsCalcOffset(Type, 0); + break; + } Symbols[TableSlot].Name = strdup(Name); Symbols[TableSlot].Type = Type; Symbols[TableSlot].Structure = Structure; - Symbols[TableSlot].Length = Size; + Symbols[TableSlot].Storage = Storage; + Symbols[TableSlot].Length = Length; + Symbols[TableSlot].SinkOffset = SinkOffset; //printf("Adding new variable %s of type %s to the table at %d\n", CurrentIdentifier, Types[Type], TableSlot); return TableSlot;