Implement enums and the foundation of a type alias system
This commit is contained in:
parent
3717b310be
commit
628c7a3a13
|
@ -22,9 +22,11 @@ extern_ struct SymbolTableEntry* Params, * ParamsEnd;
|
|||
extern_ struct SymbolTableEntry* Structs, * StructsEnd;
|
||||
|
||||
extern_ struct SymbolTableEntry* CompositeMembers, * CompositeMembersEnd;
|
||||
extern_ struct SymbolTableEntry* EnumMembers, * EnumMembersEnd;
|
||||
|
||||
extern_ struct SymbolTableEntry* Unions, * UnionsEnd;
|
||||
extern_ struct SymbolTableEntry* Enums, * EnumsEnd;
|
||||
extern_ struct SymbolTableEntry* Types, * TypesEnd;
|
||||
|
||||
extern_ bool OptDumpTree;
|
||||
extern_ bool OptKeepAssembly;
|
||||
|
|
|
@ -97,7 +97,9 @@ enum TokenTypes {
|
|||
KW_FOR,
|
||||
KW_RETURN,
|
||||
KW_STRUCT,
|
||||
KW_UNION
|
||||
KW_UNION,
|
||||
KW_ENUM,
|
||||
KW_ALIAS
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -222,7 +224,9 @@ enum StorageScope {
|
|||
SC_STRUCT, // Struct Definitions
|
||||
SC_UNION, // Union 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_STATIC, // Static storage definitions
|
||||
SC_PARAM, // Function parameters
|
||||
|
@ -249,6 +253,7 @@ enum DataTypes {
|
|||
|
||||
DAT_STRUCT = 80, // Struct Data
|
||||
DAT_UNION, // Union Data
|
||||
DAT_ENUM = -1, // Enum Data
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -260,8 +265,8 @@ enum StructureType {
|
|||
ST_VAR, // This is variable
|
||||
ST_FUNC, // This is a function
|
||||
ST_ARR, // This is an array
|
||||
ST_RUCT // This is a struct
|
||||
// This is an enum
|
||||
ST_RUCT, // This is a struct
|
||||
ST_ENUM, // This is an enum
|
||||
// This is a typedef
|
||||
};
|
||||
|
||||
|
@ -352,6 +357,8 @@ struct ASTNode* ParseCompound();
|
|||
|
||||
struct SymbolTableEntry* BeginCompositeDeclaration(int Type);
|
||||
|
||||
void BeginEnumDeclaration();
|
||||
|
||||
struct ASTNode* GetExpressionList();
|
||||
|
||||
struct ASTNode* CallFunction();
|
||||
|
@ -389,6 +396,10 @@ struct SymbolTableEntry* FindGlobal(char* Symbol);
|
|||
|
||||
struct SymbolTableEntry* FindStruct(char* Symbol);
|
||||
|
||||
struct SymbolTableEntry* FindEnum(char* Symbol);
|
||||
|
||||
struct SymbolTableEntry* FindEnumMember(char* Symbol);
|
||||
|
||||
struct SymbolTableEntry* FindUnion(char* Symbol);
|
||||
|
||||
struct SymbolTableEntry* FindMember(char* Symbol);
|
||||
|
|
|
@ -283,6 +283,11 @@ static int ReadKeyword(char* Str) {
|
|||
return KW_FUNC;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
if (!strcmp(Str, "alias"))
|
||||
return KW_ALIAS;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if (!strcmp(Str, "char"))
|
||||
return TY_CHAR;
|
||||
|
@ -291,6 +296,8 @@ static int ReadKeyword(char* Str) {
|
|||
case 'e':
|
||||
if (!strcmp(Str, "else"))
|
||||
return KW_ELSE;
|
||||
if (!strcmp(Str, "enum"))
|
||||
return KW_ENUM;
|
||||
|
||||
break;
|
||||
|
||||
|
|
|
@ -89,6 +89,8 @@ char* ScopeNames[] = {
|
|||
"STRUCT",
|
||||
"UNION",
|
||||
"ENUM",
|
||||
"ENUM_ENTRY",
|
||||
"ALIAS",
|
||||
"MEMBER",
|
||||
"PARAMETER",
|
||||
"LOCAL"
|
||||
|
|
|
@ -534,7 +534,7 @@ void ParseGlobals() {
|
|||
|
||||
// Structs are parsed fully in ParseOptionalPointer
|
||||
// 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();
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -96,6 +96,12 @@ int ParseOptionalPointer(struct SymbolTableEntry** Composite) {
|
|||
Type = DAT_STRUCT;
|
||||
*Composite = BeginCompositeDeclaration(Type);
|
||||
break;
|
||||
case KW_ENUM:
|
||||
Type = RET_INT;
|
||||
BeginEnumDeclaration();
|
||||
if (CurrentToken.type == LI_SEMIC)
|
||||
Type = DAT_ENUM;
|
||||
break;
|
||||
case KW_UNION:
|
||||
Type = DAT_UNION;
|
||||
*Composite = BeginCompositeDeclaration(Type);
|
||||
|
|
|
@ -94,7 +94,7 @@ struct SymbolTableEntry* BeginCompositeDeclaration(int Type) {
|
|||
if (Composite)
|
||||
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();
|
||||
printf("Reading a composite declaration.. Type is %s\n", Type == DAT_STRUCT ? "struct" : "union");
|
||||
ReadDeclarationList(NULL, SC_MEMBER, LI_RBRAC);
|
||||
|
@ -123,6 +123,69 @@ struct SymbolTableEntry* BeginCompositeDeclaration(int Type) {
|
|||
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.
|
||||
* int newVar;
|
||||
|
@ -502,6 +565,12 @@ struct ASTNode* PostfixStatement() {
|
|||
struct ASTNode* Tree;
|
||||
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();
|
||||
|
||||
if (CurrentToken.type == LI_LPARE)
|
||||
|
|
|
@ -120,6 +120,29 @@ struct SymbolTableEntry* FindGlobal(char* Symbol) {
|
|||
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 Unions.
|
||||
|
@ -231,6 +254,12 @@ struct SymbolTableEntry* AddSymbol(char* Name, int Type, int Structure, int Stor
|
|||
case SC_UNION:
|
||||
AppendSymbol(&Unions, &UnionsEnd, Node);
|
||||
break;
|
||||
case SC_ENUM:
|
||||
AppendSymbol(&Enums, &EnumsEnd, Node);
|
||||
break;
|
||||
case SC_ENUMENTRY:
|
||||
AppendSymbol(&EnumMembers, &EnumMembersEnd, Node);
|
||||
break;
|
||||
case SC_MEMBER:
|
||||
AppendSymbol(&CompositeMembers, &CompositeMembersEnd, Node);
|
||||
break;
|
||||
|
|
18
tests/enum.er
Normal file
18
tests/enum.er
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user