Use inbuilt stdlib instead of hard coded functions

This commit is contained in:
2026-01-12 16:18:59 +11:00
parent 48c130351a
commit 6d5d29f05b
4 changed files with 105 additions and 78 deletions

View File

@@ -5,7 +5,7 @@ LDFLAGS = -lgroundvm
BUILD_DIR = build BUILD_DIR = build
SRC_DIR = src SRC_DIR = src
SRCS = $(SRC_DIR)/main.cpp $(SRC_DIR)/argparser.cpp $(SRC_DIR)/lexer.cpp $(SRC_DIR)/parser.cpp $(SRC_DIR)/error.cpp SRCS = $(SRC_DIR)/main.cpp $(SRC_DIR)/argparser.cpp $(SRC_DIR)/lexer.cpp $(SRC_DIR)/parser.cpp $(SRC_DIR)/error.cpp $(SRC_DIR)/solstice_stdlib.cpp
OBJS = $(patsubst $(SRC_DIR)/%.cpp, $(BUILD_DIR)/%.o, $(SRCS)) OBJS = $(patsubst $(SRC_DIR)/%.cpp, $(BUILD_DIR)/%.o, $(SRCS))
TARGET = solstice TARGET = solstice

View File

@@ -1,14 +1,23 @@
#include "parser.h" #include "parser.h"
#include "error.h" #include "error.h"
#include "lexer.h"
#include "solstice_stdlib.h"
#include <groundvm.h> #include <groundvm.h>
#include <cstring> #include <cstring>
#include <string> #include <string>
#include <cstdlib>
#define parseOneToken(token) Parser({token}).parse().children[0] #define parseOneToken(token) Parser({token}).parse().children[0]
namespace Solstice { namespace Solstice {
namespace Parser { namespace Parser {
char* copyString(std::string s) {
char* str = (char*) malloc(s.size() + 1);
strcpy(str, s.c_str());
return str;
}
bool isTemp(std::string id) { bool isTemp(std::string id) {
return id.rfind("tmp_", 0) == 0; return id.rfind("tmp_", 0) == 0;
} }
@@ -56,13 +65,6 @@ namespace Solstice {
break; break;
} }
case SolNodeType::FunctionCall: { case SolNodeType::FunctionCall: {
if (i.children[0].outputId == "input") {
if (i.children.size() > 1) {
ensure(i.children[1], "string", "input function argument");
}
return "string";
}
std::string funcName = i.children[0].outputId; std::string funcName = i.children[0].outputId;
if (variables.find(funcName) == variables.end()) { if (variables.find(funcName) == variables.end()) {
Error::syntaxError("Unknown function " + funcName, i.line, i.lineContent); Error::syntaxError("Unknown function " + funcName, i.line, i.lineContent);
@@ -205,6 +207,12 @@ namespace Solstice {
const std::vector<SolGroundCodeBlock> SolNode::generateCode() { const std::vector<SolGroundCodeBlock> SolNode::generateCode() {
std::vector<SolGroundCodeBlock> code; std::vector<SolGroundCodeBlock> code;
if (nodeType == SolNodeType::Root) {
// Compile and insert standard library
auto parsedStdlib = Parser(Lexer(getStdLib()).lex()).parse();
parsedStdlib.nodeType = SolNodeType::None;
code = parsedStdlib.generateCode();
}
if (nodeType != SolNodeType::If && nodeType != SolNodeType::While) for (auto& child : children) { if (nodeType != SolNodeType::If && nodeType != SolNodeType::While) for (auto& child : children) {
auto childCode = child.generateCode(); auto childCode = child.generateCode();
code.insert(code.end(), childCode.begin(), childCode.end()); code.insert(code.end(), childCode.begin(), childCode.end());
@@ -214,7 +222,7 @@ namespace Solstice {
outputId = "tmp_" + std::to_string(tmpIdIterator++); outputId = "tmp_" + std::to_string(tmpIdIterator++);
SolGroundCodeBlock codeBlock; SolGroundCodeBlock codeBlock;
GroundInstruction gi = groundCreateInstruction(SET); GroundInstruction gi = groundCreateInstruction(SET);
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
switch (data.type) { switch (data.type) {
case SolDataType::Int: { case SolDataType::Int: {
auto dataopt = data.getInt(); auto dataopt = data.getInt();
@@ -268,9 +276,9 @@ namespace Solstice {
if (children.size() < 2) { if (children.size() < 2) {
Error::typingError("Need more stuff to add", children[0].line, children[0].lineContent); Error::typingError("Need more stuff to add", children[0].line, children[0].lineContent);
} }
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[1].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId); if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId);
if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId); if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId);
@@ -286,9 +294,9 @@ namespace Solstice {
if (children.size() < 2) { if (children.size() < 2) {
Error::typingError("Need more stuff to subtract", children[0].line, children[0].lineContent); Error::typingError("Need more stuff to subtract", children[0].line, children[0].lineContent);
} }
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[1].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId); if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId);
if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId); if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId);
@@ -304,9 +312,9 @@ namespace Solstice {
if (children.size() < 2) { if (children.size() < 2) {
Error::typingError("Need more stuff to multiply", children[0].line, children[0].lineContent); Error::typingError("Need more stuff to multiply", children[0].line, children[0].lineContent);
} }
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[1].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId); if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId);
if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId); if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId);
@@ -322,9 +330,9 @@ namespace Solstice {
if (children.size() < 2) { if (children.size() < 2) {
Error::typingError("Need more stuff to divide", children[0].line, children[0].lineContent); Error::typingError("Need more stuff to divide", children[0].line, children[0].lineContent);
} }
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[1].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId); if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId);
if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId); if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId);
@@ -339,9 +347,9 @@ namespace Solstice {
if (children.size() < 2) { if (children.size() < 2) {
Error::typingError("Need more stuff to equal", children[0].line, children[0].lineContent); Error::typingError("Need more stuff to equal", children[0].line, children[0].lineContent);
} }
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[1].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId); if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId);
if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId); if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId);
@@ -356,9 +364,9 @@ namespace Solstice {
if (children.size() < 2) { if (children.size() < 2) {
Error::typingError("Need more stuff to inequal", children[0].line, children[0].lineContent); Error::typingError("Need more stuff to inequal", children[0].line, children[0].lineContent);
} }
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[1].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId); if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId);
if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId); if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId);
@@ -373,9 +381,9 @@ namespace Solstice {
if (children.size() < 2) { if (children.size() < 2) {
Error::typingError("Need more stuff to greater", children[0].line, children[0].lineContent); Error::typingError("Need more stuff to greater", children[0].line, children[0].lineContent);
} }
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[1].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId); if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId);
if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId); if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId);
@@ -390,9 +398,9 @@ namespace Solstice {
if (children.size() < 2) { if (children.size() < 2) {
Error::typingError("Need more stuff to lesser", children[0].line, children[0].lineContent); Error::typingError("Need more stuff to lesser", children[0].line, children[0].lineContent);
} }
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[1].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId); if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId);
if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId); if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId);
@@ -417,8 +425,8 @@ namespace Solstice {
strcpy(endLabelId, endLabelIdString.data()); strcpy(endLabelId, endLabelIdString.data());
// greater $tmp_0 $tmp_1 &cond // greater $tmp_0 $tmp_1 &cond
GroundInstruction gi = groundCreateInstruction(GREATER); GroundInstruction gi = groundCreateInstruction(GREATER);
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[1].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, (char*) "internal_cond0")); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, (char*) "internal_cond0"));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// if &cond %true // if &cond %true
@@ -428,8 +436,8 @@ namespace Solstice {
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// equal $tmp_0 $tmp_1 &cond // equal $tmp_0 $tmp_1 &cond
gi = groundCreateInstruction(EQUAL); gi = groundCreateInstruction(EQUAL);
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[1].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, (char*) "internal_cond1")); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, (char*) "internal_cond1"));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// if $cond %true // if $cond %true
@@ -447,7 +455,7 @@ namespace Solstice {
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// set &tmp_x true // set &tmp_x true
gi = groundCreateInstruction(SET); gi = groundCreateInstruction(SET);
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
groundAddValueToInstruction(&gi, groundCreateValue(BOOL, true)); groundAddValueToInstruction(&gi, groundCreateValue(BOOL, true));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// jump %end // jump %end
@@ -460,7 +468,7 @@ namespace Solstice {
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// set &tmp_x false // set &tmp_x false
gi = groundCreateInstruction(SET); gi = groundCreateInstruction(SET);
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
groundAddValueToInstruction(&gi, groundCreateValue(BOOL, false)); groundAddValueToInstruction(&gi, groundCreateValue(BOOL, false));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// @end // @end
@@ -490,8 +498,8 @@ namespace Solstice {
strcpy(endLabelId, endLabelIdString.data()); strcpy(endLabelId, endLabelIdString.data());
// lesser $tmp_0 $tmp_1 &cond // lesser $tmp_0 $tmp_1 &cond
GroundInstruction gi = groundCreateInstruction(LESSER); GroundInstruction gi = groundCreateInstruction(LESSER);
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[1].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, (char*) "internal_cond0")); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, (char*) "internal_cond0"));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// if &cond %true // if &cond %true
@@ -501,8 +509,8 @@ namespace Solstice {
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// equal $tmp_0 $tmp_1 &cond // equal $tmp_0 $tmp_1 &cond
gi = groundCreateInstruction(EQUAL); gi = groundCreateInstruction(EQUAL);
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[1].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, (char*) "internal_cond1")); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, (char*) "internal_cond1"));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// if $cond %true // if $cond %true
@@ -520,7 +528,7 @@ namespace Solstice {
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// set &tmp_x true // set &tmp_x true
gi = groundCreateInstruction(SET); gi = groundCreateInstruction(SET);
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
groundAddValueToInstruction(&gi, groundCreateValue(BOOL, true)); groundAddValueToInstruction(&gi, groundCreateValue(BOOL, true));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// jump %end // jump %end
@@ -533,7 +541,7 @@ namespace Solstice {
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// set &tmp_x false // set &tmp_x false
gi = groundCreateInstruction(SET); gi = groundCreateInstruction(SET);
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
groundAddValueToInstruction(&gi, groundCreateValue(BOOL, false)); groundAddValueToInstruction(&gi, groundCreateValue(BOOL, false));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
// @end // @end
@@ -552,7 +560,7 @@ namespace Solstice {
if (children.size() < 1) { if (children.size() < 1) {
Error::typingError("Need more stuff to puts", children[0].line, children[0].lineContent); Error::typingError("Need more stuff to puts", children[0].line, children[0].lineContent);
} }
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId); if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId);
code.push_back(codeBlock); code.push_back(codeBlock);
@@ -567,14 +575,14 @@ namespace Solstice {
codeBlock.toBeDropped.push_back(outputId); codeBlock.toBeDropped.push_back(outputId);
if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId); if (isTemp(children[0].outputId)) codeBlock.toBeDropped.push_back(children[0].outputId);
GroundInstruction gi = groundCreateInstruction(NOT); GroundInstruction gi = groundCreateInstruction(NOT);
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
codeBlock.code.push_back(gi); codeBlock.code.push_back(gi);
std::string labelIdString = "if_" + std::to_string(labelIterator++); std::string labelIdString = "if_" + std::to_string(labelIterator++);
char* labelId = (char*) malloc(sizeof(char) * labelIdString.size() + 1); char* labelId = (char*) malloc(sizeof(char) * labelIdString.size() + 1);
strcpy(labelId, labelIdString.data()); strcpy(labelId, labelIdString.data());
GroundInstruction gi2 = groundCreateInstruction(IF); GroundInstruction gi2 = groundCreateInstruction(IF);
groundAddReferenceToInstruction(&gi2, groundCreateReference(VALREF, outputId.data())); groundAddReferenceToInstruction(&gi2, groundCreateReference(VALREF, copyString(outputId)));
groundAddReferenceToInstruction(&gi2, groundCreateReference(LINEREF, labelId)); groundAddReferenceToInstruction(&gi2, groundCreateReference(LINEREF, labelId));
codeBlock.code.push_back(gi2); codeBlock.code.push_back(gi2);
code.push_back(codeBlock); code.push_back(codeBlock);
@@ -613,11 +621,11 @@ namespace Solstice {
checkBlock.toBeDropped.push_back(outputId); checkBlock.toBeDropped.push_back(outputId);
if (isTemp(children[0].outputId)) checkBlock.toBeDropped.push_back(children[0].outputId); if (isTemp(children[0].outputId)) checkBlock.toBeDropped.push_back(children[0].outputId);
GroundInstruction gi = groundCreateInstruction(NOT); GroundInstruction gi = groundCreateInstruction(NOT);
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
checkBlock.code.push_back(gi); checkBlock.code.push_back(gi);
GroundInstruction gi2 = groundCreateInstruction(IF); GroundInstruction gi2 = groundCreateInstruction(IF);
groundAddReferenceToInstruction(&gi2, groundCreateReference(VALREF, outputId.data())); groundAddReferenceToInstruction(&gi2, groundCreateReference(VALREF, copyString(outputId)));
groundAddReferenceToInstruction(&gi2, groundCreateReference(LINEREF, endLabelId)); groundAddReferenceToInstruction(&gi2, groundCreateReference(LINEREF, endLabelId));
checkBlock.code.push_back(gi2); checkBlock.code.push_back(gi2);
code.push_back(checkBlock); code.push_back(checkBlock);
@@ -649,8 +657,8 @@ namespace Solstice {
exists(children[1]); exists(children[1]);
SolGroundCodeBlock codeBlock; SolGroundCodeBlock codeBlock;
GroundInstruction setInstruction = groundCreateInstruction(SET); GroundInstruction setInstruction = groundCreateInstruction(SET);
groundAddReferenceToInstruction(&setInstruction, groundCreateReference(DIRREF, children[0].outputId.data())); groundAddReferenceToInstruction(&setInstruction, groundCreateReference(DIRREF, copyString(children[0].outputId)));
groundAddReferenceToInstruction(&setInstruction, groundCreateReference(VALREF, children[1].outputId.data())); groundAddReferenceToInstruction(&setInstruction, groundCreateReference(VALREF, copyString(children[1].outputId)));
codeBlock.code.push_back(setInstruction); codeBlock.code.push_back(setInstruction);
if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId); if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId);
code.push_back(codeBlock); code.push_back(codeBlock);
@@ -660,34 +668,16 @@ namespace Solstice {
} }
case SolNodeType::FunctionCall: { case SolNodeType::FunctionCall: {
checkNodeReturnType(*this); checkNodeReturnType(*this);
// Take care of in built functions
// This will be removed when inline ground is added
if (children[0].outputId == "input") {
ensure(children[1], "string", "input function argument");
SolGroundCodeBlock inputCodeBlock;
if (children.size() > 1) {
GroundInstruction printInstruction = groundCreateInstruction(PRINT);
groundAddReferenceToInstruction(&printInstruction, groundCreateReference(VALREF, children[1].outputId.data()));
inputCodeBlock.code.push_back(printInstruction);
if (isTemp(children[1].outputId)) inputCodeBlock.toBeDropped.push_back(children[1].outputId);
}
GroundInstruction inputInstruction = groundCreateInstruction(INPUT);
outputId = "tmp_" + std::to_string(tmpIdIterator++);
groundAddReferenceToInstruction(&inputInstruction, groundCreateReference(DIRREF, outputId.data()));
inputCodeBlock.code.push_back(inputInstruction);
code.push_back(inputCodeBlock);
break;
}
exists(children[0]); exists(children[0]);
std::string fnToCall = children[0].outputId; std::string fnToCall = children[0].outputId;
outputId = "tmp_" + std::to_string(tmpIdIterator++); outputId = "tmp_" + std::to_string(tmpIdIterator++);
SolGroundCodeBlock codeBlock; SolGroundCodeBlock codeBlock;
GroundInstruction callInstruction = groundCreateInstruction(CALL); GroundInstruction callInstruction = groundCreateInstruction(CALL);
groundAddReferenceToInstruction(&callInstruction, groundCreateReference(FNREF, children[0].outputId.data())); groundAddReferenceToInstruction(&callInstruction, groundCreateReference(FNREF, copyString(children[0].outputId)));
for (int i = 1; i < children.size(); i++) { for (int i = 1; i < children.size(); i++) {
groundAddReferenceToInstruction(&callInstruction, groundCreateReference(VALREF, children[i].outputId.data())); groundAddReferenceToInstruction(&callInstruction, groundCreateReference(VALREF, copyString(children[i].outputId)));
} }
groundAddReferenceToInstruction(&callInstruction, groundCreateReference(DIRREF, outputId.data())); groundAddReferenceToInstruction(&callInstruction, groundCreateReference(DIRREF, copyString(outputId)));
codeBlock.code.push_back(callInstruction); codeBlock.code.push_back(callInstruction);
code.push_back(codeBlock); code.push_back(codeBlock);
break; break;
@@ -699,7 +689,7 @@ namespace Solstice {
} }
SolGroundCodeBlock codeBlock; SolGroundCodeBlock codeBlock;
GroundInstruction returnInstruction = groundCreateInstruction(RETURN); GroundInstruction returnInstruction = groundCreateInstruction(RETURN);
groundAddReferenceToInstruction(&returnInstruction, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&returnInstruction, groundCreateReference(VALREF, copyString(children[0].outputId)));
codeBlock.code.push_back(returnInstruction); codeBlock.code.push_back(returnInstruction);
code.push_back(codeBlock); code.push_back(codeBlock);
break; break;
@@ -725,8 +715,8 @@ namespace Solstice {
currentFunctionRetType = function.returnType; currentFunctionRetType = function.returnType;
for (auto& pair : function.parameters) { for (auto& pair : function.parameters) {
groundAddReferenceToInstruction(&inst, groundCreateReference(TYPEREF, pair.second.data())); groundAddReferenceToInstruction(&inst, groundCreateReference(TYPEREF, copyString(pair.second)));
groundAddReferenceToInstruction(&inst, groundCreateReference(DIRREF, pair.first.data())); groundAddReferenceToInstruction(&inst, groundCreateReference(DIRREF, copyString(pair.first)));
variables[pair.first] = pair.second; // Correctly map Name -> Type variables[pair.first] = pair.second; // Correctly map Name -> Type
} }

34
src/solstice_stdlib.cpp Normal file
View File

@@ -0,0 +1,34 @@
#include <string>
std::string getStdLib() {
return R"(
// Solstice stdlib
def input(string msg) string {
retval = ""
ground {
print $msg
input &retval
}
return retval
}
def print(string msg) string {
ground {
print $msg
}
return msg
}
def println(string msg) string {
ground {
println $msg
}
return msg
}
// End Solstice stdlib
)";
}

3
src/solstice_stdlib.h Normal file
View File

@@ -0,0 +1,3 @@
#include <string>
std::string getStdLib();