forked from solstice/solstice
Add >, >=, <, <=
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
225
src/parser.cpp
225
src/parser.cpp
@@ -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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
55
tests/compare.sols
Normal 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"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user