While loop
This commit is contained in:
91
src/main.cpp
91
src/main.cpp
@@ -8,6 +8,7 @@
|
||||
#include <sstream>
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
#include <cstring>
|
||||
|
||||
#define parseOneToken(token) Parser({token.value()}).parse().children[0]
|
||||
|
||||
@@ -198,10 +199,12 @@ namespace HighGround {
|
||||
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data()));
|
||||
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data()));
|
||||
codeBlock.code.push_back(gi);
|
||||
std::string labelId = "if_" + std::to_string(labelIterator++);
|
||||
std::string labelIdString = "if_" + std::to_string(labelIterator++);
|
||||
char* labelId = (char*) malloc(sizeof(char) * labelIdString.size() + 1);
|
||||
strcpy(labelId, labelIdString.data());
|
||||
GroundInstruction gi2 = groundCreateInstruction(IF);
|
||||
groundAddReferenceToInstruction(&gi2, groundCreateReference(VALREF, outputId.data()));
|
||||
groundAddReferenceToInstruction(&gi2, groundCreateReference(LINEREF, labelId.data()));
|
||||
groundAddReferenceToInstruction(&gi2, groundCreateReference(LINEREF, labelId));
|
||||
codeBlock.code.push_back(gi2);
|
||||
code.push_back(codeBlock);
|
||||
for (size_t i = 1; i < children.size(); i++) {
|
||||
@@ -210,11 +213,48 @@ namespace HighGround {
|
||||
}
|
||||
codeBlock.code.clear();
|
||||
GroundInstruction gi3 = groundCreateInstruction(CREATELABEL);
|
||||
groundAddReferenceToInstruction(&gi3, groundCreateReference(LABEL, labelId.data()));
|
||||
groundAddReferenceToInstruction(&gi3, groundCreateReference(LABEL, labelId));
|
||||
codeBlock.code.push_back(gi3);
|
||||
code.push_back(codeBlock);
|
||||
break;
|
||||
}
|
||||
case HGNodeType::While: {
|
||||
HGGroundCodeBlock codeBlock;
|
||||
std::string startLabelIdString = "whilestart_" + std::to_string(labelIterator++);
|
||||
std::string endLabelIdString = "whileend_" + std::to_string(labelIterator);
|
||||
char* startLabelId = (char*) malloc(sizeof(char) * startLabelIdString.size());
|
||||
strcpy(startLabelId, startLabelIdString.data());
|
||||
char* endLabelId = (char*) malloc(sizeof(char) * endLabelIdString.size());
|
||||
strcpy(endLabelId, endLabelIdString.data());
|
||||
GroundInstruction startLabel = groundCreateInstruction(CREATELABEL);
|
||||
groundAddReferenceToInstruction(&startLabel, groundCreateReference(LABEL, startLabelId));
|
||||
codeBlock.code.push_back(startLabel);
|
||||
auto conditionCode = children[0].generateCode();
|
||||
code.insert(code.end(), conditionCode.begin(), conditionCode.end());
|
||||
outputId = "tmp_" + std::to_string(tmpIdIterator++);
|
||||
GroundInstruction gi = groundCreateInstruction(NOT);
|
||||
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data()));
|
||||
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data()));
|
||||
codeBlock.code.push_back(gi);
|
||||
GroundInstruction gi2 = groundCreateInstruction(IF);
|
||||
groundAddReferenceToInstruction(&gi2, groundCreateReference(VALREF, outputId.data()));
|
||||
groundAddReferenceToInstruction(&gi2, groundCreateReference(LINEREF, endLabelId));
|
||||
codeBlock.code.push_back(gi2);
|
||||
code.push_back(codeBlock);
|
||||
for (size_t i = 1; i < children.size(); i++) {
|
||||
auto childCode = children[i].generateCode();
|
||||
code.insert(code.end(), childCode.begin(), childCode.end());
|
||||
}
|
||||
codeBlock.code.clear();
|
||||
GroundInstruction gi3 = groundCreateInstruction(JUMP);
|
||||
groundAddReferenceToInstruction(&gi3, groundCreateReference(LINEREF, startLabelId));
|
||||
codeBlock.code.push_back(gi3);
|
||||
GroundInstruction gi4 = groundCreateInstruction(CREATELABEL);
|
||||
groundAddReferenceToInstruction(&gi4, groundCreateReference(LABEL, endLabelId));
|
||||
codeBlock.code.push_back(gi4);
|
||||
code.push_back(codeBlock);
|
||||
break;
|
||||
}
|
||||
default: {}
|
||||
}
|
||||
return code;
|
||||
@@ -318,6 +358,9 @@ namespace HighGround {
|
||||
if (in == "if") {
|
||||
return HGNodeType::If;
|
||||
}
|
||||
if (in == "while") {
|
||||
return HGNodeType::While;
|
||||
}
|
||||
if (in == "{") {
|
||||
return HGNodeType::CodeBlockStart;
|
||||
}
|
||||
@@ -458,6 +501,48 @@ namespace HighGround {
|
||||
rootNode.addNode(ifNode);
|
||||
break;
|
||||
}
|
||||
case HGNodeType::While: {
|
||||
HGNode whileNode(HGNodeType::While);
|
||||
std::vector<std::string> tokens;
|
||||
while (auto tokenopt = consume()) {
|
||||
if (tokenopt.value() == "\n") {
|
||||
break;
|
||||
}
|
||||
tokens.push_back(tokenopt.value());
|
||||
}
|
||||
auto children = Parser(tokens).parse();
|
||||
whileNode.addNode(children.children[0]);
|
||||
tokens.clear();
|
||||
size_t brackets = 1;
|
||||
auto tokenopt = consume();
|
||||
if (tokenopt) {
|
||||
if (tokenopt.value() == "{") {
|
||||
tokens.push_back(tokenopt.value());
|
||||
while (auto tokenopt = consume()) {
|
||||
tokens.push_back(tokenopt.value());
|
||||
if (tokenopt.value() == "{") {
|
||||
brackets++;
|
||||
}
|
||||
if (tokenopt.value() == "}") {
|
||||
brackets--;
|
||||
}
|
||||
if (brackets == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::cout << "I want a code block instead of a " + tokenopt.value() + "\n";
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
std::cout << "FEED ME MORE TOKENSSSSS\n";
|
||||
exit(1);
|
||||
}
|
||||
auto childCodeBlock = Parser(tokens).parse();
|
||||
whileNode.addNode(childCodeBlock.children[0]);
|
||||
rootNode.addNode(whileNode);
|
||||
break;
|
||||
}
|
||||
case HGNodeType::CodeBlockStart: {
|
||||
HGNode codeBlockNode(HGNodeType::CodeBlock);
|
||||
size_t brackets = 1;
|
||||
|
||||
3
tests/while.hg
Normal file
3
tests/while.hg
Normal file
@@ -0,0 +1,3 @@
|
||||
while 1 == 1 {
|
||||
puts "yay infinite loop"
|
||||
}
|
||||
Reference in New Issue
Block a user