diff --git a/.gitignore b/.gitignore index cbb0de2..7f5ba35 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -hg +solstice diff --git a/README.md b/README.md index 80b0394..7cd8097 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,20 @@ -# High Ground +# Solstice -High Ground is a programming language based on Ground. - -It is the reference language designed to teach you how to build your own Ground-based language. +Solstice is a programming language based on Ground. ## Compiling First, ensure CGround is installed on your system with `sudo make install`. Then, compile with ``` -g++ src/main.cpp -o hg -lgroundvm +g++ src/main.cpp -o solstice -lgroundvm ``` ## Usage -High Ground files use the `.hg` extension. Run files as you would with any other interpreted language. +Solstice files use the `.sols` extension. Run files as you would with any other interpreted language. -## Using High Ground +## Using Solstice ### Types @@ -80,7 +78,7 @@ if password == "password123" { puts "Your password is insecure." } -if password = "dingus" { +if password == "dingus" { puts "Cool password!" } ``` diff --git a/src/main.cpp b/src/main.cpp index 96955da..15b0132 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,70 +12,70 @@ #define parseOneToken(token) Parser({token.value()}).parse().children[0] -namespace HighGround { +namespace Solstice { int tmpIdIterator = 0; int labelIterator = 0; namespace Parser { - enum class HGNodeType { + enum class SolNodeType { Add, Subtract, Equal, Inequal, Set, While, If, Value, Identifier, None, Root, CodeBlock, CodeBlockStart, CodeBlockEnd, Puts }; - enum class HGDataType { + enum class SolDataType { Int, String, Double, Bool, Char, None }; - class HGNode; + class SolNode; - class HGGroundCodeBlock { + class SolGroundCodeBlock { public: std::vector code; - HGGroundCodeBlock() = default; + SolGroundCodeBlock() = default; }; - class HGData { + class SolData { typedef std::variant varData; varData data; public: - HGDataType type = HGDataType::Int; - HGData() = default; - HGData(int64_t in) : data(in), type(HGDataType::Int) {} - HGData(double in) : data(in), type(HGDataType::Double) {} - HGData(std::string in) : data(in), type(HGDataType::String) {} - HGData(char in) : data(in), type(HGDataType::Char) {} - HGData(bool in) : data(in), type(HGDataType::Bool) {} + SolDataType type = SolDataType::Int; + SolData() = default; + SolData(int64_t in) : data(in), type(SolDataType::Int) {} + SolData(double in) : data(in), type(SolDataType::Double) {} + SolData(std::string in) : data(in), type(SolDataType::String) {} + SolData(char in) : data(in), type(SolDataType::Char) {} + SolData(bool in) : data(in), type(SolDataType::Bool) {} std::optional getInt() { - if (type == HGDataType::Int) { + if (type == SolDataType::Int) { return std::get(data); } else { return {}; } } std::optional getDouble() { - if (type == HGDataType::Double) { + if (type == SolDataType::Double) { return std::get(data); } else { return {}; } } std::optional getString() { - if (type == HGDataType::String) { + if (type == SolDataType::String) { return std::get(data); } else { return {}; } } std::optional getChar() { - if (type == HGDataType::Char) { + if (type == SolDataType::Char) { return std::get(data); } else { return {}; } } std::optional getBool() { - if (type == HGDataType::Bool) { + if (type == SolDataType::Bool) { return std::get(data); } else { return {}; @@ -83,63 +83,63 @@ namespace HighGround { } }; - class HGNode { - HGNodeType nodeType = HGNodeType::None; - HGData data; + class SolNode { + SolNodeType nodeType = SolNodeType::None; + SolData data; public: - std::vector children; + std::vector children; std::string outputId; - HGNode(HGNodeType nodeType) : nodeType(nodeType) {} - HGNode(HGNodeType nodeType, HGData data) : nodeType(nodeType), data(data) {} - HGNode() = default; - void addNode(HGNode in) { + SolNode(SolNodeType nodeType) : nodeType(nodeType) {} + SolNode(SolNodeType nodeType, SolData data) : nodeType(nodeType), data(data) {} + SolNode() = default; + void addNode(SolNode in) { children.push_back(in); } - void setValue(HGData in) { + void setValue(SolData in) { data = in; } - const std::vector generateCode() { - std::vector code; - if (nodeType != HGNodeType::If) for (auto& child : children) { + const std::vector generateCode() { + std::vector code; + if (nodeType != SolNodeType::If && nodeType != SolNodeType::While) for (auto& child : children) { auto childCode = child.generateCode(); code.insert(code.end(), childCode.begin(), childCode.end()); } switch (nodeType) { - case HGNodeType::Value: { + case SolNodeType::Value: { outputId = "tmp_" + std::to_string(tmpIdIterator++); - HGGroundCodeBlock codeBlock; + SolGroundCodeBlock codeBlock; GroundInstruction gi = groundCreateInstruction(SET); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); switch (data.type) { - case HGDataType::Int: { + case SolDataType::Int: { auto dataopt = data.getInt(); if (dataopt) { groundAddValueToInstruction(&gi, groundCreateValue(INT, dataopt.value())); } break; } - case HGDataType::Double: { + case SolDataType::Double: { auto dataopt = data.getDouble(); if (dataopt) { groundAddValueToInstruction(&gi, groundCreateValue(DOUBLE, dataopt.value())); } break; } - case HGDataType::String: { + case SolDataType::String: { auto dataopt = data.getString(); if (dataopt) { groundAddValueToInstruction(&gi, groundCreateValue(STRING, dataopt.value().c_str())); } break; } - case HGDataType::Char: { + case SolDataType::Char: { auto dataopt = data.getChar(); if (dataopt) { groundAddValueToInstruction(&gi, groundCreateValue(CHAR, dataopt.value())); } break; } - case HGDataType::Bool: { + case SolDataType::Bool: { auto dataopt = data.getBool(); if (dataopt) { groundAddValueToInstruction(&gi, groundCreateValue(BOOL, dataopt.value())); @@ -151,8 +151,8 @@ namespace HighGround { code.push_back(codeBlock); break; } - case HGNodeType::Add: { - HGGroundCodeBlock codeBlock; + case SolNodeType::Add: { + SolGroundCodeBlock codeBlock; outputId = "tmp_" + std::to_string(tmpIdIterator++); GroundInstruction gi = groundCreateInstruction(ADD); if (children.size() < 2) { @@ -165,8 +165,8 @@ namespace HighGround { code.push_back(codeBlock); break; } - case HGNodeType::Equal: { - HGGroundCodeBlock codeBlock; + case SolNodeType::Equal: { + SolGroundCodeBlock codeBlock; outputId = "tmp_" + std::to_string(tmpIdIterator++); GroundInstruction gi = groundCreateInstruction(EQUAL); if (children.size() < 2) { @@ -179,8 +179,8 @@ namespace HighGround { code.push_back(codeBlock); break; } - case HGNodeType::Inequal: { - HGGroundCodeBlock codeBlock; + case SolNodeType::Inequal: { + SolGroundCodeBlock codeBlock; outputId = "tmp_" + std::to_string(tmpIdIterator++); GroundInstruction gi = groundCreateInstruction(INEQUAL); if (children.size() < 2) { @@ -193,8 +193,8 @@ namespace HighGround { code.push_back(codeBlock); break; } - case HGNodeType::Puts: { - HGGroundCodeBlock codeBlock; + case SolNodeType::Puts: { + SolGroundCodeBlock codeBlock; GroundInstruction gi = groundCreateInstruction(PRINTLN); if (children.size() < 1) { std::cout << "Need more stuff to puts\n"; @@ -204,11 +204,11 @@ namespace HighGround { code.push_back(codeBlock); break; } - case HGNodeType::If: { + case SolNodeType::If: { auto conditionCode = children[0].generateCode(); code.insert(code.end(), conditionCode.begin(), conditionCode.end()); outputId = "tmp_" + std::to_string(tmpIdIterator++); - HGGroundCodeBlock codeBlock; + SolGroundCodeBlock codeBlock; GroundInstruction gi = groundCreateInstruction(NOT); groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, children[0].outputId.data())); groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, outputId.data())); @@ -232,48 +232,55 @@ namespace HighGround { code.push_back(codeBlock); break; } - case HGNodeType::While: { - HGGroundCodeBlock codeBlock; + case SolNodeType::While: { + SolGroundCodeBlock startLabelBlock; std::string startLabelIdString = "whilestart_" + std::to_string(labelIterator++); std::string endLabelIdString = "whileend_" + std::to_string(labelIterator); char* startLabelId = (char*) malloc(sizeof(char) * (startLabelIdString.size() + 1)); strcpy(startLabelId, startLabelIdString.data()); char* endLabelId = (char*) malloc(sizeof(char) * (endLabelIdString.size() + 1)); strcpy(endLabelId, endLabelIdString.data()); + GroundInstruction startLabel = groundCreateInstruction(CREATELABEL); groundAddReferenceToInstruction(&startLabel, groundCreateReference(LABEL, startLabelId)); - codeBlock.code.push_back(startLabel); + startLabelBlock.code.push_back(startLabel); + code.push_back(startLabelBlock); + auto conditionCode = children[0].generateCode(); code.insert(code.end(), conditionCode.begin(), conditionCode.end()); + + SolGroundCodeBlock checkBlock; 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); + checkBlock.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); + checkBlock.code.push_back(gi2); + code.push_back(checkBlock); + 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(); + + SolGroundCodeBlock endBlock; GroundInstruction gi3 = groundCreateInstruction(JUMP); groundAddReferenceToInstruction(&gi3, groundCreateReference(LINEREF, startLabelId)); - codeBlock.code.push_back(gi3); + endBlock.code.push_back(gi3); GroundInstruction gi4 = groundCreateInstruction(CREATELABEL); groundAddReferenceToInstruction(&gi4, groundCreateReference(LABEL, endLabelId)); - codeBlock.code.push_back(gi4); - code.push_back(codeBlock); + endBlock.code.push_back(gi4); + code.push_back(endBlock); break; } - case HGNodeType::Identifier: { + case SolNodeType::Identifier: { break; } - case HGNodeType::Set: { - HGGroundCodeBlock codeBlock; + case SolNodeType::Set: { + SolGroundCodeBlock codeBlock; GroundInstruction setInstruction = groundCreateInstruction(SET); groundAddReferenceToInstruction(&setInstruction, groundCreateReference(DIRREF, children[0].outputId.data())); groundAddReferenceToInstruction(&setInstruction, groundCreateReference(VALREF, children[1].outputId.data())); @@ -349,97 +356,97 @@ namespace HighGround { return false; } - HGDataType getDataType(std::string in) { + SolDataType getDataType(std::string in) { if (isInt(in)) { - return HGDataType::Int; + return SolDataType::Int; } if (isDouble(in)) { - return HGDataType::Double; + return SolDataType::Double; } if (isString(in)) { - return HGDataType::String; + return SolDataType::String; } if (isChar(in)) { - return HGDataType::Char; + return SolDataType::Char; } if (isBool(in)) { - return HGDataType::Bool; + return SolDataType::Bool; } - return HGDataType::None; + return SolDataType::None; } - HGNodeType getNodeType(std::string in) { - if (getDataType(in) != HGDataType::None) { - return HGNodeType::Value; + SolNodeType getNodeType(std::string in) { + if (getDataType(in) != SolDataType::None) { + return SolNodeType::Value; } if (in == "+") { - return HGNodeType::Add; + return SolNodeType::Add; } if (in == "=") { - return HGNodeType::Set; + return SolNodeType::Set; } if (in == "==") { - return HGNodeType::Equal; + return SolNodeType::Equal; } if (in == "!=") { - return HGNodeType::Inequal; + return SolNodeType::Inequal; } if (in == "puts") { - return HGNodeType::Puts; + return SolNodeType::Puts; } if (in == "if") { - return HGNodeType::If; + return SolNodeType::If; } if (in == "while") { - return HGNodeType::While; + return SolNodeType::While; } if (in == "{") { - return HGNodeType::CodeBlockStart; + return SolNodeType::CodeBlockStart; } if (in == "}") { - return HGNodeType::CodeBlockEnd; + return SolNodeType::CodeBlockEnd; } - return HGNodeType::Identifier; + return SolNodeType::Identifier; } public: Parser(std::vector in) : tokensToParse(in) {} - HGNode parse() { + SolNode parse() { current = 0; size = tokensToParse.size(); - HGNode rootNode(HGNodeType::Root); + SolNode rootNode(SolNodeType::Root); while (auto tokenopt = consume()) { std::string token = tokenopt.value(); switch (getNodeType(token)) { - case HGNodeType::Value: { + case SolNodeType::Value: { switch (getDataType(token)) { - case HGDataType::Int: { - HGNode intNode(HGNodeType::Value); + case SolDataType::Int: { + SolNode intNode(SolNodeType::Value); intNode.setValue((int64_t) std::stoll(token)); rootNode.addNode(intNode); break; } - case HGDataType::Double: { - HGNode doubleNode(HGNodeType::Value); + case SolDataType::Double: { + SolNode doubleNode(SolNodeType::Value); doubleNode.setValue(std::stod(token)); rootNode.addNode(doubleNode); break; } - case HGDataType::String: { - HGNode stringNode(HGNodeType::Value); + case SolDataType::String: { + SolNode stringNode(SolNodeType::Value); stringNode.setValue(token.substr(1, token.size() - 2)); rootNode.addNode(stringNode); break; } - case HGDataType::Char: { - HGNode charNode(HGNodeType::Value); + case SolDataType::Char: { + SolNode charNode(SolNodeType::Value); charNode.setValue(token[1]); rootNode.addNode(charNode); break; } - case HGDataType::Bool: { - HGNode boolNode(HGNodeType::Value); + case SolDataType::Bool: { + SolNode boolNode(SolNodeType::Value); boolNode.setValue(token == "true"); rootNode.addNode(boolNode); break; @@ -447,8 +454,8 @@ namespace HighGround { } break; } - case HGNodeType::Add: { - HGNode addNode(HGNodeType::Add); + case SolNodeType::Add: { + SolNode addNode(SolNodeType::Add); addNode.addNode(rootNode.children.back()); rootNode.children.pop_back(); auto tokenopt = consume(); @@ -461,8 +468,8 @@ namespace HighGround { rootNode.addNode(addNode); break; } - case HGNodeType::Equal: { - HGNode equalNode(HGNodeType::Equal); + case SolNodeType::Equal: { + SolNode equalNode(SolNodeType::Equal); equalNode.addNode(rootNode.children.back()); rootNode.children.pop_back(); auto tokenopt = consume(); @@ -475,8 +482,8 @@ namespace HighGround { rootNode.addNode(equalNode); break; } - case HGNodeType::Inequal: { - HGNode inequalNode(HGNodeType::Inequal); + case SolNodeType::Inequal: { + SolNode inequalNode(SolNodeType::Inequal); inequalNode.addNode(rootNode.children.back()); rootNode.children.pop_back(); auto tokenopt = consume(); @@ -489,8 +496,8 @@ namespace HighGround { rootNode.addNode(inequalNode); break; } - case HGNodeType::Puts: { - HGNode putsNode(HGNodeType::Puts); + case SolNodeType::Puts: { + SolNode putsNode(SolNodeType::Puts); std::vector tokens; while (auto tokenopt = consume()) { if (tokenopt.value() == "\n") { @@ -505,8 +512,8 @@ namespace HighGround { rootNode.addNode(putsNode); break; } - case HGNodeType::If: { - HGNode ifNode(HGNodeType::If); + case SolNodeType::If: { + SolNode ifNode(SolNodeType::If); std::vector tokens; while (auto tokenopt = consume()) { if (tokenopt.value() == "\n") { @@ -547,8 +554,8 @@ namespace HighGround { rootNode.addNode(ifNode); break; } - case HGNodeType::While: { - HGNode whileNode(HGNodeType::While); + case SolNodeType::While: { + SolNode whileNode(SolNodeType::While); std::vector tokens; while (auto tokenopt = consume()) { if (tokenopt.value() == "\n") { @@ -589,8 +596,8 @@ namespace HighGround { rootNode.addNode(whileNode); break; } - case HGNodeType::CodeBlockStart: { - HGNode codeBlockNode(HGNodeType::CodeBlock); + case SolNodeType::CodeBlockStart: { + SolNode codeBlockNode(SolNodeType::CodeBlock); size_t brackets = 1; std::vector tokens; while (auto tokenopt = consume()) { @@ -609,14 +616,14 @@ namespace HighGround { rootNode.addNode(codeBlockNode); break; } - case HGNodeType::Identifier: { - HGNode idNode(HGNodeType::Identifier); + case SolNodeType::Identifier: { + SolNode idNode(SolNodeType::Identifier); idNode.outputId = token; rootNode.addNode(idNode); break; } - case HGNodeType::Set: { - HGNode setNode(HGNodeType::Set); + case SolNodeType::Set: { + SolNode setNode(SolNodeType::Set); setNode.addNode(rootNode.children.back()); rootNode.children.pop_back(); std::vector tokens; @@ -637,7 +644,7 @@ namespace HighGround { } }; - GroundProgram assembleProgram(HGNode& rootNode) { + GroundProgram assembleProgram(SolNode& rootNode) { GroundProgram gp = groundCreateProgram(); auto code = rootNode.generateCode(); for (int i = 0; i < code.size(); i++) { @@ -735,6 +742,7 @@ namespace HighGround { break; } // tokens which may be followed by an equals sign + case '!': case '*': case '/': case '=': @@ -790,7 +798,7 @@ namespace HighGround { }; -} // namespace HighGround +} // namespace HigSolround int main(int argc, char** argv) { @@ -801,8 +809,8 @@ int main(int argc, char** argv) { std::ifstream file(argv[1]); std::ostringstream ss; ss << file.rdbuf(); - auto lexed = HighGround::Lexer(ss.str()).lex(); - auto parsed = HighGround::Parser::Parser(lexed).parse(); - GroundProgram program = HighGround::Parser::assembleProgram(parsed); + auto lexed = Solstice::Lexer(ss.str()).lex(); + auto parsed = Solstice::Parser::Parser(lexed).parse(); + GroundProgram program = Solstice::Parser::assembleProgram(parsed); groundRunProgram(&program); } diff --git a/tests/count.hg b/tests/count.sols similarity index 100% rename from tests/count.hg rename to tests/count.sols diff --git a/tests/data.hg b/tests/data.sols similarity index 100% rename from tests/data.hg rename to tests/data.sols diff --git a/tests/if.hg b/tests/if.sols similarity index 100% rename from tests/if.hg rename to tests/if.sols diff --git a/tests/int.hg b/tests/int.sols similarity index 100% rename from tests/int.hg rename to tests/int.sols diff --git a/tests/math.hg b/tests/math.sols similarity index 100% rename from tests/math.hg rename to tests/math.sols diff --git a/tests/print.hg b/tests/print.sols similarity index 100% rename from tests/print.hg rename to tests/print.sols diff --git a/tests/set.hg b/tests/set.sols similarity index 100% rename from tests/set.hg rename to tests/set.sols diff --git a/tests/while.hg b/tests/while.sols similarity index 100% rename from tests/while.hg rename to tests/while.sols