Add stuff

This commit is contained in:
2026-02-26 11:46:29 +11:00
parent 1bc4b7fa62
commit f5068fe861
5 changed files with 133 additions and 2 deletions

View File

@@ -13,6 +13,7 @@ typedef struct SolsVariable {
typedef struct SolsScope {
SolsVariable* variables;
size_t tmpCounter;
} SolsScope;
// Adds a variable to the SolsScope.

View File

@@ -30,6 +30,40 @@ ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope) {
}
return Success(SolsType, charptr, type.as.success);
}
case SNT_OP_ADD: {
if (node->children.count < 2) {
return Error(SolsType, charptr, "Not enough children to determine type");
}
ResultType(SolsType, charptr) leftType = getNodeType(&node->children.at[0], scope);
if (leftType.error) {
return Error(SolsType, charptr, leftType.as.error);
}
ResultType(SolsType, charptr) rightType = getNodeType(&node->children.at[1], scope);
if (rightType.error) {
return Error(SolsType, charptr, rightType.as.error);
}
if (!(leftType.as.success.type == STT_INT || leftType.as.success.type == STT_DOUBLE || leftType.as.success.type == STT_STRING)) {
return Error(SolsType, charptr, "Cannot add left type");
}
if (!(rightType.as.success.type == STT_INT || rightType.as.success.type == STT_DOUBLE || rightType.as.success.type == STT_STRING)) {
return Error(SolsType, charptr, "Cannot add right type");
}
if (leftType.as.success.type == rightType.as.success.type) {
return Success(SolsType, charptr, leftType.as.success);
}
if ((leftType.as.success.type == STT_INT && rightType.as.success.type == STT_DOUBLE) || (leftType.as.success.type == STT_DOUBLE && rightType.as.success.type == STT_INT)) {
ResultType(SolsType, charptr) type = createSolsType(STT_DOUBLE);
if (type.error) {
return Error(SolsType, charptr, type.as.error);
}
return Success(SolsType, charptr, type.as.success);
}
return Error(SolsType, charptr, "Cannot add these types together");
}
case SNT_LITERAL: {
switch (node->as.literal.type) {
case SLT_INT: {
@@ -115,6 +149,36 @@ static inline ResultType(GroundProgram, charptr) generateSetNode(SolsNode* node,
return Success(GroundProgram, charptr, gp);
}
static inline ResultType(GroundProgram, charptr) generateAddNode(SolsNode* node, SolsScope* scope) {
if (node->children.count < 2) {
return Error(GroundProgram, charptr, "add requires arguments");
}
// Use this function for type checking
ResultType(SolsType, charptr) type = getNodeType(node, scope);
if (type.error) {
return Error(GroundProgram, charptr, type.as.error);
}
GroundProgram gp = groundCreateProgram();
GroundInstruction add = groundCreateInstruction(ADD);
groundAddReferenceToInstruction(&add, node->children.at[0].accessArg);
groundAddReferenceToInstruction(&add, node->children.at[1].accessArg);
char* tmpId = malloc(sizeof(char) * 64);
if (tmpId == NULL) {
return Error(GroundProgram, charptr, "Failed to allocate memory for temporary identifier in add");
}
snprintf(tmpId, 64, "__SOLS_TMP_ADD_%zu", scope->tmpCounter++);
groundAddReferenceToInstruction(&add, groundCreateReference(DIRREF, tmpId));
node->accessArg = groundCreateReference(VALREF, tmpId);
groundAddInstructionToProgram(&gp, add);
return Success(GroundProgram, charptr, gp);
}
ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope) {
GroundProgram program = groundCreateProgram();
@@ -135,6 +199,7 @@ ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope
case SNT_PUTS: generate(Puts);
case SNT_LITERAL: generate(Literal);
case SNT_OP_SET: generate(Set);
case SNT_OP_ADD: generate(Add);
}
return Success(GroundProgram, charptr, program);
}

View File

@@ -73,7 +73,8 @@ int main(int argc, char** argv) {
}
SolsScope scope = {
.variables = NULL
.variables = NULL,
.tmpCounter = 0
};
// Do codegen on root node

View File

@@ -214,6 +214,69 @@ static inline ResultType(Nothing, charptr) parseSet(SolsParser* parser) {
return Success(Nothing, charptr, {});
}
static inline ResultType(Nothing, charptr) parseAdd(SolsParser* parser) {
if (parser->currentParent->children.count < 1) {
return Error(Nothing, charptr, "Expecting something before '+'");
}
// Collect tokens for node
ResultType(SolsTokens, charptr) tokens = createSolsTokens();
if (tokens.error) {
return Error(Nothing, charptr, tokens.as.error);
}
// Get the previous node
SolsNode idNode = parser->currentParent->children.at[parser->currentParent->children.count - 1];
ResultType(SolsToken, Nothing) peek = parserPeek(parser, 0);
if (peek.error) return Error(Nothing, charptr, "ruh roh");
for (;;) {
ResultType(SolsToken, Nothing) peek = parserPeek(parser, 1);
if (peek.error) break;
if (getPrecedence(&peek.as.success) <= STP_ADD) {
break;
}
parserConsume(parser);
addTokenToSolsTokens(&tokens.as.success, peek.as.success);
}
// Create node
ResultType(SolsNode, charptr) node = createSolsNode(SNT_OP_ADD);
if (node.error) return Error(Nothing, charptr, node.as.error);
node.as.success.line = peek.as.success.line;
// Parse selected tokens
ResultType(SolsParser, charptr) putsParser = createSolsParser(&tokens.as.success);
if (putsParser.error) return Error(Nothing, charptr, putsParser.as.error);
putsParser.as.success.currentParent = &putsParser.as.success.output;
ResultType(Nothing, charptr) parsed = parse(&putsParser.as.success);
// Add any error messages from parsing
if (parsed.error) {
addToParserErrors(parser, parsed.as.error);
return Success(Nothing, charptr, {});
}
if (putsParser.as.success.output.children.count < 1) {
return Error(Nothing, charptr, "Expecting token after '+'");
}
// Copy idnode into set node
addChildToSolsNode(&node.as.success, idNode);
// Copy nodes into the set node
for (size_t i = 0; i < putsParser.as.success.output.children.count; i++) {
addChildToSolsNode(&node.as.success, putsParser.as.success.output.children.at[i]);
}
// Put the set node where the idNode was
parser->currentParent->children.count--;
addChildToSolsNode(parser->currentParent, node.as.success);
return Success(Nothing, charptr, {});
}
static inline ResultType(Nothing, charptr) parseLiteral(SolsParser* parser) {
ResultType(SolsToken, Nothing) peek = parserPeek(parser, 0);
if (peek.error) {
@@ -317,6 +380,7 @@ ResultType(Nothing, charptr) parse(SolsParser* parser) {
case STT_LITERAL: PARSER_HANDLE(Literal);
case STT_KW_PUTS: PARSER_HANDLE(Puts);
case STT_OP_SET: PARSER_HANDLE(Set);
case STT_OP_ADD: PARSER_HANDLE(Add);
}
}
if (parser->errors.count > 0) {

View File

@@ -1,5 +1,5 @@
// heheheha comment
x = 5
puts x
puts x + 3