2020-09-10 00:56:16 +00:00
|
|
|
|
|
|
|
/*************/
|
|
|
|
/*GEMWIRE */
|
|
|
|
/* ERYTHRO*/
|
|
|
|
/*************/
|
|
|
|
|
|
|
|
#include <Defs.h>
|
|
|
|
#include <Data.h>
|
|
|
|
|
|
|
|
static int GlobalSymbols = 0;
|
|
|
|
|
2020-11-25 17:03:33 +00:00
|
|
|
|
|
|
|
int FindSymbolImpl(char* Symbol, int Storage) {
|
2020-09-10 00:56:16 +00:00
|
|
|
int Ind;
|
|
|
|
|
2020-11-27 21:16:50 +00:00
|
|
|
for(Ind = (Storage == SC_GLOBAL /* Are we global scope? */
|
|
|
|
? 0 /* If so, start from the beginning */
|
|
|
|
: CurrentLocal + 1 /* Else, go from the start of the local block */
|
|
|
|
);
|
|
|
|
Ind < (Storage == SC_GLOBAL /* Are we global scope? */
|
2020-11-25 17:03:33 +00:00
|
|
|
? CurrentGlobal /* If so, start searching at the start */
|
|
|
|
: SYMBOLS /* Otherwise, start at the end and work backward */
|
2020-11-27 21:16:50 +00:00
|
|
|
);
|
|
|
|
Ind++) {
|
2021-01-17 06:37:39 +00:00
|
|
|
if(Storage == SC_GLOBAL && Symbols[Ind].Storage == SC_PARAM) continue; // Skip searching globals for parameters.
|
2020-11-27 21:16:50 +00:00
|
|
|
if(*Symbol == *Symbols[Ind].Name && !strcmp(Symbol, Symbols[Ind].Name)) {
|
|
|
|
printf("\t\tFound %s at %d\r\n", Symbol, Ind);
|
2020-09-10 00:56:16 +00:00
|
|
|
return Ind;
|
2020-11-27 21:16:50 +00:00
|
|
|
}
|
2020-09-10 00:56:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2020-11-25 17:03:33 +00:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
2020-09-10 00:56:16 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
2020-11-25 17:03:33 +00:00
|
|
|
* The death condition here is running into the local symbol table.
|
2020-09-10 00:56:16 +00:00
|
|
|
* //TODO: Dump symbols on death?
|
|
|
|
*/
|
2020-11-25 17:03:33 +00:00
|
|
|
static int NewGlobalSymbol() {
|
2020-09-10 00:56:16 +00:00
|
|
|
int Pos;
|
|
|
|
|
2020-11-27 21:16:50 +00:00
|
|
|
if((Pos = (CurrentGlobal++)) >= CurrentLocal) {
|
|
|
|
printf("%d:%d\r\n", CurrentGlobal, CurrentLocal);
|
2020-11-25 17:03:33 +00:00
|
|
|
Die("Too many Global symbols");
|
2020-11-27 21:16:50 +00:00
|
|
|
}
|
2020-09-10 00:56:16 +00:00
|
|
|
|
|
|
|
return Pos;
|
|
|
|
}
|
|
|
|
|
2020-11-25 17:03:33 +00:00
|
|
|
/*
|
|
|
|
* 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");
|
2020-11-18 20:49:08 +00:00
|
|
|
|
2020-11-25 17:03:33 +00:00
|
|
|
return Pos;
|
2020-09-10 00:56:16 +00:00
|
|
|
}
|
|
|
|
|
2021-01-17 06:37:39 +00:00
|
|
|
/*
|
|
|
|
* Reset the local counter on functions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void FreeLocals() {
|
|
|
|
CurrentLocal = SYMBOLS - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-11-25 17:03:33 +00:00
|
|
|
/*
|
|
|
|
* 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) {
|
2020-09-10 00:56:16 +00:00
|
|
|
|
|
|
|
int TableSlot;
|
2020-11-25 17:03:33 +00:00
|
|
|
int SinkOffset = 0;
|
2020-09-10 00:56:16 +00:00
|
|
|
|
2021-01-17 06:37:39 +00:00
|
|
|
if((TableSlot = FindSymbolImpl(Name, Storage)) != -1)
|
|
|
|
return -1;
|
2020-09-10 00:56:16 +00:00
|
|
|
|
2020-11-25 17:03:33 +00:00
|
|
|
// Instaed of spliting this up into AddLocalSymbol and AddGlobalSymbol,
|
|
|
|
// we can use this switch to avoid duplicated code.
|
|
|
|
switch(Storage) {
|
2021-01-17 06:37:39 +00:00
|
|
|
case SC_PARAM:
|
|
|
|
// Instead of special casing parameters, we can just add these to the symbol lists and be done with it.
|
|
|
|
printf("\tPreparing new parameter %s of type %s\r\n", Name, TypeNames[Type]);
|
|
|
|
TableSlot = AddSymbol(Name, Type, Structure, SC_GLOBAL, 88, 1);
|
|
|
|
Symbols[TableSlot].Storage = SC_PARAM; // Fix the parameter after running the global process
|
|
|
|
TableSlot = AddSymbol(Name, Type, Structure, SC_LOCAL, 88, 1);
|
|
|
|
Symbols[TableSlot].Storage = SC_PARAM; // Fix the parameter after running the local process
|
|
|
|
return TableSlot;
|
2020-11-25 17:03:33 +00:00
|
|
|
case SC_GLOBAL:
|
|
|
|
TableSlot = NewGlobalSymbol();
|
|
|
|
break;
|
|
|
|
case SC_LOCAL:
|
2020-11-27 21:16:50 +00:00
|
|
|
printf("\tCreating new local symbol %s\r\n", Name);
|
2020-11-25 17:03:33 +00:00
|
|
|
TableSlot = NewLocalSymbol();
|
2021-01-17 06:37:39 +00:00
|
|
|
SinkOffset = AsCalcOffset(Type);
|
2020-11-25 17:03:33 +00:00
|
|
|
break;
|
|
|
|
}
|
2020-09-10 00:56:16 +00:00
|
|
|
|
|
|
|
Symbols[TableSlot].Name = strdup(Name);
|
|
|
|
Symbols[TableSlot].Type = Type;
|
|
|
|
Symbols[TableSlot].Structure = Structure;
|
2020-11-25 17:03:33 +00:00
|
|
|
Symbols[TableSlot].Storage = Storage;
|
|
|
|
Symbols[TableSlot].Length = Length;
|
|
|
|
Symbols[TableSlot].SinkOffset = SinkOffset;
|
2021-01-17 06:37:39 +00:00
|
|
|
Symbols[TableSlot].EndLabel = EndLabel;
|
2020-09-10 00:56:16 +00:00
|
|
|
|
2020-11-30 20:01:00 +00:00
|
|
|
// NOTE: Generating global symbol names must happen AFTER the name and type are declared.
|
|
|
|
switch(Storage) {
|
|
|
|
case SC_GLOBAL:
|
|
|
|
printf("\tCreating new global symbol %s into slot %d\r\n", Name, TableSlot);
|
2021-01-17 06:37:39 +00:00
|
|
|
if(Structure != ST_FUNC && EndLabel != 88) { // Magic keyword so that we don't generate ASM globals for parameters
|
2020-11-30 20:01:00 +00:00
|
|
|
printf("\t\tGenerating data symbol.\r\n");
|
|
|
|
AsGlobalSymbol(TableSlot);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SC_LOCAL:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-09-10 00:56:16 +00:00
|
|
|
//printf("Adding new variable %s of type %s to the table at %d\n", CurrentIdentifier, Types[Type], TableSlot);
|
|
|
|
return TableSlot;
|
|
|
|
}
|