Implement (broken) struct member access

This commit is contained in:
Curle 2021-07-05 00:07:04 +01:00
parent 2bdbe6e6c0
commit 8e45ea5eef
5 changed files with 71 additions and 3 deletions

View File

@ -77,6 +77,8 @@ enum TokenTypes {
LI_RPARE, // ) LI_RPARE, // )
LI_COM, // , LI_COM, // ,
LI_DOT, // .
LI_ARROW, // ->
TY_IDENTIFIER, // Identifier name. Variable, function, etc. TY_IDENTIFIER, // Identifier name. Variable, function, etc.
TY_NONE, // No return type. Literal void. TY_NONE, // No return type. Literal void.
@ -254,9 +256,9 @@ enum DataTypes {
enum StructureType { 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
// This is an enum // This is an enum
// This is a struct
// This is a typedef // This is a typedef
}; };
@ -342,6 +344,7 @@ int ValueAt(int Type);
int PointerTo(int Type); int PointerTo(int Type);
struct ASTNode* AccessArray(); struct ASTNode* AccessArray();
struct ASTNode* AccessMember(bool Deref);
int ParseTokenToOperation(int Token); int ParseTokenToOperation(int Token);

View File

@ -377,6 +377,10 @@ void Tokenise() {
Token->type = LI_EOF; Token->type = LI_EOF;
return; return;
case '.':
Token->type = LI_DOT;
return;
case '+': case '+':
// + can be either "+" or "++". // + can be either "+" or "++".
Char = NextChar(); Char = NextChar();
@ -389,10 +393,12 @@ void Tokenise() {
break; break;
case '-': case '-':
// - can be either "-" or "--" // - can be either "-" or "--" or "->"
Char = NextChar(); Char = NextChar();
if(Char == '-') { if(Char == '-') {
Token->type = PPMM_MINUS; Token->type = PPMM_MINUS;
} else if(Char == '>') {
Token->type = LI_ARROW;
} else { } else {
Token->type = AR_MINUS; Token->type = AR_MINUS;
ReturnCharToStream(Char); ReturnCharToStream(Char);

View File

@ -58,6 +58,8 @@ char* TokenNames[] = {
"Logical Block End", "Logical Block End",
"Comma", "Comma",
"Dot",
"Arrow",
"Identifier", "Identifier",
"None Type", "None Type",

View File

@ -155,3 +155,55 @@ struct ASTNode* AccessArray() {
printf("\tArray Access constructed\r\n"); printf("\tArray Access constructed\r\n");
return LeftNode; return LeftNode;
} }
/**
* Members of enums and structs are accessed with x.y or *x->y
*
* x must be enum, struct, or pointer to struct.
* y must be a valid member of any of the above.
*
* It is a wrapper around *((imax*)x + xType.ordinal(y))
*
* @return the AST Node representing this statement.
*/
struct ASTNode* AccessMember(bool Deref) {
struct ASTNode* LeftNode, *RightNode;
struct SymbolTableEntry* CompositeVar, *TypePtr, *Member;
if((CompositeVar = FindSymbol(CurrentIdentifier)) == NULL)
DieMessage("Undecalred variable", CurrentIdentifier);
if(Deref && CompositeVar->Type != PointerTo(DAT_STRUCT))
DieMessage("Undeclared struct", CurrentIdentifier);
if(!Deref && CompositeVar->Type != DAT_STRUCT)
DieMessage("Undeclared struct", CurrentIdentifier);
if(Deref)
LeftNode = ConstructASTLeaf(REF_IDENT, PointerTo(DAT_STRUCT), CompositeVar, 0);
else
LeftNode = ConstructASTLeaf(OP_ADDRESS, CompositeVar->Type, CompositeVar, 0);
LeftNode->RVal = true;
TypePtr = CompositeVar->CompositeType;
Tokenise();
VerifyToken(TY_IDENTIFIER, "identifier");
for(Member = TypePtr->Start; Member != NULL, Member = Member->NextSymbol;) {
printf("\tComparing struct entry %s with the wanted %s. Index %d.\r\n", Member->Name, CurrentIdentifier, Member->SinkOffset);
if(!strcmp(Member->Name, CurrentIdentifier))
break;
}
if(Member == NULL)
DieMessage("Invalid struct member", CurrentIdentifier);
RightNode = ConstructASTLeaf(TERM_INTLITERAL, RET_INT, NULL, Member->SinkOffset);
LeftNode = ConstructASTNode(OP_ADD, PointerTo(Member->Type), LeftNode, NULL, RightNode, NULL, 0);
LeftNode = ConstructASTBranch(OP_DEREF, Member->Type, LeftNode, Member, 0);
return LeftNode;
}

View File

@ -103,6 +103,7 @@ struct SymbolTableEntry* BeginStructDeclaration() {
StructMembers = StructMembersEnd = NULL; StructMembers = StructMembersEnd = NULL;
Member = Composite->Start; Member = Composite->Start;
printf("\tSetting first entry in struct to %s\r\n", Member->Name);
Member->SinkOffset = 0; Member->SinkOffset = 0;
Offset = TypeSize(Member->Type, Member->CompositeType); Offset = TypeSize(Member->Type, Member->CompositeType);
@ -516,6 +517,10 @@ struct ASTNode* PostfixStatement() {
// Here we check for postincrement and postdecrement. // Here we check for postincrement and postdecrement.
switch(CurrentToken.type) { switch(CurrentToken.type) {
case LI_DOT:
return AccessMember(false);
case LI_ARROW:
return AccessMember(true);
case PPMM_PLUS: case PPMM_PLUS:
Tokenise(); Tokenise();
Tree = ConstructASTLeaf(OP_POSTINC, Entry->Type, Entry, 0); Tree = ConstructASTLeaf(OP_POSTINC, Entry->Type, Entry, 0);