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* 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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,8 @@ char* ScopeNames[] = {
|
||||||
"STRUCT",
|
"STRUCT",
|
||||||
"UNION",
|
"UNION",
|
||||||
"ENUM",
|
"ENUM",
|
||||||
|
"ENUM_ENTRY",
|
||||||
|
"ALIAS",
|
||||||
"MEMBER",
|
"MEMBER",
|
||||||
"PARAMETER",
|
"PARAMETER",
|
||||||
"LOCAL"
|
"LOCAL"
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
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