From 0488067ef28cda706d3b7b575c01a7ed1b73c2fe Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sat, 20 Dec 2025 07:37:15 +1100 Subject: [PATCH] While loop --- src/main.cpp | 91 ++++++++++++++++++++++++++++++++++++++++++++++++-- tests/while.hg | 3 ++ 2 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 tests/while.hg diff --git a/src/main.cpp b/src/main.cpp index e4cda98..d7a9efd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #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 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; diff --git a/tests/while.hg b/tests/while.hg new file mode 100644 index 0000000..c03aa3a --- /dev/null +++ b/tests/while.hg @@ -0,0 +1,3 @@ +while 1 == 1 { + puts "yay infinite loop" +}