forked from solstice/solstice
Partially working function calling
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include "error.h"
|
||||
#include <groundvm.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#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<Token> 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;
|
||||
|
||||
Reference in New Issue
Block a user