forked from solstice/solstice
Add >, >=, <, <=
This commit is contained in:
225
src/parser.cpp
225
src/parser.cpp
@@ -1,4 +1,5 @@
|
||||
#include "parser.h"
|
||||
#include <groundvm.h>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
@@ -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<std::string> 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<std::string> tokens;
|
||||
@@ -681,4 +860,4 @@ namespace Solstice {
|
||||
|
||||
} // namespace Parser
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user