forked from solstice/solstice
Struct member writing
This commit is contained in:
@@ -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(<ype.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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user