While loop

This commit is contained in:
2025-12-20 07:37:15 +11:00
parent a8e5f6a0f1
commit 0488067ef2
2 changed files with 91 additions and 3 deletions

View File

@@ -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
View File

@@ -0,0 +1,3 @@
while 1 == 1 {
puts "yay infinite loop"
}