Implement enums and the foundation of a type alias system

This commit is contained in:
Curle 2022-03-04 01:11:04 +00:00
parent 3717b310be
commit 628c7a3a13
9 changed files with 150 additions and 6 deletions

View File

@ -22,9 +22,11 @@ extern_ struct SymbolTableEntry* Params, * ParamsEnd;
extern_ struct SymbolTableEntry* Structs, * StructsEnd; extern_ struct SymbolTableEntry* Structs, * StructsEnd;
extern_ struct SymbolTableEntry* CompositeMembers, * CompositeMembersEnd; extern_ struct SymbolTableEntry* CompositeMembers, * CompositeMembersEnd;
extern_ struct SymbolTableEntry* EnumMembers, * EnumMembersEnd;
extern_ struct SymbolTableEntry* Unions, * UnionsEnd; extern_ struct SymbolTableEntry* Unions, * UnionsEnd;
extern_ struct SymbolTableEntry* Enums, * EnumsEnd; extern_ struct SymbolTableEntry* Enums, * EnumsEnd;
extern_ struct SymbolTableEntry* Types, * TypesEnd;
extern_ bool OptDumpTree; extern_ bool OptDumpTree;
extern_ bool OptKeepAssembly; extern_ bool OptKeepAssembly;

View File

@ -97,7 +97,9 @@ enum TokenTypes {
KW_FOR, KW_FOR,
KW_RETURN, KW_RETURN,
KW_STRUCT, KW_STRUCT,
KW_UNION KW_UNION,
KW_ENUM,
KW_ALIAS
}; };
/* /*
@ -222,7 +224,9 @@ enum StorageScope {
SC_STRUCT, // Struct Definitions SC_STRUCT, // Struct Definitions
SC_UNION, // Union Definitions SC_UNION, // Union Definitions
SC_ENUM, // Enum Definitions SC_ENUM, // Enum Definitions
SC_MEMBER, // The members of Structs or Enums SC_ENUMENTRY, // Enum Entry Names
SC_ALIAS, // Typedef aliases
SC_MEMBER, // The members of Structs or Unions
//SC_CLASS, // Class-local definitions //SC_CLASS, // Class-local definitions
//SC_STATIC, // Static storage definitions //SC_STATIC, // Static storage definitions
SC_PARAM, // Function parameters SC_PARAM, // Function parameters
@ -249,6 +253,7 @@ enum DataTypes {
DAT_STRUCT = 80, // Struct Data DAT_STRUCT = 80, // Struct Data
DAT_UNION, // Union Data DAT_UNION, // Union Data
DAT_ENUM = -1, // Enum Data
}; };
/* /*
@ -260,8 +265,8 @@ enum StructureType {
ST_VAR, // This is variable ST_VAR, // This is variable
ST_FUNC, // This is a function ST_FUNC, // This is a function
ST_ARR, // This is an array ST_ARR, // This is an array
ST_RUCT // This is a struct ST_RUCT, // This is a struct
// This is an enum ST_ENUM, // This is an enum
// This is a typedef // This is a typedef
}; };
@ -352,6 +357,8 @@ struct ASTNode* ParseCompound();
struct SymbolTableEntry* BeginCompositeDeclaration(int Type); struct SymbolTableEntry* BeginCompositeDeclaration(int Type);
void BeginEnumDeclaration();
struct ASTNode* GetExpressionList(); struct ASTNode* GetExpressionList();
struct ASTNode* CallFunction(); struct ASTNode* CallFunction();
@ -389,6 +396,10 @@ struct SymbolTableEntry* FindGlobal(char* Symbol);
struct SymbolTableEntry* FindStruct(char* Symbol); struct SymbolTableEntry* FindStruct(char* Symbol);
struct SymbolTableEntry* FindEnum(char* Symbol);
struct SymbolTableEntry* FindEnumMember(char* Symbol);
struct SymbolTableEntry* FindUnion(char* Symbol); struct SymbolTableEntry* FindUnion(char* Symbol);
struct SymbolTableEntry* FindMember(char* Symbol); struct SymbolTableEntry* FindMember(char* Symbol);

View File

@ -283,6 +283,11 @@ static int ReadKeyword(char* Str) {
return KW_FUNC; return KW_FUNC;
break; break;
case 'a':
if (!strcmp(Str, "alias"))
return KW_ALIAS;
break;
case 'c': case 'c':
if (!strcmp(Str, "char")) if (!strcmp(Str, "char"))
return TY_CHAR; return TY_CHAR;
@ -291,6 +296,8 @@ static int ReadKeyword(char* Str) {
case 'e': case 'e':
if (!strcmp(Str, "else")) if (!strcmp(Str, "else"))
return KW_ELSE; return KW_ELSE;
if (!strcmp(Str, "enum"))
return KW_ENUM;
break; break;

View File

@ -89,6 +89,8 @@ char* ScopeNames[] = {
"STRUCT", "STRUCT",
"UNION", "UNION",
"ENUM", "ENUM",
"ENUM_ENTRY",
"ALIAS",
"MEMBER", "MEMBER",
"PARAMETER", "PARAMETER",
"LOCAL" "LOCAL"

View File

@ -534,7 +534,7 @@ void ParseGlobals() {
// Structs are parsed fully in ParseOptionalPointer // Structs are parsed fully in ParseOptionalPointer
// TODO: FIX THAT!! // TODO: FIX THAT!!
if ((Type == DAT_STRUCT || Type == DAT_UNION) && CurrentToken.type == LI_SEMIC) { if ((Type == DAT_STRUCT || Type == DAT_UNION || Type == DAT_ENUM) && CurrentToken.type == LI_SEMIC) {
Tokenise(); Tokenise();
continue; continue;
} }

View File

@ -96,6 +96,12 @@ int ParseOptionalPointer(struct SymbolTableEntry** Composite) {
Type = DAT_STRUCT; Type = DAT_STRUCT;
*Composite = BeginCompositeDeclaration(Type); *Composite = BeginCompositeDeclaration(Type);
break; break;
case KW_ENUM:
Type = RET_INT;
BeginEnumDeclaration();
if (CurrentToken.type == LI_SEMIC)
Type = DAT_ENUM;
break;
case KW_UNION: case KW_UNION:
Type = DAT_UNION; Type = DAT_UNION;
*Composite = BeginCompositeDeclaration(Type); *Composite = BeginCompositeDeclaration(Type);

View File

@ -94,7 +94,7 @@ struct SymbolTableEntry* BeginCompositeDeclaration(int Type) {
if (Composite) if (Composite)
DieMessage("Redefinition of composite", CurrentIdentifier); DieMessage("Redefinition of composite", CurrentIdentifier);
Composite = AddSymbol(CurrentIdentifier, Type, 0, Type == DAT_STRUCT ? SC_STRUCT : SC_UNION, 0, 0, NULL); Composite = AddSymbol(CurrentIdentifier, Type, ST_RUCT, Type == DAT_STRUCT ? SC_STRUCT : SC_UNION, 0, 0, NULL);
Tokenise(); Tokenise();
printf("Reading a composite declaration.. Type is %s\n", Type == DAT_STRUCT ? "struct" : "union"); printf("Reading a composite declaration.. Type is %s\n", Type == DAT_STRUCT ? "struct" : "union");
ReadDeclarationList(NULL, SC_MEMBER, LI_RBRAC); ReadDeclarationList(NULL, SC_MEMBER, LI_RBRAC);
@ -123,6 +123,69 @@ struct SymbolTableEntry* BeginCompositeDeclaration(int Type) {
return Composite; return Composite;
} }
void BeginEnumDeclaration() {
struct SymbolTableEntry* Type = NULL;
char* Name;
int Value = 0;
Tokenise();
// enum name
if (CurrentToken.type == TY_IDENTIFIER) {
Type = FindEnum(CurrentIdentifier);
Name = strdup(CurrentIdentifier);
Tokenise();
}
// enum name {? if not, enum name var.
if (CurrentToken.type != LI_LBRAC) {
if (Type == NULL)
DieMessage("Undeclared Enum", Name);
return;
}
// Skip the { that we have
Tokenise();
if (Type != NULL)
DieMessage("Attempting to redefine enum", Type->Name);
else
Type = AddSymbol(Name, DAT_ENUM, ST_ENUM, SC_ENUM, 0, 0, NULL);
while (1) {
VerifyToken(TY_IDENTIFIER, "Enum Entry");
Name = strdup(CurrentIdentifier);
Type = FindEnumMember(Name);
if (Type != NULL)
DieMessage("Attempting to redeclare enum value", Name);
// Parse equality
if (CurrentToken.type == LI_EQUAL) {
Tokenise();
// Expect a number after the equals
if (CurrentToken.type != LI_INT)
Die("Expected integer to assign enum value to");
Value = CurrentToken.value;
Tokenise();
}
Type = AddSymbol(Name, DAT_ENUM, ST_ENUM, SC_ENUMENTRY, Value++, 0, NULL);
// Break on right brace
if (CurrentToken.type == LI_RBRAC)
break;
VerifyToken(LI_COM, "Comma");
}
// Skip right brace
Tokenise();
}
/* /*
* Handles the declaration of a type of a variable. * Handles the declaration of a type of a variable.
* int newVar; * int newVar;
@ -502,6 +565,12 @@ struct ASTNode* PostfixStatement() {
struct ASTNode* Tree; struct ASTNode* Tree;
struct SymbolTableEntry* Entry; struct SymbolTableEntry* Entry;
// Early exit if we find an enum value
if ((Entry = FindEnumMember(CurrentIdentifier)) != NULL) {
Tokenise();
return ConstructASTLeaf(TERM_INTLITERAL, RET_INT, NULL, Entry->IntValue);
}
Tokenise(); Tokenise();
if (CurrentToken.type == LI_LPARE) if (CurrentToken.type == LI_LPARE)

View File

@ -120,6 +120,29 @@ struct SymbolTableEntry* FindGlobal(char* Symbol) {
struct SymbolTableEntry* FindStruct(char* Symbol) { struct SymbolTableEntry* FindStruct(char* Symbol) {
return SearchList(Symbol, Structs); 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. * An override for FindSymbol.
* Searches only the defined Unions. * Searches only the defined Unions.
@ -231,6 +254,12 @@ struct SymbolTableEntry* AddSymbol(char* Name, int Type, int Structure, int Stor
case SC_UNION: case SC_UNION:
AppendSymbol(&Unions, &UnionsEnd, Node); AppendSymbol(&Unions, &UnionsEnd, Node);
break; break;
case SC_ENUM:
AppendSymbol(&Enums, &EnumsEnd, Node);
break;
case SC_ENUMENTRY:
AppendSymbol(&EnumMembers, &EnumMembersEnd, Node);
break;
case SC_MEMBER: case SC_MEMBER:
AppendSymbol(&CompositeMembers, &CompositeMembersEnd, Node); AppendSymbol(&CompositeMembers, &CompositeMembersEnd, Node);
break; break;

18
tests/enum.er Normal file
View File

@ -0,0 +1,18 @@
int :: printf(char* format);
enum fruit { apple, pear, shallot };
enum basket {
abc = 15,
def
};
enum basket thing;
enum fruit stuff;
int :: main() {
int temp;
temp = apple + pear + abc;
printf("%d\n", temp);
return (0);
}