diff --git a/src/main.cpp b/src/main.cpp index 40e54ca..f23beb7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,5 @@ +#include +#include #include #include #include @@ -5,32 +7,193 @@ #include #include #include +#include namespace HighGround { + int tmpIdIterator = 0; + namespace Parser { enum class HGNodeType { - Add, Subtract, Equal, Set, While, If, None, Root, CodeBlock + Add, Subtract, Equal, Set, While, If, Value, Identifier, None, Root, CodeBlock + }; + + enum class HGDataType { + Int, String, Double, Bool, Char, None }; class HGNode; + class HGGroundCodeBlock { + public: + std::vector code; + HGGroundCodeBlock() = default; + }; + + class HGData { + std::variant data; + public: + HGDataType type = HGDataType::Int; + HGData() = default; + HGData(int64_t in) : data(in) {} + std::optional getInt() { + if (type == HGDataType::Int) { + return std::get(data); + } else { + return {}; + } + } + }; + class HGNode { HGNodeType nodeType = HGNodeType::None; + HGData data; std::vector children; public: + std::string outputId; HGNode(HGNodeType nodeType) : nodeType(nodeType) {} + HGNode(HGNodeType nodeType, HGData data) : nodeType(nodeType), data(data) {} HGNode() = default; void addNode(HGNode in) { children.push_back(in); } - std::vector generateCode() { - std::vector code; + void setValue(HGData in) { + data = in; + } + const std::vector generateCode() { + std::vector code; + for (auto& child : children) { + auto childCode = child.generateCode(); + code.insert(code.end(), childCode.begin(), childCode.end()); + } + switch (nodeType) { + case HGNodeType::Value: { + outputId = "tmp_" + std::to_string(tmpIdIterator++); + HGGroundCodeBlock codeBlock; + GroundInstruction gi = groundCreateInstruction(SET); + groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); + switch (data.type) { + case HGDataType::Int: { + auto dataopt = data.getInt(); + if (dataopt) { + groundAddValueToInstruction(&gi, groundCreateValue(INT, dataopt.value())); + } + } + } + codeBlock.code.push_back(gi); + code.push_back(codeBlock); + break; + } + default: { + std::cout << "Not implemented yet\n"; + } + } return code; } + }; + class Parser { + std::vector tokensToParse; + size_t current; + size_t size; + + std::optional peek(int ahead = 1) { + if (current + ahead < size) { + return tokensToParse[current + ahead]; + } else { + return {}; + } + } + + std::optional consume() { + if (current < size) { + return tokensToParse[current++]; + } else { + return {}; + } + } + + bool isInt(std::string in) { + for (const char& c : in) { + if (!std::isdigit(c)) { + return false; + } + } + return true; + } + bool isDouble(std::string in) { + bool foundDot = false; + for (const char& c : in) { + if (!std::isdigit(c)) { + if (!foundDot && c == '.') { + foundDot = true; + continue; + } + return false; + } + } + return true; + } + + HGDataType getDataType(std::string in) { + if (isInt(in)) { + return HGDataType::Int; + } + if (isDouble(in)) { + return HGDataType::Double; + } + return HGDataType::None; + } + + HGNodeType getNodeType(std::string in) { + if (getDataType(in) != HGDataType::None) { + return HGNodeType::Value; + } + return HGNodeType::None; + } + + public: + Parser(std::vector in) : tokensToParse(in) {} + + HGNode parse() { + current = 0; + size = tokensToParse.size(); + HGNode rootNode(HGNodeType::Root); + while (auto tokenopt = consume()) { + std::string token = tokenopt.value(); + switch (getNodeType(token)) { + case HGNodeType::Value: { + switch (getDataType(token)) { + case HGDataType::Int: { + std::cout << "We have an int\n"; + HGNode intNode(HGNodeType::Value); + intNode.setValue(std::stoll(token)); + rootNode.addNode(intNode); + break; + } + } + break; + } + } + } + return rootNode; + } + }; + + GroundProgram assembleProgram(HGNode& rootNode) { + GroundProgram gp = groundCreateProgram(); + auto code = rootNode.generateCode(); + for (int i = 0; i < code.size(); i++) { + for (const auto& inst : code[i].code) { + groundAddInstructionToProgram(&gp, inst); + } + } + groundAddInstructionToProgram(&gp, groundCreateInstruction(PAUSE)); + return gp; + } + } // namespace Parser class Lexer { @@ -156,7 +319,7 @@ int main(int argc, char** argv) { std::ostringstream ss; ss << file.rdbuf(); auto lexed = HighGround::Lexer(ss.str()).lex(); - for (const std::string& str : lexed) { - std::cout << str << "\n"; - } + auto parsed = HighGround::Parser::Parser(lexed).parse(); + GroundProgram program = HighGround::Parser::assembleProgram(parsed); + groundRunProgram(&program); } diff --git a/tests/int.hg b/tests/int.hg new file mode 100644 index 0000000..367340f --- /dev/null +++ b/tests/int.hg @@ -0,0 +1 @@ +32 12 3320932 31920