Erythro/src/Symbols.c
2023-12-08 03:12:09 +00:00

304 lines
8.4 KiB
C

/*************/
/*GEMWIRE */
/* ERYTHRO*/
/*************/
#include <Defs.h>
#include <Data.h>
/**
* Dump all symbol tables to the console.
*/
void DumpAllLists() {
printf("Initiating table dump. Expect lots of spam.\n");
printf("Global symbols:\n");
DumpList(Globals);
printf("\nLocal symbols:\n");
DumpList(Locals);
printf("\nParameters:\n");
if (CurrentFile->FunctionEntry != NULL && CurrentFile->FunctionEntry->Start != NULL)
DumpList(CurrentFile->FunctionEntry->Start);
DumpList(Params);
printf("\nStructs:\n");
DumpList(Structs);
printf("\nComposite Members:\n");
DumpList(CompositeMembers);
printf("\nEnum Members:\n");
DumpList(EnumMembers);
printf("\nUnions:\n");
DumpList(Unions);
printf("\nEnums:\n");
DumpList(Enums);
printf("\nTypes:\n");
DumpList(Types);
printf("\n\nDump over.\n");
}
/**
* Dump all the items in the list.
* Prints their names to stdout, tab separated.
*
* @param List the list to dump
*/
void DumpList(struct SymbolTableEntry* List) {
for (; List != NULL; List = List->NextSymbol)
if ((List->Name != NULL))
printf("%s\t", List->Name);
}
/*
* 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.
*/
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;
}
/*
* 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.
*
*
*/
struct SymbolTableEntry* FindSymbol(char* Symbol) {
struct SymbolTableEntry* Node;
if (CurrentFile->FunctionEntry) {
Node = SearchList(Symbol, CurrentFile->FunctionEntry->Start);
if (Node)
return Node;
}
Node = SearchList(Symbol, Locals);
if (Node)
return Node;
return SearchList(Symbol, Globals);
}
/*
* 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
*/
struct SymbolTableEntry* FindLocal(char* Symbol) {
struct SymbolTableEntry* Node;
if (CurrentFile->FunctionEntry) {
Node = SearchList(Symbol, CurrentFile->FunctionEntry->Start);
if (Node)
return Node;
}
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);
}
/*
* An override for FindSymbol.
* Searches only the defined Structs.
* @param Symbol: The string name of the symbol to search for.
* @return a pointer to the node if found, else NULL
*
*/
struct SymbolTableEntry* FindStruct(char* Symbol) {
return SearchList(Symbol, Structs);
}
/*
* An override for FindSymbol.
* Searches only the defined Enums.
* @param Symbol: The string name of the symbol to search for.
* @return a pointer to the node if found, else NULL
*
*/
struct SymbolTableEntry* FindEnum(char* Symbol) {
return SearchList(Symbol, Enums);
}
/*
* An override for FindSymbol.
* Searches only the defined enum members.
* @param Symbol: The string name of the symbol to search for.
* @return a pointer to the node if found, else NULL
*
*/
struct SymbolTableEntry* FindEnumMember(char* Symbol) {
return SearchList(Symbol, EnumMembers);
}
/*
* An override for FindSymbol.
* Searches only the defined type names.
* @param Symbol: The string name of the symbol to search for.
* @return a pointer to the node if found, else NULL
*
*/
struct SymbolTableEntry* FindAlias(char* Symbol) {
return SearchList(Symbol, Types);
}
/*
* An override for FindSymbol.
* Searches only the defined Unions.
* @param Symbol: The string name of the symbol to search for.
* @return a pointer to the node if found, else NULL
*
*/
struct SymbolTableEntry* FindUnion(char* Symbol) {
return SearchList(Symbol, Unions);
}
/*
* An override for FindSymbol.
* Searches only the defined Struct & Enum Members.
* @param Symbol: The string name of the symbol to search for.
* @return a pointer to the node if found, else NULL
*
*/
struct SymbolTableEntry* FindMember(char* Symbol) {
return SearchList(Symbol, CompositeMembers);
}
/*
* 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
*
*/
void AppendSymbol(struct SymbolTableEntry** Head, struct SymbolTableEntry** Tail, struct SymbolTableEntry* Node) {
if (Head == NULL || Tail == NULL || Node == NULL)
ErrorReport("Not enough data to append a symbol to the tables. Missing: %s\n", Head == NULL ? "Head" : Tail == NULL ? "Tail" : "Node");
if (*Tail) {
(*Tail)->NextSymbol = Node;
*Tail = Node;
} else {
*Head = *Tail = Node;
}
Node->NextSymbol = NULL;
}
/*
* Reset the local variables of functions.
*/
void FreeLocals() {
Locals = LocalsEnd = NULL;
Params = ParamsEnd = NULL;
CurrentFile->FunctionEntry = NULL;
}
/*
* Reset all tables.
*/
void ClearTables() {
Globals = GlobalsEnd = NULL;
Locals = LocalsEnd = NULL;
Params = ParamsEnd = NULL;
CompositeMembers = CompositeMembersEnd = NULL;
Structs = StructsEnd = NULL;
}
/*
* Create a symbol item, 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 Length: The label # to jump to to exit the function or array, where appropriate.
* The size of the struct/array in units of 1xbase
*
* @return The SymbolTableEntry* pointer that corresponds to this newly constructed node.
*/
struct SymbolTableEntry* AddSymbol(char* Name, int Type, int Structure, int Storage, int Length, int SinkOffset,
struct SymbolTableEntry* CompositeType) {
struct SymbolTableEntry* Node =
(struct SymbolTableEntry*) malloc(sizeof(struct SymbolTableEntry));
Node->Name = strdup(Name);
Node->Type = Type;
Node->Structure = Structure;
Node->Storage = Storage;
Node->Length = Length;
Node->SinkOffset = SinkOffset;
Node->CompositeType = CompositeType;
if (TypeIsPtr(Type) || TypeIsInt(Type))
Node->Size = Length * TypeSize(Type, CompositeType);
printf("Adding a %s symbol of name %s, type %s to the tables.\n", ScopeNames[Node->Storage], Node->Name,
TypeNames(Node->Type));
switch (Storage) {
case SC_GLOBAL:
AppendSymbol(&Globals, &GlobalsEnd, Node);
// We don't want to generate a static block for functions.
if (Structure != ST_FUNC) Assembler->vtable->AsGlobalSymbol(Node);
break;
case SC_STRUCT:
AppendSymbol(&Structs, &StructsEnd, Node);
break;
case SC_UNION:
AppendSymbol(&Unions, &UnionsEnd, Node);
break;
case SC_ENUM:
AppendSymbol(&Enums, &EnumsEnd, Node);
break;
case SC_ALIAS:
AppendSymbol(&Types, &TypesEnd, Node);
break;
case SC_ENUMENTRY:
AppendSymbol(&EnumMembers, &EnumMembersEnd, Node);
break;
case SC_MEMBER:
AppendSymbol(&CompositeMembers, &CompositeMembersEnd, Node);
break;
case SC_LOCAL:
AppendSymbol(&Locals, &LocalsEnd, Node);
break;
case SC_PARAM:
AppendSymbol(&Params, &ParamsEnd, Node);
break;
}
return Node;
}