Struct member writing

This commit is contained in:
2026-04-10 14:56:49 +10:00
parent fd08b7cdb7
commit 16569d7355
2 changed files with 62 additions and 24 deletions

View File

@@ -11,6 +11,7 @@
#include "../lexer/SolsType.h"
#include "../parser/parser.h"
#include "../parser/SolsNode.h"
#include "../typeparser/typeparser.h"
#include "../include/estr.h"
#include "../include/uthash.h"
#include "../include/ansii.h"
@@ -291,33 +292,60 @@ static inline ResultType(GroundProgram, charptr) generateSetNode(SolsNode* node,
if (node->children.count < 2) {
return Error(GroundProgram, charptr, "set requires arguments");
}
if (node->children.at[0].type != SNT_IDENTIFIER) {
return Error(GroundProgram, charptr, "set requires an identifier before '='");
}
SolsVariable* var = findSolsVariable(scope, node->children.at[0].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 (node->children.at[0].type == SNT_IDENTIFIER) {
SolsVariable* var = findSolsVariable(scope, node->children.at[0].as.idName);
ResultType(SolsType, charptr) type = getNodeType(&node->children.at[1], 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");
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");
}
}
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);
} else if (node->children.at[0].type == SNT_DOT) {
ResultType(SolsType, charptr) ltype = getNodeType(&node->children.at[0].children.at[0], scope);
if (ltype.error) {
return Error(GroundProgram, charptr, ltype.as.error);
}
ResultType(SolsType, charptr) rtype = getNodeType(&node->children.at[1], scope);
if (rtype.error) {
return Error(GroundProgram, charptr, rtype.as.error);
}
ResultType(SolsType, charptr) type = findStructMemberType(&ltype.as.success, node->children.at[0].children.at[1].as.idName);
if (type.error) {
return Error(GroundProgram, charptr, type.as.error);
}
if (compareTypes(&type.as.success, &rtype.as.success) == false) {
return Error(GroundProgram, charptr, "Type of member cannot be changed");
}
// TODO codegen for nested types
GroundProgram gp = groundCreateProgram();
GroundInstruction gi = groundCreateInstruction(SETFIELD);
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, node->children.at[0].children.at[0].accessArg.value.refName));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, node->children.at[0].children.at[1].as.idName));
groundAddReferenceToInstruction(&gi, node->children.at[1].accessArg);
groundAddInstructionToProgram(&gp, gi);
return Success(GroundProgram, charptr, gp);
} else {
return Error(GroundProgram, charptr, "set requires an identifier before '='");
}
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);
}
static inline ResultType(GroundProgram, charptr) generateAddNode(SolsNode* node, SolsScope* scope) {
@@ -976,8 +1004,16 @@ ResultType(GroundProgram, charptr) generateUseNode(SolsNode* node, SolsScope* sc
return Error(GroundProgram, charptr, "Error with use");
}
// Detect and parse types
ResultType(SolsTokens, charptr) typed = addTypeInfo(&lexer.as.success.output);
if (typed.error) {
printf("While parsing types in file %s:\n", filePath.str);
printf("%s\n", typed.as.error);
return Error(GroundProgram, charptr, "Error with use");
}
// Parse file
ResultType(SolsParser, charptr) parser = createSolsParser(&lexer.as.success.output);
ResultType(SolsParser, charptr) parser = createSolsParser(&typed.as.success);
if (parser.error) {
printf("While parsing file %s:\n", filePath.str);
printf("Error while creating parser: %s\n", parser.as.error);

View File

@@ -175,7 +175,8 @@ static inline ResultType(Nothing, charptr) parseSet(SolsParser* parser) {
if (parser->currentParent->children.count < 1) {
return Error(Nothing, charptr, "Expecting identifier before '='");
}
if (parser->currentParent->children.at[parser->output.children.count - 1].type != SNT_IDENTIFIER) {
if (parser->currentParent->children.at[parser->output.children.count - 1].type != SNT_IDENTIFIER &&
parser->currentParent->children.at[parser->output.children.count - 1].type != SNT_DOT) {
return Error(Nothing, charptr, "Expecting identifier before '='");
}
@@ -1837,6 +1838,7 @@ ResultType(Nothing, charptr) parseDot(SolsParser* parser) {
return Error(Nothing, charptr, "Expecting identifier after '.'");
}
addChildToSolsNode(&newNode.as.success, left);
parser->currentParent->children.count--;
addChildToSolsNode(&newNode.as.success, ({
ResultType(SolsNode, charptr) _result = createSolsNode(SNT_IDENTIFIER, right.as.success.as.idName);
if (_result.error) {