From 8e45ea5eef5931c9d819cddd5b559040bd147b1b Mon Sep 17 00:00:00 2001 From: Curle Date: Mon, 5 Jul 2021 00:07:04 +0100 Subject: [PATCH] Implement (broken) struct member access --- include/Defs.h | 7 +++++-- src/Lexer.c | 8 +++++++- src/Main.c | 2 ++ src/Pointers.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ src/Statements.c | 5 +++++ 5 files changed, 71 insertions(+), 3 deletions(-) diff --git a/include/Defs.h b/include/Defs.h index ef6e1ab..99481d8 100644 --- a/include/Defs.h +++ b/include/Defs.h @@ -77,6 +77,8 @@ enum TokenTypes { LI_RPARE, // ) LI_COM, // , + LI_DOT, // . + LI_ARROW, // -> TY_IDENTIFIER, // Identifier name. Variable, function, etc. TY_NONE, // No return type. Literal void. @@ -254,9 +256,9 @@ enum DataTypes { enum StructureType { ST_VAR, // This is variable 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 a struct // This is a typedef }; @@ -342,6 +344,7 @@ int ValueAt(int Type); int PointerTo(int Type); struct ASTNode* AccessArray(); +struct ASTNode* AccessMember(bool Deref); int ParseTokenToOperation(int Token); diff --git a/src/Lexer.c b/src/Lexer.c index 155e3a4..c379d24 100644 --- a/src/Lexer.c +++ b/src/Lexer.c @@ -377,6 +377,10 @@ void Tokenise() { Token->type = LI_EOF; return; + case '.': + Token->type = LI_DOT; + return; + case '+': // + can be either "+" or "++". Char = NextChar(); @@ -389,10 +393,12 @@ void Tokenise() { break; case '-': - // - can be either "-" or "--" + // - can be either "-" or "--" or "->" Char = NextChar(); if(Char == '-') { Token->type = PPMM_MINUS; + } else if(Char == '>') { + Token->type = LI_ARROW; } else { Token->type = AR_MINUS; ReturnCharToStream(Char); diff --git a/src/Main.c b/src/Main.c index 5a10236..52323f2 100644 --- a/src/Main.c +++ b/src/Main.c @@ -58,6 +58,8 @@ char* TokenNames[] = { "Logical Block End", "Comma", + "Dot", + "Arrow", "Identifier", "None Type", diff --git a/src/Pointers.c b/src/Pointers.c index 83a3723..9e237e5 100644 --- a/src/Pointers.c +++ b/src/Pointers.c @@ -153,5 +153,57 @@ struct ASTNode* AccessArray() { printf("\tAccessArray: Preparing LeftNode for dereference.\r\n"); LeftNode = ConstructASTBranch(OP_DEREF, ValueAt(LeftNode->ExprType), LeftNode, NULL, 0); printf("\tArray Access constructed\r\n"); + 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; } \ No newline at end of file diff --git a/src/Statements.c b/src/Statements.c index 6af8a78..22b58bb 100644 --- a/src/Statements.c +++ b/src/Statements.c @@ -103,6 +103,7 @@ struct SymbolTableEntry* BeginStructDeclaration() { StructMembers = StructMembersEnd = NULL; Member = Composite->Start; + printf("\tSetting first entry in struct to %s\r\n", Member->Name); Member->SinkOffset = 0; Offset = TypeSize(Member->Type, Member->CompositeType); @@ -516,6 +517,10 @@ struct ASTNode* PostfixStatement() { // Here we check for postincrement and postdecrement. switch(CurrentToken.type) { + case LI_DOT: + return AccessMember(false); + case LI_ARROW: + return AccessMember(true); case PPMM_PLUS: Tokenise(); Tree = ConstructASTLeaf(OP_POSTINC, Entry->Type, Entry, 0);