Variables (polish notation for now)

This commit is contained in:
2026-02-25 21:44:55 +11:00
parent cd204b7bc1
commit abc9728aa2
5 changed files with 90 additions and 12 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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) {

View File

@@ -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);\

View File

@@ -1,7 +1,5 @@
// heheheha comment
puts "dinglefart"
= x 5
puts x
if 3 == 3 {
puts "3 is 3 lmao"
}