forked from solstice/solstice
Better errors, comments
This commit is contained in:
225
src/parser.cpp
225
src/parser.cpp
@@ -4,7 +4,7 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
#define parseOneToken(token) Parser({token.value()}).parse().children[0]
|
||||
#define parseOneToken(token) Parser({token}).parse().children[0]
|
||||
|
||||
namespace Solstice {
|
||||
namespace Parser {
|
||||
@@ -21,7 +21,7 @@ namespace Solstice {
|
||||
if (variables.find(i.outputId) != variables.end()) {
|
||||
return variables[i.outputId];
|
||||
} else {
|
||||
Error::syntaxError("Unknown variable");
|
||||
Error::syntaxError("Unknown variable", i.line, i.lineContent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -178,14 +178,14 @@ namespace Solstice {
|
||||
break;
|
||||
}
|
||||
case SolNodeType::Add: {
|
||||
ensure3(children[0], SolDataType::Int, SolDataType::Double, SolDataType::String);
|
||||
ensure3(children[1], SolDataType::Int, SolDataType::Double, SolDataType::String);
|
||||
ensuresame(children[0], children[1]);
|
||||
ensure3(children[0], SolDataType::Int, SolDataType::Double, SolDataType::String, "operator '+'");
|
||||
ensure3(children[1], SolDataType::Int, SolDataType::Double, SolDataType::String, "operator '+'");
|
||||
ensuresame(children[0], children[1], "operator '+'");
|
||||
SolGroundCodeBlock codeBlock;
|
||||
outputId = "tmp_" + std::to_string(tmpIdIterator++);
|
||||
GroundInstruction gi = groundCreateInstruction(ADD);
|
||||
if (children.size() < 2) {
|
||||
std::cout << "Need more stuff to add\n";
|
||||
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, children[1].outputId.data()));
|
||||
@@ -197,13 +197,13 @@ namespace Solstice {
|
||||
break;
|
||||
}
|
||||
case SolNodeType::Subtract: {
|
||||
ensure2(children[0], SolDataType::Int, SolDataType::Double);
|
||||
ensure2(children[1], SolDataType::Int, SolDataType::Double);
|
||||
ensure2(children[0], SolDataType::Int, SolDataType::Double, "operator '-'");
|
||||
ensure2(children[1], SolDataType::Int, SolDataType::Double, "operator '-'");
|
||||
SolGroundCodeBlock codeBlock;
|
||||
outputId = "tmp_" + std::to_string(tmpIdIterator++);
|
||||
GroundInstruction gi = groundCreateInstruction(SUBTRACT);
|
||||
if (children.size() < 2) {
|
||||
std::cout << "Need more stuff to add\n";
|
||||
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, children[1].outputId.data()));
|
||||
@@ -215,13 +215,13 @@ namespace Solstice {
|
||||
break;
|
||||
}
|
||||
case SolNodeType::Multiply: {
|
||||
ensure2(children[0], SolDataType::Int, SolDataType::Double);
|
||||
ensure2(children[1], SolDataType::Int, SolDataType::Double);
|
||||
ensure2(children[0], SolDataType::Int, SolDataType::Double, "operator '*'");
|
||||
ensure2(children[1], SolDataType::Int, SolDataType::Double, "operator '*'");
|
||||
SolGroundCodeBlock codeBlock;
|
||||
outputId = "tmp_" + std::to_string(tmpIdIterator++);
|
||||
GroundInstruction gi = groundCreateInstruction(MULTIPLY);
|
||||
if (children.size() < 2) {
|
||||
std::cout << "Need more stuff to add\n";
|
||||
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, children[1].outputId.data()));
|
||||
@@ -233,13 +233,13 @@ namespace Solstice {
|
||||
break;
|
||||
}
|
||||
case SolNodeType::Divide: {
|
||||
ensure2(children[0], SolDataType::Int, SolDataType::Double);
|
||||
ensure2(children[1], SolDataType::Int, SolDataType::Double);
|
||||
ensure2(children[0], SolDataType::Int, SolDataType::Double, "operator '/'");
|
||||
ensure2(children[1], SolDataType::Int, SolDataType::Double, "operator '/'");
|
||||
SolGroundCodeBlock codeBlock;
|
||||
outputId = "tmp_" + std::to_string(tmpIdIterator++);
|
||||
GroundInstruction gi = groundCreateInstruction(DIVIDE);
|
||||
if (children.size() < 2) {
|
||||
std::cout << "Need more stuff to add\n";
|
||||
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, children[1].outputId.data()));
|
||||
@@ -251,12 +251,12 @@ namespace Solstice {
|
||||
break;
|
||||
}
|
||||
case SolNodeType::Equal: {
|
||||
ensuresame(children[0], children[1]);
|
||||
ensuresame(children[0], children[1], "operator '=='");
|
||||
SolGroundCodeBlock codeBlock;
|
||||
outputId = "tmp_" + std::to_string(tmpIdIterator++);
|
||||
GroundInstruction gi = groundCreateInstruction(EQUAL);
|
||||
if (children.size() < 2) {
|
||||
std::cout << "Need more stuff to equal\n";
|
||||
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, children[1].outputId.data()));
|
||||
@@ -268,12 +268,12 @@ namespace Solstice {
|
||||
break;
|
||||
}
|
||||
case SolNodeType::Inequal: {
|
||||
ensuresame(children[0], children[1]);
|
||||
ensuresame(children[0], children[1], "operator '!='");
|
||||
SolGroundCodeBlock codeBlock;
|
||||
outputId = "tmp_" + std::to_string(tmpIdIterator++);
|
||||
GroundInstruction gi = groundCreateInstruction(INEQUAL);
|
||||
if (children.size() < 2) {
|
||||
std::cout << "Need more stuff to inequal\n";
|
||||
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, children[1].outputId.data()));
|
||||
@@ -285,12 +285,12 @@ namespace Solstice {
|
||||
break;
|
||||
}
|
||||
case SolNodeType::Greater: {
|
||||
ensuresame(children[0], children[1]);
|
||||
ensuresame(children[0], children[1], "operator '>'");
|
||||
SolGroundCodeBlock codeBlock;
|
||||
outputId = "tmp_" + std::to_string(tmpIdIterator++);
|
||||
GroundInstruction gi = groundCreateInstruction(GREATER);
|
||||
if (children.size() < 2) {
|
||||
std::cout << "Need more stuff to greater\n";
|
||||
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, children[1].outputId.data()));
|
||||
@@ -302,12 +302,12 @@ namespace Solstice {
|
||||
break;
|
||||
}
|
||||
case SolNodeType::Lesser: {
|
||||
ensuresame(children[0], children[1]);
|
||||
ensuresame(children[0], children[1], "operator '<'");
|
||||
SolGroundCodeBlock codeBlock;
|
||||
outputId = "tmp_" + std::to_string(tmpIdIterator++);
|
||||
GroundInstruction gi = groundCreateInstruction(LESSER);
|
||||
if (children.size() < 2) {
|
||||
std::cout << "Need more stuff to lesser\n";
|
||||
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, children[1].outputId.data()));
|
||||
@@ -319,10 +319,10 @@ namespace Solstice {
|
||||
break;
|
||||
}
|
||||
case SolNodeType::EqGreater: {
|
||||
ensuresame(children[0], children[1]);
|
||||
ensuresame(children[0], children[1], "operator '>='");
|
||||
SolGroundCodeBlock codeBlock;
|
||||
if (children.size() < 2) {
|
||||
std::cout << "Need more stuff to inequal\n";
|
||||
Error::typingError("Need more stuff to inequal", children[0].line, children[0].lineContent);
|
||||
}
|
||||
outputId = "tmp_" + std::to_string(tmpIdIterator++);
|
||||
std::string trueLabelIdString = "internal_true" + std::to_string(labelIterator++);
|
||||
@@ -392,10 +392,10 @@ namespace Solstice {
|
||||
break;
|
||||
}
|
||||
case SolNodeType::EqLesser: {
|
||||
ensuresame(children[0], children[1]);
|
||||
ensuresame(children[0], children[1], "operator '<='");
|
||||
SolGroundCodeBlock codeBlock;
|
||||
if (children.size() < 2) {
|
||||
std::cout << "Need more stuff to inequal\n";
|
||||
Error::typingError("Need more stuff to inequal", children[0].line, children[0].lineContent);
|
||||
}
|
||||
outputId = "tmp_" + std::to_string(tmpIdIterator++);
|
||||
std::string trueLabelIdString = "internal_true" + std::to_string(labelIterator++);
|
||||
@@ -469,7 +469,7 @@ namespace Solstice {
|
||||
exists(children[0]);
|
||||
GroundInstruction gi = groundCreateInstruction(PRINTLN);
|
||||
if (children.size() < 1) {
|
||||
std::cout << "Need more stuff to puts\n";
|
||||
Error::typingError("Need more stuff to puts", children[0].line, children[0].lineContent);
|
||||
}
|
||||
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data()));
|
||||
codeBlock.code.push_back(gi);
|
||||
@@ -478,7 +478,7 @@ namespace Solstice {
|
||||
break;
|
||||
}
|
||||
case SolNodeType::If: {
|
||||
ensure(children[0], SolDataType::Bool);
|
||||
ensure(children[0], SolDataType::Bool, "if condition");
|
||||
auto conditionCode = children[0].generateCode();
|
||||
code.insert(code.end(), conditionCode.begin(), conditionCode.end());
|
||||
outputId = "tmp_" + std::to_string(tmpIdIterator++);
|
||||
@@ -510,7 +510,7 @@ namespace Solstice {
|
||||
break;
|
||||
}
|
||||
case SolNodeType::While: {
|
||||
ensure(children[0], SolDataType::Bool);
|
||||
ensure(children[0], SolDataType::Bool, "while condition");
|
||||
SolGroundCodeBlock startLabelBlock;
|
||||
std::string startLabelIdString = "whilestart_" + std::to_string(labelIterator++);
|
||||
std::string endLabelIdString = "whileend_" + std::to_string(labelIterator);
|
||||
@@ -562,7 +562,7 @@ namespace Solstice {
|
||||
case SolNodeType::Set: {
|
||||
if (variables.find(children[0].outputId) != variables.end()) {
|
||||
if (variables[children[0].outputId] != checkNodeReturnType(children[1])) {
|
||||
Error::typingError("Cannot change type of this variable");
|
||||
Error::typingError("Cannot change type of this variable", children[0].line, children[0].lineContent);
|
||||
}
|
||||
}
|
||||
exists(children[1]);
|
||||
@@ -580,7 +580,7 @@ namespace Solstice {
|
||||
case SolNodeType::FunctionCall: {
|
||||
// Take care of in built functions
|
||||
if (children[0].outputId == "input") {
|
||||
ensure(children[1], SolDataType::String);
|
||||
ensure(children[1], SolDataType::String, "input function argument");
|
||||
SolGroundCodeBlock inputCodeBlock;
|
||||
if (children.size() > 1) {
|
||||
GroundInstruction printInstruction = groundCreateInstruction(PRINT);
|
||||
@@ -604,9 +604,9 @@ namespace Solstice {
|
||||
}
|
||||
|
||||
// Parser Implementation
|
||||
Parser::Parser(std::vector<std::string> in) : tokensToParse(in) {}
|
||||
Parser::Parser(std::vector<Token> in) : tokensToParse(in) {}
|
||||
|
||||
std::optional<std::string> Parser::peek(int ahead) {
|
||||
std::optional<Token> Parser::peek(int ahead) {
|
||||
if (current + ahead < size) {
|
||||
return tokensToParse[current + ahead];
|
||||
} else {
|
||||
@@ -614,7 +614,7 @@ namespace Solstice {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::string> Parser::consume() {
|
||||
std::optional<Token> Parser::consume() {
|
||||
if (current < size) {
|
||||
return tokensToParse[current++];
|
||||
} else {
|
||||
@@ -752,14 +752,16 @@ namespace Solstice {
|
||||
SolNode Parser::parsePrimary() {
|
||||
auto tokenopt = consume();
|
||||
if (!tokenopt) {
|
||||
std::cout << "Unexpected end of input\n";
|
||||
exit(1);
|
||||
Error::syntaxError("Unexpected end of input");
|
||||
}
|
||||
std::string token = tokenopt.value();
|
||||
Token tokenObj = tokenopt.value();
|
||||
std::string token = tokenObj.value;
|
||||
SolNodeType type = getNodeType(token);
|
||||
|
||||
if (type == SolNodeType::Value) {
|
||||
SolNode node(SolNodeType::Value);
|
||||
node.line = tokenObj.line;
|
||||
node.lineContent = tokenObj.lineContent;
|
||||
switch (getDataType(token)) {
|
||||
case SolDataType::Int: node.setValue((int64_t) std::stoll(token)); break;
|
||||
case SolDataType::Double: node.setValue(std::stod(token)); break;
|
||||
@@ -774,19 +776,28 @@ namespace Solstice {
|
||||
if (type == SolNodeType::Identifier) {
|
||||
SolNode idNode(SolNodeType::Identifier);
|
||||
idNode.outputId = token;
|
||||
if (peek().value_or("") == "(") {
|
||||
idNode.line = tokenObj.line;
|
||||
idNode.lineContent = tokenObj.lineContent;
|
||||
|
||||
auto peekOpt = peek();
|
||||
if (peekOpt.has_value() && peekOpt.value().value == "(") {
|
||||
consume(); // (
|
||||
SolNode fnCallNode(SolNodeType::FunctionCall);
|
||||
fnCallNode.line = tokenObj.line;
|
||||
fnCallNode.lineContent = tokenObj.lineContent;
|
||||
fnCallNode.addNode(idNode);
|
||||
|
||||
std::vector<std::string> tokens;
|
||||
std::vector<Token> tokens;
|
||||
size_t brackets = 1;
|
||||
while (auto t = consume()) {
|
||||
if (t.value() == "(") brackets++;
|
||||
if (t.value() == ")") brackets--;
|
||||
if (t.value().value == "(") brackets++;
|
||||
if (t.value().value == ")") brackets--;
|
||||
if (brackets == 0) break;
|
||||
tokens.push_back(t.value());
|
||||
}
|
||||
if (brackets != 0) {
|
||||
Error::syntaxError("Unclosed function call bracket", tokenObj.line, tokenObj.lineContent);
|
||||
}
|
||||
auto args = Parser(tokens).parse();
|
||||
for(auto& child : args.children) fnCallNode.addNode(child);
|
||||
return fnCallNode;
|
||||
@@ -795,21 +806,23 @@ namespace Solstice {
|
||||
}
|
||||
|
||||
if (type == SolNodeType::BracketStart) {
|
||||
std::vector<std::string> tokens;
|
||||
std::vector<Token> tokens;
|
||||
size_t brackets = 1;
|
||||
while (auto t = consume()) {
|
||||
if (t.value() == "(") brackets++;
|
||||
if (t.value() == ")") brackets--;
|
||||
if (t.value().value == "(") brackets++;
|
||||
if (t.value().value == ")") brackets--;
|
||||
if (brackets == 0) break;
|
||||
tokens.push_back(t.value());
|
||||
}
|
||||
if (brackets != 0) {
|
||||
Error::syntaxError("Unclosed bracket", tokenObj.line, tokenObj.lineContent);
|
||||
}
|
||||
auto inner = Parser(tokens).parse();
|
||||
if (inner.children.size() > 0) return inner.children[0];
|
||||
return SolNode(SolNodeType::None);
|
||||
}
|
||||
|
||||
std::cout << "Unexpected token in expression: " << token << "\n";
|
||||
exit(1);
|
||||
Error::syntaxError("Unexpected token in expression: " + token, tokenObj.line, tokenObj.lineContent);
|
||||
}
|
||||
|
||||
SolNode Parser::parseExpression(int minPrec) {
|
||||
@@ -817,13 +830,16 @@ namespace Solstice {
|
||||
while(true) {
|
||||
auto opOpt = peek();
|
||||
if (!opOpt) break;
|
||||
std::string op = opOpt.value();
|
||||
Token opToken = opOpt.value();
|
||||
std::string op = opToken.value;
|
||||
int prec = getPrecedence(op);
|
||||
if (prec < minPrec) break;
|
||||
|
||||
consume();
|
||||
SolNode rhs = parseExpression(prec + 1);
|
||||
SolNode newNode(getNodeType(op));
|
||||
newNode.line = opToken.line;
|
||||
newNode.lineContent = opToken.lineContent;
|
||||
newNode.addNode(lhs);
|
||||
newNode.addNode(rhs);
|
||||
lhs = newNode;
|
||||
@@ -836,37 +852,48 @@ namespace Solstice {
|
||||
size = tokensToParse.size();
|
||||
SolNode rootNode(SolNodeType::Root);
|
||||
while (auto tokenopt = consume()) {
|
||||
std::string token = tokenopt.value();
|
||||
Token tokenObj = tokenopt.value();
|
||||
std::string token = tokenObj.value;
|
||||
switch (getNodeType(token)) {
|
||||
case SolNodeType::Value: {
|
||||
switch (getDataType(token)) {
|
||||
case SolDataType::Int: {
|
||||
SolNode intNode(SolNodeType::Value);
|
||||
intNode.setValue((int64_t) std::stoll(token));
|
||||
intNode.line = tokenObj.line;
|
||||
intNode.lineContent = tokenObj.lineContent;
|
||||
rootNode.addNode(intNode);
|
||||
break;
|
||||
}
|
||||
case SolDataType::Double: {
|
||||
SolNode doubleNode(SolNodeType::Value);
|
||||
doubleNode.setValue(std::stod(token));
|
||||
doubleNode.line = tokenObj.line;
|
||||
doubleNode.lineContent = tokenObj.lineContent;
|
||||
rootNode.addNode(doubleNode);
|
||||
break;
|
||||
}
|
||||
case SolDataType::String: {
|
||||
SolNode stringNode(SolNodeType::Value);
|
||||
stringNode.setValue(token.substr(1, token.size() - 2));
|
||||
stringNode.line = tokenObj.line;
|
||||
stringNode.lineContent = tokenObj.lineContent;
|
||||
rootNode.addNode(stringNode);
|
||||
break;
|
||||
}
|
||||
case SolDataType::Char: {
|
||||
SolNode charNode(SolNodeType::Value);
|
||||
charNode.setValue(token[1]);
|
||||
charNode.line = tokenObj.line;
|
||||
charNode.lineContent = tokenObj.lineContent;
|
||||
rootNode.addNode(charNode);
|
||||
break;
|
||||
}
|
||||
case SolDataType::Bool: {
|
||||
SolNode boolNode(SolNodeType::Value);
|
||||
boolNode.setValue(token == "true");
|
||||
boolNode.line = tokenObj.line;
|
||||
boolNode.lineContent = tokenObj.lineContent;
|
||||
rootNode.addNode(boolNode);
|
||||
break;
|
||||
}
|
||||
@@ -879,9 +906,11 @@ namespace Solstice {
|
||||
case SolNodeType::Divide:
|
||||
{
|
||||
SolNode opNode(getNodeType(token));
|
||||
opNode.line = tokenObj.line;
|
||||
opNode.lineContent = tokenObj.lineContent;
|
||||
|
||||
if (rootNode.children.empty()) {
|
||||
std::cout << "Expected operand before operator\n";
|
||||
exit(1);
|
||||
Error::syntaxError("Expected operand before operator", tokenObj.line, tokenObj.lineContent);
|
||||
}
|
||||
opNode.addNode(rootNode.children.back());
|
||||
rootNode.children.pop_back();
|
||||
@@ -901,15 +930,17 @@ namespace Solstice {
|
||||
case SolNodeType::EqGreater:
|
||||
{
|
||||
SolNode equalNode(getNodeType(token));
|
||||
equalNode.line = tokenObj.line;
|
||||
equalNode.lineContent = tokenObj.lineContent;
|
||||
|
||||
if (rootNode.children.empty()) {
|
||||
std::cout << "ah dingus\n";
|
||||
exit(1);
|
||||
Error::syntaxError("Expected operand before comparison", tokenObj.line, tokenObj.lineContent);
|
||||
}
|
||||
equalNode.addNode(rootNode.children.back());
|
||||
rootNode.children.pop_back();
|
||||
std::vector<std::string> tokens;
|
||||
std::vector<Token> tokens;
|
||||
while (auto tokenopt = consume()) {
|
||||
if (tokenopt.value() == "\n") {
|
||||
if (tokenopt.value().value == "\n") {
|
||||
break;
|
||||
}
|
||||
tokens.push_back(tokenopt.value());
|
||||
@@ -921,9 +952,11 @@ namespace Solstice {
|
||||
}
|
||||
case SolNodeType::Puts: {
|
||||
SolNode putsNode(SolNodeType::Puts);
|
||||
std::vector<std::string> tokens;
|
||||
putsNode.line = tokenObj.line;
|
||||
putsNode.lineContent = tokenObj.lineContent;
|
||||
std::vector<Token> tokens;
|
||||
while (auto tokenopt = consume()) {
|
||||
if (tokenopt.value() == "\n") {
|
||||
if (tokenopt.value().value == "\n") {
|
||||
break;
|
||||
}
|
||||
tokens.push_back(tokenopt.value());
|
||||
@@ -937,9 +970,11 @@ namespace Solstice {
|
||||
}
|
||||
case SolNodeType::If: {
|
||||
SolNode ifNode(SolNodeType::If);
|
||||
std::vector<std::string> tokens;
|
||||
ifNode.line = tokenObj.line;
|
||||
ifNode.lineContent = tokenObj.lineContent;
|
||||
std::vector<Token> tokens;
|
||||
while (auto tokenopt = consume()) {
|
||||
if (tokenopt.value() == "\n") {
|
||||
if (tokenopt.value().value == "\n") {
|
||||
break;
|
||||
}
|
||||
tokens.push_back(tokenopt.value());
|
||||
@@ -950,27 +985,28 @@ namespace Solstice {
|
||||
size_t brackets = 1;
|
||||
auto tokenopt = consume();
|
||||
if (tokenopt) {
|
||||
if (tokenopt.value() == "{") {
|
||||
if (tokenopt.value().value == "{") {
|
||||
tokens.push_back(tokenopt.value());
|
||||
while (auto tokenopt = consume()) {
|
||||
tokens.push_back(tokenopt.value());
|
||||
if (tokenopt.value() == "{") {
|
||||
if (tokenopt.value().value == "{") {
|
||||
brackets++;
|
||||
}
|
||||
if (tokenopt.value() == "}") {
|
||||
if (tokenopt.value().value == "}") {
|
||||
brackets--;
|
||||
}
|
||||
if (brackets == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (brackets != 0) {
|
||||
Error::syntaxError("Unclosed code block", tokenopt.value().line, tokenopt.value().lineContent);
|
||||
}
|
||||
} else {
|
||||
std::cout << "I want a code block instead of a " + tokenopt.value() + "\n";
|
||||
exit(1);
|
||||
Error::syntaxError("I want a code block instead of a " + tokenopt.value().value, tokenopt.value().line, tokenopt.value().lineContent);
|
||||
}
|
||||
} else {
|
||||
std::cout << "FEED ME MORE TOKENSSSSS\n";
|
||||
exit(1);
|
||||
Error::syntaxError("Expected code block after if condition", ifNode.line, ifNode.lineContent);
|
||||
}
|
||||
auto childCodeBlock = Parser(tokens).parse();
|
||||
ifNode.addNode(childCodeBlock.children[0]);
|
||||
@@ -979,9 +1015,11 @@ namespace Solstice {
|
||||
}
|
||||
case SolNodeType::While: {
|
||||
SolNode whileNode(SolNodeType::While);
|
||||
std::vector<std::string> tokens;
|
||||
whileNode.line = tokenObj.line;
|
||||
whileNode.lineContent = tokenObj.lineContent;
|
||||
std::vector<Token> tokens;
|
||||
while (auto tokenopt = consume()) {
|
||||
if (tokenopt.value() == "\n") {
|
||||
if (tokenopt.value().value == "\n") {
|
||||
break;
|
||||
}
|
||||
tokens.push_back(tokenopt.value());
|
||||
@@ -992,27 +1030,28 @@ namespace Solstice {
|
||||
size_t brackets = 1;
|
||||
auto tokenopt = consume();
|
||||
if (tokenopt) {
|
||||
if (tokenopt.value() == "{") {
|
||||
if (tokenopt.value().value == "{") {
|
||||
tokens.push_back(tokenopt.value());
|
||||
while (auto tokenopt = consume()) {
|
||||
tokens.push_back(tokenopt.value());
|
||||
if (tokenopt.value() == "{") {
|
||||
if (tokenopt.value().value == "{") {
|
||||
brackets++;
|
||||
}
|
||||
if (tokenopt.value() == "}") {
|
||||
if (tokenopt.value().value == "}") {
|
||||
brackets--;
|
||||
}
|
||||
if (brackets == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (brackets != 0) {
|
||||
Error::syntaxError("Unclosed code block", tokenopt.value().line, tokenopt.value().lineContent);
|
||||
}
|
||||
} else {
|
||||
std::cout << "I want a code block instead of a " + tokenopt.value() + "\n";
|
||||
exit(1);
|
||||
Error::syntaxError("I want a code block instead of a " + tokenopt.value().value, tokenopt.value().line, tokenopt.value().lineContent);
|
||||
}
|
||||
} else {
|
||||
std::cout << "FEED ME MORE TOKENSSSSS\n";
|
||||
exit(1);
|
||||
Error::syntaxError("Expected code block after while condition", whileNode.line, whileNode.lineContent);
|
||||
}
|
||||
auto childCodeBlock = Parser(tokens).parse();
|
||||
whileNode.addNode(childCodeBlock.children[0]);
|
||||
@@ -1021,13 +1060,15 @@ namespace Solstice {
|
||||
}
|
||||
case SolNodeType::CodeBlockStart: {
|
||||
SolNode codeBlockNode(SolNodeType::CodeBlock);
|
||||
codeBlockNode.line = tokenObj.line;
|
||||
codeBlockNode.lineContent = tokenObj.lineContent;
|
||||
size_t brackets = 1;
|
||||
std::vector<std::string> tokens;
|
||||
std::vector<Token> tokens;
|
||||
while (auto tokenopt = consume()) {
|
||||
if (tokenopt.value() == "{") {
|
||||
if (tokenopt.value().value == "{") {
|
||||
brackets++;
|
||||
}
|
||||
if (tokenopt.value() == "}") {
|
||||
if (tokenopt.value().value == "}") {
|
||||
brackets--;
|
||||
}
|
||||
if (brackets == 0) {
|
||||
@@ -1035,6 +1076,9 @@ namespace Solstice {
|
||||
}
|
||||
tokens.push_back(tokenopt.value());
|
||||
}
|
||||
if (brackets != 0) {
|
||||
Error::syntaxError("Unclosed code block", tokenObj.line, tokenObj.lineContent);
|
||||
}
|
||||
codeBlockNode.children = Parser(tokens).parse().children;
|
||||
rootNode.addNode(codeBlockNode);
|
||||
break;
|
||||
@@ -1042,16 +1086,21 @@ namespace Solstice {
|
||||
case SolNodeType::Identifier: {
|
||||
SolNode idNode(SolNodeType::Identifier);
|
||||
idNode.outputId = token;
|
||||
idNode.line = tokenObj.line;
|
||||
idNode.lineContent = tokenObj.lineContent;
|
||||
rootNode.addNode(idNode);
|
||||
break;
|
||||
}
|
||||
case SolNodeType::Set: {
|
||||
SolNode setNode(SolNodeType::Set);
|
||||
setNode.line = tokenObj.line;
|
||||
setNode.lineContent = tokenObj.lineContent;
|
||||
|
||||
setNode.addNode(rootNode.children.back());
|
||||
rootNode.children.pop_back();
|
||||
std::vector<std::string> tokens;
|
||||
std::vector<Token> tokens;
|
||||
while (auto tokenopt = consume()) {
|
||||
if (tokenopt.value() == "\n") {
|
||||
if (tokenopt.value().value == "\n") {
|
||||
break;
|
||||
}
|
||||
tokens.push_back(tokenopt.value());
|
||||
@@ -1064,15 +1113,17 @@ namespace Solstice {
|
||||
case SolNodeType::BracketStart: {
|
||||
if (rootNode.children.back().nodeType == SolNodeType::Identifier) {
|
||||
SolNode fnCallNode(SolNodeType::FunctionCall);
|
||||
fnCallNode.line = tokenObj.line;
|
||||
fnCallNode.lineContent = tokenObj.lineContent;
|
||||
fnCallNode.addNode(rootNode.children.back());
|
||||
rootNode.children.pop_back();
|
||||
std::vector<std::string> tokens;
|
||||
std::vector<Token> tokens;
|
||||
size_t brackets = 1;
|
||||
while (auto tokenopt = consume()) {
|
||||
if (tokenopt.value() == "(") {
|
||||
if (tokenopt.value().value == "(") {
|
||||
brackets++;
|
||||
}
|
||||
if (tokenopt.value() == ")") {
|
||||
if (tokenopt.value().value == ")") {
|
||||
brackets--;
|
||||
}
|
||||
if (brackets < 1) {
|
||||
@@ -1084,13 +1135,13 @@ namespace Solstice {
|
||||
fnCallNode.children.insert(fnCallNode.children.end(), node.children.begin(), node.children.end());
|
||||
rootNode.addNode(fnCallNode);
|
||||
} else {
|
||||
std::vector<std::string> tokens;
|
||||
std::vector<Token> tokens;
|
||||
size_t brackets = 1;
|
||||
while (auto tokenopt = consume()) {
|
||||
if (tokenopt.value() == "(") {
|
||||
if (tokenopt.value().value == "(") {
|
||||
brackets++;
|
||||
}
|
||||
if (tokenopt.value() == ")") {
|
||||
if (tokenopt.value().value == ")") {
|
||||
brackets--;
|
||||
}
|
||||
if (brackets < 1) {
|
||||
@@ -1128,4 +1179,4 @@ namespace Solstice {
|
||||
|
||||
} // namespace Parser
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user