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_STRUCT = 80, // Struct Data
|
||||||
DAT_UNION, // Union 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();
|
void BeginEnumDeclaration();
|
||||||
|
|
||||||
|
int ReadAlias(struct SymbolTableEntry** Composite);
|
||||||
|
|
||||||
|
int ParseAlias(char* Name, struct SymbolTableEntry** Composite);
|
||||||
|
|
||||||
struct ASTNode* GetExpressionList();
|
struct ASTNode* GetExpressionList();
|
||||||
|
|
||||||
struct ASTNode* CallFunction();
|
struct ASTNode* CallFunction();
|
||||||
|
@ -396,6 +401,8 @@ struct SymbolTableEntry* FindGlobal(char* Symbol);
|
||||||
|
|
||||||
struct SymbolTableEntry* FindStruct(char* Symbol);
|
struct SymbolTableEntry* FindStruct(char* Symbol);
|
||||||
|
|
||||||
|
struct SymbolTableEntry* FindAlias(char* Symbol);
|
||||||
|
|
||||||
struct SymbolTableEntry* FindEnum(char* Symbol);
|
struct SymbolTableEntry* FindEnum(char* Symbol);
|
||||||
|
|
||||||
struct SymbolTableEntry* FindEnumMember(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.
|
* @param IntValue: The integer value encoded by this Node, if applicable.
|
||||||
* @return a newly constructed AST Node
|
* @return a newly constructed AST Node
|
||||||
*/
|
*/
|
||||||
struct ASTNode*
|
struct ASTNode* ConstructASTBranch(int Operation, int Type, struct ASTNode* Left, struct SymbolTableEntry* Symbol, int IntValue) {
|
||||||
ConstructASTBranch(int Operation, int Type, struct ASTNode* Left, struct SymbolTableEntry* Symbol, int IntValue) {
|
|
||||||
return ConstructASTNode(Operation, Type, Left, NULL, NULL, Symbol, IntValue);
|
return ConstructASTNode(Operation, Type, Left, NULL, NULL, Symbol, IntValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +158,64 @@ int ParseTokenToOperation(int Token) {
|
||||||
DieDecimal("ParseToken: Unknown token", 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:
|
* Primary expressions may be any one of:
|
||||||
* * A terminal integer literal
|
* * A terminal integer literal
|
||||||
|
@ -215,7 +272,7 @@ struct ASTNode* ParsePrimary(void) {
|
||||||
* the order of operations is upheld, that the precedence of the prior
|
* the order of operations is upheld, that the precedence of the prior
|
||||||
* iteration is considered, and that every error is handled.
|
* 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
|
* type mismatches and widening are handled properly, and that all parsing
|
||||||
* is over by the time the end tokens ") } ] ;" are encountered.
|
* is over by the time the end tokens ") } ] ;" are encountered.
|
||||||
*
|
*
|
||||||
|
@ -534,7 +591,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 || 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();
|
Tokenise();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,9 +92,13 @@ int ParseOptionalPointer(struct SymbolTableEntry** Composite) {
|
||||||
Type = RET_LONG;
|
Type = RET_LONG;
|
||||||
Tokenise();
|
Tokenise();
|
||||||
break;
|
break;
|
||||||
case KW_STRUCT:
|
case TY_IDENTIFIER:
|
||||||
Type = DAT_STRUCT;
|
Type = ParseAlias(CurrentIdentifier, Composite);
|
||||||
*Composite = BeginCompositeDeclaration(Type);
|
break;
|
||||||
|
case KW_ALIAS:
|
||||||
|
Type = ReadAlias(Composite);
|
||||||
|
if (CurrentToken.type == LI_SEMIC)
|
||||||
|
Type = DAT_ALIAS;
|
||||||
break;
|
break;
|
||||||
case KW_ENUM:
|
case KW_ENUM:
|
||||||
Type = RET_INT;
|
Type = RET_INT;
|
||||||
|
@ -102,6 +106,10 @@ int ParseOptionalPointer(struct SymbolTableEntry** Composite) {
|
||||||
if (CurrentToken.type == LI_SEMIC)
|
if (CurrentToken.type == LI_SEMIC)
|
||||||
Type = DAT_ENUM;
|
Type = DAT_ENUM;
|
||||||
break;
|
break;
|
||||||
|
case KW_STRUCT:
|
||||||
|
Type = DAT_STRUCT;
|
||||||
|
*Composite = BeginCompositeDeclaration(Type);
|
||||||
|
break;
|
||||||
case KW_UNION:
|
case KW_UNION:
|
||||||
Type = DAT_UNION;
|
Type = DAT_UNION;
|
||||||
*Composite = BeginCompositeDeclaration(Type);
|
*Composite = BeginCompositeDeclaration(Type);
|
||||||
|
|
|
@ -143,6 +143,17 @@ struct SymbolTableEntry* FindEnumMember(char* Symbol) {
|
||||||
return SearchList(Symbol, EnumMembers);
|
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.
|
* An override for FindSymbol.
|
||||||
* Searches only the defined Unions.
|
* Searches only the defined Unions.
|
||||||
|
@ -257,6 +268,9 @@ struct SymbolTableEntry* AddSymbol(char* Name, int Type, int Structure, int Stor
|
||||||
case SC_ENUM:
|
case SC_ENUM:
|
||||||
AppendSymbol(&Enums, &EnumsEnd, Node);
|
AppendSymbol(&Enums, &EnumsEnd, Node);
|
||||||
break;
|
break;
|
||||||
|
case SC_ALIAS:
|
||||||
|
AppendSymbol(&Types, &TypesEnd, Node);
|
||||||
|
break;
|
||||||
case SC_ENUMENTRY:
|
case SC_ENUMENTRY:
|
||||||
AppendSymbol(&EnumMembers, &EnumMembersEnd, Node);
|
AppendSymbol(&EnumMembers, &EnumMembersEnd, Node);
|
||||||
break;
|
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