diff --git a/src/lexer.cpp b/src/lexer.cpp index a138783..c2aeebc 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp @@ -88,6 +88,8 @@ namespace Solstice { case '*': case '/': case '=': + case '>': + case '<': { std::string newToken(1, c); auto tokenopt = peek(0); diff --git a/src/parser.cpp b/src/parser.cpp index b55b2bc..731038e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1,4 +1,5 @@ #include "parser.h" +#include #include #include #include @@ -157,6 +158,174 @@ namespace Solstice { code.push_back(codeBlock); break; } + case SolNodeType::Greater: { + SolGroundCodeBlock codeBlock; + outputId = "tmp_" + std::to_string(tmpIdIterator++); + GroundInstruction gi = groundCreateInstruction(GREATER); + if (children.size() < 2) { + std::cout << "Need more stuff to greater\n"; + } + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); + groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); + codeBlock.code.push_back(gi); + code.push_back(codeBlock); + break; + } + case SolNodeType::Lesser: { + SolGroundCodeBlock codeBlock; + outputId = "tmp_" + std::to_string(tmpIdIterator++); + GroundInstruction gi = groundCreateInstruction(LESSER); + if (children.size() < 2) { + std::cout << "Need more stuff to lesser\n"; + } + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); + groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); + codeBlock.code.push_back(gi); + code.push_back(codeBlock); + break; + } + case SolNodeType::EqGreater: { + SolGroundCodeBlock codeBlock; + if (children.size() < 2) { + std::cout << "Need more stuff to inequal\n"; + } + outputId = "tmp_" + std::to_string(tmpIdIterator++); + std::string trueLabelIdString = "internal_true" + std::to_string(labelIterator++); + std::string falseLabelIdString = "internal_false" + std::to_string(labelIterator); + std::string endLabelIdString = "internal_end" + std::to_string(labelIterator); + char* trueLabelId = (char*) malloc(sizeof(char) * (trueLabelIdString.size() + 1)); + strcpy(trueLabelId, trueLabelIdString.data()); + char* falseLabelId = (char*) malloc(sizeof(char) * (falseLabelIdString.size() + 1)); + strcpy(falseLabelId, falseLabelIdString.data()); + char* endLabelId = (char*) malloc(sizeof(char) * (endLabelIdString.size() + 1)); + strcpy(endLabelId, endLabelIdString.data()); + // greater $tmp_0 $tmp_1 &cond + GroundInstruction gi = groundCreateInstruction(GREATER); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); + groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, (char*) "internal_cond0")); + codeBlock.code.push_back(gi); + // if &cond %true + gi = groundCreateInstruction(IF); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, (char*) "internal_cond0")); + groundAddReferenceToInstruction(&gi, groundCreateReference(LINEREF, trueLabelId)); + codeBlock.code.push_back(gi); + // equal $tmp_0 $tmp_1 &cond + gi = groundCreateInstruction(EQUAL); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); + groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, (char*) "internal_cond1")); + codeBlock.code.push_back(gi); + // if $cond %true + gi = groundCreateInstruction(IF); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, (char*) "internal_cond1")); + groundAddReferenceToInstruction(&gi, groundCreateReference(LINEREF, trueLabelId)); + codeBlock.code.push_back(gi); + // jump %false + gi = groundCreateInstruction(JUMP); + groundAddReferenceToInstruction(&gi, groundCreateReference(LINEREF, falseLabelId)); + codeBlock.code.push_back(gi); + // @true + gi = groundCreateInstruction(CREATELABEL); + groundAddReferenceToInstruction(&gi, groundCreateReference(LABEL, trueLabelId)); + codeBlock.code.push_back(gi); + // set &tmp_x true + gi = groundCreateInstruction(SET); + groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); + groundAddValueToInstruction(&gi, groundCreateValue(BOOL, true)); + codeBlock.code.push_back(gi); + // jump %end + gi = groundCreateInstruction(JUMP); + groundAddReferenceToInstruction(&gi, groundCreateReference(LINEREF, endLabelId)); + codeBlock.code.push_back(gi); + // @false + gi = groundCreateInstruction(CREATELABEL); + groundAddReferenceToInstruction(&gi, groundCreateReference(LABEL, falseLabelId)); + codeBlock.code.push_back(gi); + // set &tmp_x false + gi = groundCreateInstruction(SET); + groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); + groundAddValueToInstruction(&gi, groundCreateValue(BOOL, false)); + codeBlock.code.push_back(gi); + // @end + gi = groundCreateInstruction(CREATELABEL); + groundAddReferenceToInstruction(&gi, groundCreateReference(LABEL, endLabelId)); + codeBlock.code.push_back(gi); + code.push_back(codeBlock); + break; + } + case SolNodeType::EqLesser: { + SolGroundCodeBlock codeBlock; + if (children.size() < 2) { + std::cout << "Need more stuff to inequal\n"; + } + outputId = "tmp_" + std::to_string(tmpIdIterator++); + std::string trueLabelIdString = "internal_true" + std::to_string(labelIterator++); + std::string falseLabelIdString = "internal_false" + std::to_string(labelIterator); + std::string endLabelIdString = "internal_end" + std::to_string(labelIterator); + char* trueLabelId = (char*) malloc(sizeof(char) * (trueLabelIdString.size() + 1)); + strcpy(trueLabelId, trueLabelIdString.data()); + char* falseLabelId = (char*) malloc(sizeof(char) * (falseLabelIdString.size() + 1)); + strcpy(falseLabelId, falseLabelIdString.data()); + char* endLabelId = (char*) malloc(sizeof(char) * (endLabelIdString.size() + 1)); + strcpy(endLabelId, endLabelIdString.data()); + // lesser $tmp_0 $tmp_1 &cond + GroundInstruction gi = groundCreateInstruction(LESSER); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); + groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, (char*) "internal_cond0")); + codeBlock.code.push_back(gi); + // if &cond %true + gi = groundCreateInstruction(IF); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, (char*) "internal_cond0")); + groundAddReferenceToInstruction(&gi, groundCreateReference(LINEREF, trueLabelId)); + codeBlock.code.push_back(gi); + // equal $tmp_0 $tmp_1 &cond + gi = groundCreateInstruction(EQUAL); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[1].outputId.data())); + groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, (char*) "internal_cond1")); + codeBlock.code.push_back(gi); + // if $cond %true + gi = groundCreateInstruction(IF); + groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, (char*) "internal_cond1")); + groundAddReferenceToInstruction(&gi, groundCreateReference(LINEREF, trueLabelId)); + codeBlock.code.push_back(gi); + // jump %false + gi = groundCreateInstruction(JUMP); + groundAddReferenceToInstruction(&gi, groundCreateReference(LINEREF, falseLabelId)); + codeBlock.code.push_back(gi); + // @true + gi = groundCreateInstruction(CREATELABEL); + groundAddReferenceToInstruction(&gi, groundCreateReference(LABEL, trueLabelId)); + codeBlock.code.push_back(gi); + // set &tmp_x true + gi = groundCreateInstruction(SET); + groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); + groundAddValueToInstruction(&gi, groundCreateValue(BOOL, true)); + codeBlock.code.push_back(gi); + // jump %end + gi = groundCreateInstruction(JUMP); + groundAddReferenceToInstruction(&gi, groundCreateReference(LINEREF, endLabelId)); + codeBlock.code.push_back(gi); + // @false + gi = groundCreateInstruction(CREATELABEL); + groundAddReferenceToInstruction(&gi, groundCreateReference(LABEL, falseLabelId)); + codeBlock.code.push_back(gi); + // set &tmp_x false + gi = groundCreateInstruction(SET); + groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); + groundAddValueToInstruction(&gi, groundCreateValue(BOOL, false)); + codeBlock.code.push_back(gi); + // @end + gi = groundCreateInstruction(CREATELABEL); + groundAddReferenceToInstruction(&gi, groundCreateReference(LABEL, endLabelId)); + codeBlock.code.push_back(gi); + code.push_back(codeBlock); + break; + } case SolNodeType::Puts: { SolGroundCodeBlock codeBlock; GroundInstruction gi = groundCreateInstruction(PRINTLN); @@ -371,6 +540,18 @@ namespace Solstice { if (in == "!=") { return SolNodeType::Inequal; } + if (in == ">=") { + return SolNodeType::EqGreater; + } + if (in == "<=") { + return SolNodeType::EqLesser; + } + if (in == ">") { + return SolNodeType::Greater; + } + if (in == "<") { + return SolNodeType::Lesser; + } if (in == "puts") { return SolNodeType::Puts; } @@ -451,34 +632,32 @@ namespace Solstice { rootNode.addNode(addNode); break; } - case SolNodeType::Equal: { - SolNode equalNode(SolNodeType::Equal); + case SolNodeType::Equal: + case SolNodeType::Inequal: + case SolNodeType::Lesser: + case SolNodeType::Greater: + case SolNodeType::EqLesser: + case SolNodeType::EqGreater: + { + SolNode equalNode(getNodeType(token)); + if (rootNode.children.empty()) { + std::cout << "ah dingus\n"; + exit(1); + } equalNode.addNode(rootNode.children.back()); rootNode.children.pop_back(); - auto tokenopt = consume(); - if (tokenopt) { - equalNode.addNode(parseOneToken(tokenopt)); - } else { - std::cout << "FEED ME MORE TOKENS\n"; - exit(1); + std::vector tokens; + while (auto tokenopt = consume()) { + if (tokenopt.value() == "\n") { + break; + } + tokens.push_back(tokenopt.value()); } + auto children = Parser(tokens).parse(); + equalNode.addNode(children.children[0]); rootNode.addNode(equalNode); break; } - case SolNodeType::Inequal: { - SolNode inequalNode(SolNodeType::Inequal); - inequalNode.addNode(rootNode.children.back()); - rootNode.children.pop_back(); - auto tokenopt = consume(); - if (tokenopt) { - inequalNode.addNode(parseOneToken(tokenopt)); - } else { - std::cout << "FEED ME MORE TOKENS\n"; - exit(1); - } - rootNode.addNode(inequalNode); - break; - } case SolNodeType::Puts: { SolNode putsNode(SolNodeType::Puts); std::vector tokens; @@ -681,4 +860,4 @@ namespace Solstice { } // namespace Parser -} \ No newline at end of file +} diff --git a/src/parser.h b/src/parser.h index b872393..23310a1 100644 --- a/src/parser.h +++ b/src/parser.h @@ -16,7 +16,7 @@ namespace Solstice { namespace Parser { enum class SolNodeType { - Add, Subtract, Equal, Inequal, Set, While, If, Value, Identifier, None, Root, CodeBlock, CodeBlockStart, CodeBlockEnd, FunctionCall, Expression, BracketStart, BracketEnd, Puts + Add, Subtract, Equal, Inequal, Greater, Lesser, EqGreater, EqLesser, Set, While, If, Value, Identifier, None, Root, CodeBlock, CodeBlockStart, CodeBlockEnd, FunctionCall, Expression, BracketStart, BracketEnd, Puts }; enum class SolDataType { diff --git a/tests/compare.sols b/tests/compare.sols new file mode 100644 index 0000000..dbb3815 --- /dev/null +++ b/tests/compare.sols @@ -0,0 +1,55 @@ +if 1 == 1 { + puts "working" +} + +if 1 == 2 { + puts "not working" +} + +if 1 != 2 { + puts "working" +} + +if 1 != 1 { + puts "not working" +} + +if 2 > 1 { + puts "working" +} + +if 1 > 2 { + puts "not working" +} + +if 1 < 2 { + puts "working" +} + +if 2 < 1 { + puts "not working" +} + +if 2 >= 2 { + puts "working" +} + +if 2 >= 1 { + puts "working" +} + +if 2 >= 3 { + puts "not working" +} + +if 2 <= 2 { + puts "working" +} + +if 2 <= 3 { + puts "working" +} + +if 3 <= 2 { + puts "not working" +}