From fd08b7cdb7d1a15336ba5fa5fcdb59d31f224abb Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Fri, 10 Apr 2026 10:14:23 +1000 Subject: [PATCH] Struct field access (slightly buggy) --- src/codegen/codegen.c | 29 +++++++++++++++++++++++++++++ src/lexer/SolsType.c | 9 +++++++++ src/lexer/SolsType.h | 3 +++ 3 files changed, 41 insertions(+) diff --git a/src/codegen/codegen.c b/src/codegen/codegen.c index 84c1f55..4aa1985 100644 --- a/src/codegen/codegen.c +++ b/src/codegen/codegen.c @@ -8,6 +8,7 @@ #include #include "../lexer/lexer.h" +#include "../lexer/SolsType.h" #include "../parser/parser.h" #include "../parser/SolsNode.h" #include "../include/estr.h" @@ -249,6 +250,16 @@ ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope) { type.type = STT_OBJECT; return Success(SolsType, charptr, type); } + case SNT_DOT: { + ResultType(SolsType, charptr) type = getNodeType(&node->children.at[0], scope); + if (type.error) { + return Error(SolsType, charptr, type.as.error); + } + if (type.as.success.type != STT_OBJECT) { + return Error(SolsType, charptr, "Cannot use dot operator on non-object"); + } + return findStructMemberType(&type.as.success, node->children.at[1].as.idName); + } } return Error(SolsType, charptr, "Not yet implemented"); } @@ -1074,6 +1085,23 @@ ResultType(GroundProgram, charptr) generateNewNode(SolsNode* node, SolsScope* sc return Success(GroundProgram, charptr, program); } +ResultType(GroundProgram, charptr) generateDotNode(SolsNode* node, SolsScope* scope) { + GroundProgram program = groundCreateProgram(); + GroundInstruction inst = groundCreateInstruction(GETFIELD); + groundAddReferenceToInstruction(&inst, node->children.at[0].accessArg); + groundAddReferenceToInstruction(&inst, groundCreateReference(DIRREF, node->children.at[1].as.idName)); + char* tmpId = malloc(sizeof(char) * 64); + if (tmpId == NULL) { + return Error(GroundProgram, charptr, "Failed to allocate memory for tmp identifier"); + } + snprintf(tmpId, 64, "__SOLS_TMP_DOT_%zu", scope->tmpCounter++); + node->accessArg = groundCreateReference(VALREF, tmpId); + groundAddReferenceToInstruction(&inst, groundCreateReference(DIRREF, tmpId)); + groundAddInstructionToProgram(&program, inst); + return Success(GroundProgram, charptr, program); + +} + ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope) { @@ -1131,6 +1159,7 @@ ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope case SNT_GROUND: generate(InlineGround); case SNT_STRUCT: generate(Struct); case SNT_NEW: generate(New); + case SNT_DOT: generate(Dot); } return Success(GroundProgram, charptr, program); } diff --git a/src/lexer/SolsType.c b/src/lexer/SolsType.c index a868551..5972060 100644 --- a/src/lexer/SolsType.c +++ b/src/lexer/SolsType.c @@ -213,3 +213,12 @@ ResultType(GroundArg, charptr) createGroundArgFromSolsType(SolsType* type, struc } return Error(GroundArg, charptr, "How did we get here?"); } + +ResultType(SolsType, charptr) findStructMemberType(SolsType* type, char* member) { + for (size_t i = 0; i < type->children.count; i++) { + if (strcmp(type->children.at[i].name, member) == 0) { + return Success(SolsType, charptr, type->children.at[i].type); + } + } + return Error(SolsType, charptr, "Could not find member"); +} diff --git a/src/lexer/SolsType.h b/src/lexer/SolsType.h index 0a76f1d..e958704 100644 --- a/src/lexer/SolsType.h +++ b/src/lexer/SolsType.h @@ -114,4 +114,7 @@ void freeSolsType(SolsType* type); // Compares two SolsTypes bool compareTypes(SolsType* left, SolsType* right); +// Finds the type of a struct member. Errors if the member is not found. +ResultType(SolsType, charptr) findStructMemberType(SolsType* type, char* member); + #endif