Implement alias - a faster typedef
This commit is contained in:
parent
628c7a3a13
commit
2c87817904
|
@ -253,7 +253,8 @@ enum DataTypes {
|
|||
|
||||
DAT_STRUCT = 80, // Struct Data
|
||||
DAT_UNION, // Union Data
|
||||
DAT_ENUM = -1, // Enum Data
|
||||
DAT_ENUM, // Enum Data
|
||||
DAT_ALIAS, // Alias Definition
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -359,6 +360,10 @@ struct SymbolTableEntry* BeginCompositeDeclaration(int Type);
|
|||
|
||||
void BeginEnumDeclaration();
|
||||
|
||||
int ReadAlias(struct SymbolTableEntry** Composite);
|
||||
|
||||
int ParseAlias(char* Name, struct SymbolTableEntry** Composite);
|
||||
|
||||
struct ASTNode* GetExpressionList();
|
||||
|
||||
struct ASTNode* CallFunction();
|
||||
|
@ -396,6 +401,8 @@ struct SymbolTableEntry* FindGlobal(char* Symbol);
|
|||
|
||||
struct SymbolTableEntry* FindStruct(char* Symbol);
|
||||
|
||||
struct SymbolTableEntry* FindAlias(char* Symbol);
|
||||
|
||||
struct SymbolTableEntry* FindEnum(char* Symbol);
|
||||
|
||||
struct SymbolTableEntry* FindEnumMember(char* Symbol);
|
||||
|
|
65
src/Parser.c
65
src/Parser.c
|
@ -135,8 +135,7 @@ struct ASTNode* ConstructASTLeaf(int Operation, int Type, struct SymbolTableEntr
|
|||
* @param IntValue: The integer value encoded by this Node, if applicable.
|
||||
* @return a newly constructed AST Node
|
||||
*/
|
||||
struct ASTNode*
|
||||
ConstructASTBranch(int Operation, int Type, struct ASTNode* Left, struct SymbolTableEntry* Symbol, int IntValue) {
|
||||
struct ASTNode* ConstructASTBranch(int Operation, int Type, struct ASTNode* Left, struct SymbolTableEntry* Symbol, int IntValue) {
|
||||
return ConstructASTNode(Operation, Type, Left, NULL, NULL, Symbol, IntValue);
|
||||
}
|
||||
|
||||
|
@ -159,6 +158,64 @@ int ParseTokenToOperation(int Token) {
|
|||
DieDecimal("ParseToken: Unknown token", Token);
|
||||
}
|
||||
|
||||
/*
|
||||
* The "alias" keyword allows one to create a new keyword that is accepted in lieu of another (or a chain of another)
|
||||
* It does this by reading in sequence:
|
||||
* * The "alias" keyword
|
||||
* * The thing to alias (any valid primary type)
|
||||
* * The new name
|
||||
*
|
||||
* They are stored in a separate symbol table and can be used anywhere the original is valid.
|
||||
*/
|
||||
int ReadAlias(struct SymbolTableEntry** Composite) {
|
||||
int Type;
|
||||
|
||||
Tokenise();
|
||||
|
||||
Type = ParseOptionalPointer(Composite);
|
||||
|
||||
if (FindAlias(CurrentIdentifier) != NULL)
|
||||
DieMessage("Redefinition of type", CurrentIdentifier);
|
||||
|
||||
AddSymbol(CurrentIdentifier, Type, ST_VAR, SC_ALIAS, 0, 0, *Composite);
|
||||
Tokenise();
|
||||
|
||||
return Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* When using an alias, we need to lookup the name (possibly recursively) to check whether it is a valid alias.
|
||||
* If so, we need to know what it is an alias of.
|
||||
* Once we have resolved what it finally means, we return the type.
|
||||
* @param Name The name of the (initial) alias to check
|
||||
* @param Composite A pointer to the composite element we should fill in.
|
||||
* @return The aliased type.
|
||||
*/
|
||||
int ParseAlias(char* Name, struct SymbolTableEntry** Composite) {
|
||||
struct SymbolTableEntry* Type = NULL, *RootType = NULL;
|
||||
|
||||
// Ensure the first-round alias exists
|
||||
Type = FindAlias(Name);
|
||||
if (Type == NULL)
|
||||
DieMessage("Unknown alias", Name);
|
||||
|
||||
// Loop on the alias for as long as it continues to exist.
|
||||
while (true) {
|
||||
if (Type->CompositeType == NULL)
|
||||
break;
|
||||
|
||||
RootType = FindAlias(Type->CompositeType->Name);
|
||||
if (RootType == NULL)
|
||||
break;
|
||||
Type = RootType;
|
||||
}
|
||||
|
||||
Tokenise();
|
||||
*Composite = Type->CompositeType;
|
||||
return Type->Type;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Primary expressions may be any one of:
|
||||
* * A terminal integer literal
|
||||
|
@ -215,7 +272,7 @@ struct ASTNode* ParsePrimary(void) {
|
|||
* the order of operations is upheld, that the precedence of the prior
|
||||
* iteration is considered, and that every error is handled.
|
||||
*
|
||||
* This is where all of the right-associative statements are folded, where
|
||||
* This is where all the right-associative statements are folded, where
|
||||
* type mismatches and widening are handled properly, and that all parsing
|
||||
* is over by the time the end tokens ") } ] ;" are encountered.
|
||||
*
|
||||
|
@ -534,7 +591,7 @@ void ParseGlobals() {
|
|||
|
||||
// Structs are parsed fully in ParseOptionalPointer
|
||||
// TODO: FIX THAT!!
|
||||
if ((Type == DAT_STRUCT || Type == DAT_UNION || Type == DAT_ENUM) && CurrentToken.type == LI_SEMIC) {
|
||||
if ((Type == DAT_STRUCT || Type == DAT_UNION || Type == DAT_ENUM || Type == DAT_ALIAS) && CurrentToken.type == LI_SEMIC) {
|
||||
Tokenise();
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -92,9 +92,13 @@ int ParseOptionalPointer(struct SymbolTableEntry** Composite) {
|
|||
Type = RET_LONG;
|
||||
Tokenise();
|
||||
break;
|
||||
case KW_STRUCT:
|
||||
Type = DAT_STRUCT;
|
||||
*Composite = BeginCompositeDeclaration(Type);
|
||||
case TY_IDENTIFIER:
|
||||
Type = ParseAlias(CurrentIdentifier, Composite);
|
||||
break;
|
||||
case KW_ALIAS:
|
||||
Type = ReadAlias(Composite);
|
||||
if (CurrentToken.type == LI_SEMIC)
|
||||
Type = DAT_ALIAS;
|
||||
break;
|
||||
case KW_ENUM:
|
||||
Type = RET_INT;
|
||||
|
@ -102,6 +106,10 @@ int ParseOptionalPointer(struct SymbolTableEntry** Composite) {
|
|||
if (CurrentToken.type == LI_SEMIC)
|
||||
Type = DAT_ENUM;
|
||||
break;
|
||||
case KW_STRUCT:
|
||||
Type = DAT_STRUCT;
|
||||
*Composite = BeginCompositeDeclaration(Type);
|
||||
break;
|
||||
case KW_UNION:
|
||||
Type = DAT_UNION;
|
||||
*Composite = BeginCompositeDeclaration(Type);
|
||||
|
|
|
@ -143,6 +143,17 @@ struct SymbolTableEntry* FindEnumMember(char* Symbol) {
|
|||
return SearchList(Symbol, EnumMembers);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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* FindAlias(char* Symbol) {
|
||||
return SearchList(Symbol, Types);
|
||||
}
|
||||
|
||||
/*
|
||||
* An override for FindSymbol.
|
||||
* Searches only the defined Unions.
|
||||
|
@ -257,6 +268,9 @@ struct SymbolTableEntry* AddSymbol(char* Name, int Type, int Structure, int Stor
|
|||
case SC_ENUM:
|
||||
AppendSymbol(&Enums, &EnumsEnd, Node);
|
||||
break;
|
||||
case SC_ALIAS:
|
||||
AppendSymbol(&Types, &TypesEnd, Node);
|
||||
break;
|
||||
case SC_ENUMENTRY:
|
||||
AppendSymbol(&EnumMembers, &EnumMembersEnd, Node);
|
||||
break;
|
||||
|
|
29
tests/alias.er
Normal file
29
tests/alias.er
Normal file
|
@ -0,0 +1,29 @@
|
|||
int :: printf(char* format);
|
||||
|
||||
alias int water;
|
||||
water drink;
|
||||
|
||||
struct fruit {
|
||||
int x,
|
||||
int y
|
||||
};
|
||||
|
||||
alias struct fruit basket;
|
||||
basket food;
|
||||
|
||||
alias basket shop;
|
||||
shop market;
|
||||
|
||||
int :: main() {
|
||||
drink = 5;
|
||||
printf("%d\n", drink);
|
||||
|
||||
food.x = 10;
|
||||
food.y = 66;
|
||||
printf("%d\n", food.y);
|
||||
|
||||
market.y = 150;
|
||||
printf("%d\n", market.y);
|
||||
|
||||
return (0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user