From b46a66cea7ac2280d1779983943a4862b3d49e0a Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sun, 28 Dec 2025 13:41:05 +1100 Subject: [PATCH] Partially working function calling --- src/parser.cpp | 76 +++++++++++++++++++++++++++++++++++++++++++-- src/parser.h | 3 +- tests/function.sols | 8 +++-- 3 files changed, 80 insertions(+), 7 deletions(-) diff --git a/src/parser.cpp b/src/parser.cpp index bd1fca3..68cfac8 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2,6 +2,7 @@ #include "error.h" #include #include +#include #define parseOneToken(token) Parser({token}).parse().children[0] @@ -619,7 +620,54 @@ namespace Solstice { } exists(children[0]); std::string fnToCall = children[0].outputId; - + outputId = "tmp_" + std::to_string(tmpIdIterator++); + SolGroundCodeBlock codeBlock; + GroundInstruction callInstruction = groundCreateInstruction(CALL); + groundAddReferenceToInstruction(&callInstruction, groundCreateReference(FNREF, children[0].outputId.data())); + for (int i = 1; i < children.size(); i++) { + groundAddReferenceToInstruction(&callInstruction, groundCreateReference(VALREF, children[i].outputId.data())); + } + groundAddReferenceToInstruction(&callInstruction, groundCreateReference(DIRREF, outputId.data())); + codeBlock.code.push_back(callInstruction); + code.push_back(codeBlock); + break; + } + case SolNodeType::Return: { + SolGroundCodeBlock codeBlock; + GroundInstruction returnInstruction = groundCreateInstruction(RETURN); + groundAddReferenceToInstruction(&returnInstruction, groundCreateReference(VALREF, children[0].outputId.data())); + codeBlock.code.push_back(returnInstruction); + code.push_back(codeBlock); + break; + } + case SolNodeType::FunctionDef: { + auto functionopt = data.getFunction(); + if (functionopt.has_value()) { + SolFunction function = functionopt.value(); + SolGroundCodeBlock codeBlock; + GroundInstruction inst = groundCreateInstruction(FUN); + char* fnName = (char*) malloc(sizeof(char) * (function.name.size() + 1)); + strcpy(fnName, function.name.c_str()); + char* retType = (char*) malloc(sizeof(char) * (function.returnType.size() + 1)); + strcpy(retType, function.returnType.c_str()); + groundAddReferenceToInstruction(&inst, groundCreateReference(FNREF, fnName)); + groundAddReferenceToInstruction(&inst, groundCreateReference(TYPEREF, retType)); + auto variablebackup = variables; + variables.clear(); + for (auto& pair : function.parameters) { + groundAddReferenceToInstruction(&inst, groundCreateReference(TYPEREF, pair.second.data())); + groundAddReferenceToInstruction(&inst, groundCreateReference(DIRREF, pair.first.data())); + variables[pair.second] = pair.first; + } + variables = variablebackup; + codeBlock.code.push_back(inst); + code.push_back(codeBlock); + codeBlock.code.clear(); + auto childCode = function.content->generateCode(); + code.insert(code.end(), childCode.begin(), childCode.end()); + codeBlock.code.push_back(groundCreateInstruction(ENDFUN)); + code.push_back(codeBlock); + } break; } default: {} @@ -755,6 +803,9 @@ namespace Solstice { if (in == "def") { return SolNodeType::FunctionDef; } + if (in == "return") { + return SolNodeType::Return; + } if (in == "{") { return SolNodeType::CodeBlockStart; } @@ -850,6 +901,7 @@ namespace Solstice { } Error::syntaxError("Unexpected token in expression: " + token, tokenObj.line, tokenObj.lineContent); + return SolNode(SolNodeType::None); } SolNode Parser::parseExpression(int minPrec) { @@ -1188,7 +1240,7 @@ namespace Solstice { if (!nameTokenOpt || getNodeType(nameTokenOpt.value().value) != SolNodeType::Identifier) { Error::syntaxError("Expected function name", tokenObj.line, tokenObj.lineContent); } - std::string fnName = nameTokenOpt.value().value; + fn.name = nameTokenOpt.value().value; auto openParen = consume(); if (!openParen || openParen.value().value != "(") { @@ -1264,11 +1316,29 @@ namespace Solstice { SolNode fnNode(SolNodeType::FunctionDef); fnNode.data = SolData(fn); - variables[fnName] = signature; + variables[fn.name] = signature; rootNode.addNode(fnNode); break; } + case SolNodeType::Return: { + SolNode returnNode(SolNodeType::Return); + returnNode.line = tokenObj.line; + returnNode.lineContent = tokenObj.lineContent; + std::vector tokens; + while (auto tokenopt = consume()) { + if (tokenopt.value().value == "\n") { + break; + } + tokens.push_back(tokenopt.value()); + } + auto children = Parser(tokens).parse(); + for (auto& child : children.children) { + returnNode.addNode(child); + } + rootNode.addNode(returnNode); + break; + } } } return rootNode; diff --git a/src/parser.h b/src/parser.h index 55ee712..1f0dae0 100644 --- a/src/parser.h +++ b/src/parser.h @@ -57,7 +57,7 @@ namespace Solstice { enum class SolNodeType { - Add, Subtract, Multiply, Divide, Equal, Inequal, Greater, Lesser, EqGreater, EqLesser, Set, While, If, Value, Identifier, None, Root, CodeBlock, CodeBlockStart, CodeBlockEnd, FunctionDef, FunctionCall, Expression, BracketStart, BracketEnd, Puts + Add, Subtract, Multiply, Divide, Equal, Inequal, Greater, Lesser, EqGreater, EqLesser, Set, While, If, Value, Identifier, None, Root, CodeBlock, CodeBlockStart, CodeBlockEnd, FunctionDef, FunctionCall, Expression, BracketStart, BracketEnd, Puts, Return }; enum class SolDataType { @@ -81,6 +81,7 @@ namespace Solstice { std::vector> parameters; // name, type std::string returnType; std::shared_ptr content; + std::string name; SolFunction() = default; }; diff --git a/tests/function.sols b/tests/function.sols index 66f19d9..762a27f 100644 --- a/tests/function.sols +++ b/tests/function.sols @@ -1,4 +1,6 @@ -def add(int a, int b) { - return a + b +def add(int a, int b) int { + puts "testing" + return 3 } -add(1, 2) + +puts add(1 2)