From 99bc0dbdc24e321a331a9e78e07cf021d561911e Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Mon, 15 Dec 2025 11:37:27 +1100 Subject: [PATCH] If statements --- src/main.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++------- tests/if.hg | 7 +++++++ 2 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 tests/if.hg diff --git a/src/main.cpp b/src/main.cpp index ea5514e..b3c1973 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,7 @@ namespace HighGround { int tmpIdIterator = 0; + int labelIterator = 0; namespace Parser { @@ -98,7 +99,7 @@ namespace HighGround { } const std::vector generateCode() { std::vector code; - for (auto& child : children) { + if (nodeType != HGNodeType::If) for (auto& child : children) { auto childCode = child.generateCode(); code.insert(code.end(), childCode.begin(), childCode.end()); } @@ -174,6 +175,32 @@ namespace HighGround { code.push_back(codeBlock); break; } + case HGNodeType::If: { + auto conditionCode = children[0].generateCode(); + code.insert(code.end(), conditionCode.begin(), conditionCode.end()); + outputId = "tmp_" + std::to_string(tmpIdIterator++); + HGGroundCodeBlock codeBlock; + GroundInstruction gi = groundCreateInstruction(NOT); + 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++); + GroundInstruction gi2 = groundCreateInstruction(IF); + groundAddReferenceToInstruction(&gi2, groundCreateReference(VALREF, outputId.data())); + groundAddReferenceToInstruction(&gi2, groundCreateReference(LINEREF, labelId.data())); + 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(CREATELABEL); + groundAddReferenceToInstruction(&gi3, groundCreateReference(LABEL, labelId.data())); + codeBlock.code.push_back(gi3); + code.push_back(codeBlock); + break; + } default: {} } return code; @@ -368,10 +395,6 @@ namespace HighGround { tokens.push_back(tokenopt.value()); } auto children = Parser(tokens).parse(); - if (children.children.size() != 1) { - std::cout << "Too many or too little conditions for if\n"; - exit(1); - } ifNode.addNode(children.children[0]); tokens.clear(); size_t brackets = 1; @@ -392,17 +415,36 @@ namespace HighGround { } } } else { - std::cout << "I want a code block\n"; + 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(); + ifNode.addNode(childCodeBlock.children[0]); + rootNode.addNode(ifNode); break; } case HGNodeType::CodeBlockStart: { HGNode codeBlockNode(HGNodeType::CodeBlock); + size_t brackets = 1; + std::vector tokens; + while (auto tokenopt = consume()) { + if (tokenopt.value() == "{") { + brackets++; + } + if (tokenopt.value() == "}") { + brackets--; + } + if (brackets == 0) { + break; + } + tokens.push_back(tokenopt.value()); + } + codeBlockNode.children = Parser(tokens).parse().children; + rootNode.addNode(codeBlockNode); // WIP break; } @@ -517,8 +559,8 @@ namespace HighGround { tokens.push_back(buf); buf.clear(); } - tokens.push_back(std::string(1, c)); tokens.push_back("\n"); + tokens.push_back(std::string(1, c)); } // tokens which do not need to be included case ' ': diff --git a/tests/if.hg b/tests/if.hg new file mode 100644 index 0000000..6c18e94 --- /dev/null +++ b/tests/if.hg @@ -0,0 +1,7 @@ +if true { + puts "huzzah" +} + +if false { + puts "aww" +}