From abc9728aa2bbf4dc1b03021554a2c93e69d90274 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Wed, 25 Feb 2026 21:44:55 +1100 Subject: [PATCH] Variables (polish notation for now) --- src/codegen/SolsScope.c | 9 +++-- src/codegen/SolsScope.h | 4 +-- src/codegen/codegen.c | 80 +++++++++++++++++++++++++++++++++++++++-- src/codegen/codegen.h | 3 ++ test.sols | 6 ++-- 5 files changed, 90 insertions(+), 12 deletions(-) diff --git a/src/codegen/SolsScope.c b/src/codegen/SolsScope.c index fa08a7f..23db7db 100644 --- a/src/codegen/SolsScope.c +++ b/src/codegen/SolsScope.c @@ -3,18 +3,21 @@ #include "../include/uthash.h" #include "../lexer/SolsType.h" -void addVariableToScope(SolsScope* scope, const char* name, SolsType* type) { +void addVariableToScope(SolsScope* scope, const char* name, SolsType type) { SolsVariable* s = malloc(sizeof(SolsVariable)); strncpy(s->id, name, sizeof(s->id) - 1); s->id[sizeof(s->id) - 1] = '\0'; - s->typeinfo = *type; + s->typeinfo = type; HASH_ADD_STR(scope->variables, id, s); } -SolsVariable* findVariable(SolsScope* scope, const char* name) { +SolsVariable* findSolsVariable(SolsScope* scope, const char* name) { + if (scope == NULL || scope->variables == NULL || name == NULL) { + return NULL; + } SolsVariable* s; HASH_FIND_STR(scope->variables, name, s); return s; diff --git a/src/codegen/SolsScope.h b/src/codegen/SolsScope.h index abfcea3..764e469 100644 --- a/src/codegen/SolsScope.h +++ b/src/codegen/SolsScope.h @@ -16,9 +16,9 @@ typedef struct SolsScope { } SolsScope; // Adds a variable to the SolsScope. -void addVariableToScope(SolsScope* scope, const char* name, SolsType* type); +void addVariableToScope(SolsScope* scope, const char* name, SolsType type); // Finds a variable in the SolsScope. -SolsVariable* findVariable(SolsScope* scope, const char* name); +SolsVariable* findSolsVariable(SolsScope* scope, const char* name); #endif diff --git a/src/codegen/codegen.c b/src/codegen/codegen.c index fd00705..02ad544 100644 --- a/src/codegen/codegen.c +++ b/src/codegen/codegen.c @@ -15,6 +15,54 @@ char* createCodegenError(char* what) { return estr.str; } +ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope) { + switch (node->type) { + case SNT_PUTS: { + return Error(SolsType, charptr, "Specified node does not return data"); + } + case SNT_OP_SET: { + if (node->children.count < 2) { + return Error(SolsType, charptr, "Not enough children to determine type"); + } + ResultType(SolsType, charptr) type = getNodeType(&node->children.at[0], scope); + if (type.error) { + return Error(SolsType, charptr, type.as.error); + } + return Success(SolsType, charptr, type.as.success); + } + case SNT_LITERAL: { + switch (node->as.literal.type) { + case SLT_INT: { + return Success(SolsType, charptr, {STT_INT}); + } + case SLT_DOUBLE: { + return Success(SolsType, charptr, {STT_DOUBLE}); + } + case SLT_STRING: { + return Success(SolsType, charptr, {STT_STRING}); + } + case SLT_BOOL: { + return Success(SolsType, charptr, {STT_BOOL}); + } + case SLT_CHAR: { + return Success(SolsType, charptr, {STT_CHAR}); + } + } + break; + } + case SNT_IDENTIFIER: { + SolsVariable* var = findSolsVariable(scope, node->as.idName); + if (var == NULL) { + Estr estr = CREATE_ESTR("Unable to find variable "); + APPEND_ESTR(estr, node->as.idName); + return Error(SolsType, charptr, estr.str); + } + return Success(SolsType, charptr, var->typeinfo); + } + } + return Error(SolsType, charptr, "Not yet implemented"); +} + static inline ResultType(GroundProgram, charptr) generateLiteralNode(SolsNode* node, SolsScope* scope) { // We don't even need to do anything lmao return Success(GroundProgram, charptr, groundCreateProgram()); @@ -34,11 +82,37 @@ static inline ResultType(GroundProgram, charptr) generatePutsNode(SolsNode* node } static inline ResultType(GroundProgram, charptr) generateSetNode(SolsNode* node, SolsScope* scope) { - if (node->children.count <= 2) { + if (node->children.count < 2) { return Error(GroundProgram, charptr, "set requires arguments"); } - return Error(GroundProgram, charptr, "WIP"); - addVariableToScope(scope, node->children.at[0].as.idName, NULL); + if (node->children.at[0].type != SNT_IDENTIFIER) { + return Error(GroundProgram, charptr, "set requires an identifier before '='"); + } + SolsVariable* var = findSolsVariable(scope, node->as.idName); + ResultType(SolsType, charptr) type = getNodeType(&node->children.at[1], scope); + if (type.error) { + return Error(GroundProgram, charptr, type.as.error); + } + if (var == NULL) { + addVariableToScope(scope, node->children.at[0].as.idName, type.as.success); + } else { + ResultType(SolsType, charptr) type = getNodeType(&node->children.at[0], scope); + if (type.error) { + return Error(GroundProgram, charptr, type.as.error); + } + if (compareTypes(&var->typeinfo, &type.as.success) == false) { + return Error(GroundProgram, charptr, "Type of variable cannot be changed"); + } + } + addVariableToScope(scope, node->children.at[0].as.idName, type.as.success); + + GroundProgram gp = groundCreateProgram(); + GroundInstruction gi = groundCreateInstruction(SET); + groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, node->children.at[0].as.idName)); + groundAddReferenceToInstruction(&gi, node->children.at[1].accessArg); + groundAddInstructionToProgram(&gp, gi); + + return Success(GroundProgram, charptr, gp); } ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope) { diff --git a/src/codegen/codegen.h b/src/codegen/codegen.h index e6886bf..fa98498 100644 --- a/src/codegen/codegen.h +++ b/src/codegen/codegen.h @@ -16,6 +16,9 @@ Result(GroundProgram, charptr); // Failure: charptr detailing what happened ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope); +// Gets the type of a node generated by the parser for the type checker. +ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope); + // Macro to help with code generation (and soon error handling) #define generate(nodetype) {\ ResultType(GroundProgram, charptr) __result = generate##nodetype##Node(node, scope);\ diff --git a/test.sols b/test.sols index f9d03fa..6e7e69f 100644 --- a/test.sols +++ b/test.sols @@ -1,7 +1,5 @@ // heheheha comment -puts "dinglefart" += x 5 +puts x -if 3 == 3 { - puts "3 is 3 lmao" -}