Compare commits

...

2 Commits

Author SHA1 Message Date
6ce26709de
Start refactoring Symbols for scoping rework 2020-11-25 17:03:33 +00:00
b540d5ef1b
Cleanup data, prepare for local vars 2020-11-25 02:11:09 +00:00
4 changed files with 85 additions and 30 deletions

View File

@ -19,7 +19,6 @@ extern_ struct SymbolTable Symbols[SYMBOLS];
extern_ int TypeSizes[9]; extern_ int TypeSizes[9];
extern_ char* TypeNames[9]; extern_ char* TypeNames[9];
extern_ char* TokenStrings[];
extern_ char* TokenNames[]; extern_ char* TokenNames[];
extern_ int CurrentFunction; extern_ int CurrentFunction;
@ -30,4 +29,7 @@ extern_ FILE* SourceFile;
extern_ FILE* OutputFile; extern_ FILE* OutputFile;
extern_ struct Token CurrentToken; extern_ struct Token CurrentToken;
extern_ char CurrentIdentifier[TEXTLEN + 1]; extern_ char CurrentIdentifier[TEXTLEN + 1];
extern_ int CurrentGlobal;
extern_ int CurrentLocal;

View File

@ -196,6 +196,17 @@ struct SymbolTable {
int Structure; // An entry in StructureType - metadata on how to process the data int Structure; // An entry in StructureType - metadata on how to process the data
int EndLabel; // The number of the label to jump to, in order to exit this function (if applicable) int EndLabel; // The number of the label to jump to, in order to exit this function (if applicable)
int Length; // The length of the symbol in units of 1 element -- the size of an array, for example. int Length; // The length of the symbol in units of 1 element -- the size of an array, for example.
int Storage; // The scope of this symbol - decides when it is discarded.
int SinkOffset; // How many times must we sink the rbp to get to this symbol in the stack?
};
enum StorageScope {
SC_GLOBAL = 1, // Global Scope
//SC_CLASS, // Class-local definitions
//SC_STATIC, // Static storage definitions
//SC_PARAM, // Function parameters
SC_LOCAL // Function-local scope.
// There is no deeper scope than function.
}; };
@ -314,7 +325,7 @@ struct ASTNode* PrintStatement(void);
int FindSymbol(char* Symbol); 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); int AddFunctionSymbol(char* Name, int Type, int Structure, int EndLabel, int Size);

View File

@ -12,7 +12,6 @@
int TypeSizes[9] = { 0, 1, 4, 8, 0, 8, 8, 8, 8}; // in BYTES int TypeSizes[9] = { 0, 1, 4, 8, 0, 8, 8, 8, 8}; // in BYTES
char* TokenStrings[] = { "+", "-", "*", "/", "int" };
char* TokenNames[] = { char* TokenNames[] = {
"End of file", "End of file",
"Equivalency", "Equivalency",

View File

@ -9,15 +9,15 @@
static int GlobalSymbols = 0; static int GlobalSymbols = 0;
/*
* Find the position of a symbol in the symbol table. int FindSymbolImpl(char* Symbol, int Storage) {
* @Return the index into the symbol table if found,
* -1 if not found.
*/
int FindSymbol(char* Symbol) {
int Ind; 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)) if(*Symbol == *Symbols[Ind].Name && !strcmp(Symbol, Symbols[Ind].Name))
return Ind; return Ind;
} }
@ -25,50 +25,93 @@ int FindSymbol(char* Symbol) {
return -1; 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. * Append a new entry to the table of global symbols.
* @Return the index to the new entry * @Return the index to the new entry
* *
* Will kill the program if we run out. * Will kill the program if we run out.
* The death condition here is running into the local symbol table.
* //TODO: Dump symbols on death? * //TODO: Dump symbols on death?
*/ */
static int NewSymbol(void) { static int NewGlobalSymbol() {
int Pos; int Pos;
if((Pos = GlobalSymbols++) >= SYMBOLS) if((Pos = (CurrentGlobal++)) >= CurrentLocal)
Die("Too many symbols"); Die("Too many Global symbols");
return Pos; 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) { return Pos;
int Slot;
Slot = AddFunctionSymbol(Name, Type, Structure, EndLabel, Size);
return Slot;
} }
int AddFunctionSymbol(char* Name, int Type, int Structure, int EndLabel, int Size) { /*
int Slot; * Add a symbol to the tables, and set all the metadata.
Slot = AddSymbol(Name, Type, Structure, Size); * @param Name: The string representing the name of the symbol.
Symbols[Slot].EndLabel = EndLabel; * @param Type: The return type in terms of DataTypes enum values.
return Slot; * @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.
int AddSymbol(char* Name, int Type, int Structure, int Size) { * @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 TableSlot;
int SinkOffset = 0;
if((TableSlot = FindSymbol(Name) != -1)) if((TableSlot = FindSymbol(Name, Storage) != -1))
return TableSlot; 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].Name = strdup(Name);
Symbols[TableSlot].Type = Type; Symbols[TableSlot].Type = Type;
Symbols[TableSlot].Structure = Structure; 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); //printf("Adding new variable %s of type %s to the table at %d\n", CurrentIdentifier, Types[Type], TableSlot);
return TableSlot; return TableSlot;