Add >, >=, <, <=

This commit is contained in:
2025-12-22 13:49:44 +11:00
parent d2f295f46a
commit 525b2bc733
4 changed files with 260 additions and 24 deletions

View File

@@ -88,6 +88,8 @@ namespace Solstice {
case '*': case '*':
case '/': case '/':
case '=': case '=':
case '>':
case '<':
{ {
std::string newToken(1, c); std::string newToken(1, c);
auto tokenopt = peek(0); auto tokenopt = peek(0);

View File

@@ -1,4 +1,5 @@
#include "parser.h" #include "parser.h"
#include <groundvm.h>
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
#include <algorithm> #include <algorithm>
@@ -157,6 +158,174 @@ namespace Solstice {
code.push_back(codeBlock); code.push_back(codeBlock);
break; 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: { case SolNodeType::Puts: {
SolGroundCodeBlock codeBlock; SolGroundCodeBlock codeBlock;
GroundInstruction gi = groundCreateInstruction(PRINTLN); GroundInstruction gi = groundCreateInstruction(PRINTLN);
@@ -371,6 +540,18 @@ namespace Solstice {
if (in == "!=") { if (in == "!=") {
return SolNodeType::Inequal; 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") { if (in == "puts") {
return SolNodeType::Puts; return SolNodeType::Puts;
} }
@@ -451,34 +632,32 @@ namespace Solstice {
rootNode.addNode(addNode); rootNode.addNode(addNode);
break; break;
} }
case SolNodeType::Equal: { case SolNodeType::Equal:
SolNode equalNode(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()); equalNode.addNode(rootNode.children.back());
rootNode.children.pop_back(); rootNode.children.pop_back();
auto tokenopt = consume(); std::vector<std::string> tokens;
if (tokenopt) { while (auto tokenopt = consume()) {
equalNode.addNode(parseOneToken(tokenopt)); if (tokenopt.value() == "\n") {
} else { break;
std::cout << "FEED ME MORE TOKENS\n"; }
exit(1); tokens.push_back(tokenopt.value());
} }
auto children = Parser(tokens).parse();
equalNode.addNode(children.children[0]);
rootNode.addNode(equalNode); rootNode.addNode(equalNode);
break; 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: { case SolNodeType::Puts: {
SolNode putsNode(SolNodeType::Puts); SolNode putsNode(SolNodeType::Puts);
std::vector<std::string> tokens; std::vector<std::string> tokens;
@@ -681,4 +860,4 @@ namespace Solstice {
} // namespace Parser } // namespace Parser
} }

View File

@@ -16,7 +16,7 @@ namespace Solstice {
namespace Parser { namespace Parser {
enum class SolNodeType { 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 { enum class SolDataType {

55
tests/compare.sols Normal file
View File

@@ -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"
}