2020-09-10 00:56:16 +00:00
|
|
|
|
|
|
|
/*************/
|
|
|
|
/*GEMWIRE */
|
|
|
|
/* ERYTHRO*/
|
|
|
|
/*************/
|
|
|
|
|
|
|
|
#include <Defs.h>
|
|
|
|
#include <Data.h>
|
|
|
|
|
2021-01-20 01:05:41 +00:00
|
|
|
/*
|
|
|
|
* Find the position of a symbol in a given symbol table.
|
|
|
|
* @param Name: The string name of the symbol
|
|
|
|
* @param List: The linked list to search in.
|
|
|
|
* @return the list if found,
|
|
|
|
* NULL if no found.
|
|
|
|
*/
|
2020-09-10 00:56:16 +00:00
|
|
|
|
2021-01-20 01:05:41 +00:00
|
|
|
static struct SymbolTableEntry* SearchList(char* Name, struct SymbolTableEntry* List) {
|
|
|
|
for(; List != NULL; List = List->NextSymbol)
|
|
|
|
if((List->Name != NULL) && !strcmp(Name, List->Name))
|
|
|
|
return (List);
|
|
|
|
return NULL;
|
2020-09-10 00:56:16 +00:00
|
|
|
}
|
|
|
|
|
2020-11-25 17:03:33 +00:00
|
|
|
/*
|
2021-01-20 01:05:41 +00:00
|
|
|
* Search all the tables for a symbol.
|
|
|
|
* Use the overrides for polluted types
|
|
|
|
* eg. if you need a global from a local scope
|
|
|
|
*
|
|
|
|
* @param Symbol: The string name of the symbol to search for
|
|
|
|
* @return the Node corresponding to the most likely
|
|
|
|
* symbol required.
|
|
|
|
*
|
|
|
|
*
|
2020-11-25 17:03:33 +00:00
|
|
|
*/
|
2021-01-20 01:05:41 +00:00
|
|
|
struct SymbolTableEntry* FindSymbol(char* Symbol) {
|
|
|
|
struct SymbolTableEntry* Node;
|
|
|
|
|
|
|
|
if(CurrentFunction) {
|
|
|
|
Node = SearchList(Symbol, FunctionEntry->Start);
|
|
|
|
if(Node)
|
|
|
|
return Node;
|
|
|
|
}
|
|
|
|
|
|
|
|
Node = SearchList(Symbol, Locals);
|
|
|
|
if(Node)
|
|
|
|
return Node;
|
|
|
|
|
|
|
|
return SearchList(Symbol, Globals);
|
2020-11-25 17:03:33 +00:00
|
|
|
}
|
|
|
|
|
2020-09-10 00:56:16 +00:00
|
|
|
/*
|
2021-01-20 01:05:41 +00:00
|
|
|
* An override for FindSymbol.
|
|
|
|
* Searches only the parameters and local variables.
|
|
|
|
* @param Symbol: The string name of the symbol to search for.
|
|
|
|
* @return a pointer to the node if found, else NULL
|
2020-09-10 00:56:16 +00:00
|
|
|
*/
|
2021-01-20 01:05:41 +00:00
|
|
|
struct SymbolTableEntry* FindLocal(char* Symbol) {
|
|
|
|
struct SymbolTableEntry* Node;
|
2020-09-10 00:56:16 +00:00
|
|
|
|
2021-01-20 01:05:41 +00:00
|
|
|
if(FunctionEntry) {
|
|
|
|
Node = SearchList(Symbol, FunctionEntry->Start);
|
|
|
|
if(Node)
|
|
|
|
return Node;
|
2020-11-27 21:16:50 +00:00
|
|
|
}
|
2021-01-20 01:05:41 +00:00
|
|
|
|
|
|
|
return SearchList(Symbol, Locals);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* An override for FindSymbol.
|
|
|
|
* Searches only the global variables.
|
|
|
|
* @param Symbol: The string name of the symbol to search for.
|
|
|
|
* @return a pointer to the node if found, else NULL
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
struct SymbolTableEntry* FindGlobal(char* Symbol) {
|
|
|
|
return SearchList(Symbol, Globals);
|
2020-09-10 00:56:16 +00:00
|
|
|
}
|
|
|
|
|
2020-11-25 17:03:33 +00:00
|
|
|
/*
|
2021-01-20 01:05:41 +00:00
|
|
|
* Given a particular linked list,
|
|
|
|
* Take Node and append it to the Tail.
|
|
|
|
*
|
|
|
|
* If there is no tail, set it to the Head.
|
|
|
|
* This prevents orphaned lists.
|
|
|
|
*
|
|
|
|
* @param Head: The start of the desired linked list
|
|
|
|
* @param Tail: The end of the desired linked list
|
|
|
|
* @param Node: The new item to append
|
2020-11-25 17:03:33 +00:00
|
|
|
*
|
|
|
|
*/
|
2021-01-20 01:05:41 +00:00
|
|
|
void AppendSymbol(struct SymbolTableEntry** Head, struct SymbolTableEntry** Tail, struct SymbolTableEntry* Node) {
|
|
|
|
if(Head == NULL || Tail == NULL || Node == NULL)
|
|
|
|
Die("Not enough data to append a symbol to the tables");
|
|
|
|
|
|
|
|
if(*Tail) {
|
|
|
|
(*Tail)->NextSymbol = Node;
|
|
|
|
*Tail = Node;
|
|
|
|
} else {
|
|
|
|
*Head = *Tail = Node;
|
|
|
|
}
|
2020-11-18 20:49:08 +00:00
|
|
|
|
2021-01-20 01:05:41 +00:00
|
|
|
Node->NextSymbol = NULL;
|
2020-09-10 00:56:16 +00:00
|
|
|
}
|
|
|
|
|
2021-01-20 01:05:41 +00:00
|
|
|
|
2021-01-17 06:37:39 +00:00
|
|
|
/*
|
2021-01-20 01:05:41 +00:00
|
|
|
* Reset the local variables of functions.
|
2021-01-17 06:37:39 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
void FreeLocals() {
|
2021-01-20 01:05:41 +00:00
|
|
|
Locals = LocalsEnd = NULL;
|
|
|
|
Params = ParamsEnd = NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reset all tables.
|
|
|
|
*/
|
|
|
|
void ClearTables() {
|
|
|
|
Globals = GlobalsEnd = NULL;
|
|
|
|
Locals = LocalsEnd = NULL;
|
|
|
|
Params = ParamsEnd = NULL;
|
2021-01-17 06:37:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-11-25 17:03:33 +00:00
|
|
|
/*
|
2021-01-20 01:05:41 +00:00
|
|
|
* Create a symbol item, and set all the metadata.
|
2020-11-25 17:03:33 +00:00
|
|
|
* @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.
|
2021-01-20 01:05:41 +00:00
|
|
|
* @param Length: The label # to jump to to exit the function or array, where appropriate.
|
|
|
|
* The size of the struct/array in units of 1xbase
|
2020-11-25 17:03:33 +00:00
|
|
|
*
|
2021-01-20 01:05:41 +00:00
|
|
|
* @return The SymbolTableEntry* pointer that corresponds to this newly constructed node.
|
2020-11-25 17:03:33 +00:00
|
|
|
*/
|
2021-01-20 01:05:41 +00:00
|
|
|
struct SymbolTableEntry* AddSymbol(char* Name, int Type, int Structure, int Storage, int Length, int SinkOffset) {
|
2020-09-10 00:56:16 +00:00
|
|
|
|
2021-01-20 01:05:41 +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;
|
2021-01-20 01:05:41 +00:00
|
|
|
} */
|
|
|
|
|
|
|
|
struct SymbolTableEntry* Node =
|
|
|
|
(struct SymbolTableEntry*) malloc(sizeof(struct SymbolTableEntry));
|
2020-09-10 00:56:16 +00:00
|
|
|
|
2021-01-20 01:05:41 +00:00
|
|
|
Node->Name = strdup(Name);
|
|
|
|
Node->Type = Type;
|
|
|
|
Node->Structure = Structure;
|
|
|
|
Node->Storage = Storage;
|
|
|
|
Node->Length = Length;
|
|
|
|
Node->SinkOffset = SinkOffset;
|
2020-09-10 00:56:16 +00:00
|
|
|
|
2021-01-20 01:05:41 +00:00
|
|
|
switch(Storage) {
|
|
|
|
case SC_GLOBAL:
|
|
|
|
AppendSymbol(&Globals, &GlobalsEnd, Node);
|
|
|
|
if(Structure != ST_FUNC) AsGlobalSymbol(Node);
|
|
|
|
break;
|
|
|
|
case SC_LOCAL:
|
|
|
|
AppendSymbol(&Locals, &LocalsEnd, Node);
|
|
|
|
break;
|
|
|
|
case SC_PARAM:
|
|
|
|
AppendSymbol(&Params, &ParamsEnd, Node);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* // NOTE: Generating global symbol names must happen AFTER the name and type are declared.
|
2020-11-30 20:01:00 +00:00
|
|
|
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;
|
2021-01-20 01:05:41 +00:00
|
|
|
} */
|
2020-11-30 20:01:00 +00:00
|
|
|
|
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);
|
2021-01-20 01:05:41 +00:00
|
|
|
return Node;
|
2020-09-10 00:56:16 +00:00
|
|
|
}
|