diff --git a/src/lexer/lexer.cpp b/src/lexer/lexer.cpp index 9646062..eab5ee5 100644 --- a/src/lexer/lexer.cpp +++ b/src/lexer/lexer.cpp @@ -1,6 +1,7 @@ #include "lexer.hpp" #include #include +#include using TT = Solstice::TokenType; @@ -30,36 +31,59 @@ namespace Solstice { {"/", TT::Math_Divide} }; + std::ostream& operator<<(std::ostream& stream, const Literal& literal) { + switch (literal.type) { + case LiteralType::None: + stream << ""; + break; + case LiteralType::Bool: + stream << (*literal.getBool() ? "true" : "false"); + break; + case LiteralType::Char: + stream << *literal.getChar(); + break; + case LiteralType::Double: + stream << *literal.getDouble(); + break; + case LiteralType::Int: + stream << *literal.getInt(); + break; + case LiteralType::String: + stream << *literal.getString(); + break; + } + return stream; + } - std::optional Literal::getString() { + std::optional Literal::getString() const { if (std::holds_alternative(data)) { return std::get(data); } return {}; } - std::optional Literal::getInt() { + std::optional Literal::getInt() const { if (std::holds_alternative(data)) { return std::get(data); } return {}; } - std::optional Literal::getDouble() { + std::optional Literal::getDouble() const { if (std::holds_alternative(data)) { return std::get(data); } return {}; } - std::optional Literal::getChar() { + std::optional Literal::getChar() const { if (std::holds_alternative(data)) { return std::get(data); } return {}; } - std::optional Literal::getBool() { + std::optional Literal::getBool() const { if (std::holds_alternative(data)) { return std::get(data); } diff --git a/src/lexer/lexer.hpp b/src/lexer/lexer.hpp index 90ba010..21bfe70 100644 --- a/src/lexer/lexer.hpp +++ b/src/lexer/lexer.hpp @@ -66,11 +66,11 @@ namespace Solstice { LiteralType type = LiteralType::None; - std::optional getString(); - std::optional getInt(); - std::optional getDouble(); - std::optional getChar(); - std::optional getBool(); + std::optional getString() const; + std::optional getInt() const; + std::optional getDouble() const; + std::optional getChar() const; + std::optional getBool() const; Literal(const std::string& in) : type(LiteralType::String), data(in) {} Literal(int64_t in) : type(LiteralType::Int), data(in) {} @@ -82,6 +82,8 @@ namespace Solstice { }; + std::ostream& operator<<(std::ostream& stream, const Literal& literal); + class Token { std::variant data; diff --git a/src/main.cpp b/src/main.cpp index 19e06b5..00cb3b9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,11 +5,12 @@ int main() { try { - Solstice::Lexer lexer{"2 + 2"}; + Solstice::Lexer lexer{"2 + 2 / 5"}; auto lexed = lexer.lex(); Solstice::Parser parser{lexed}; auto parsed = parser.parse(); + std::cout << parsed << std::endl; } catch (const std::runtime_error& e) { std::cout << e.what() << std::endl; diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index d6a83ac..49e8725 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -1,6 +1,8 @@ #include "parser.hpp" #include #include +#include +#include using TT = Solstice::TokenType; @@ -17,6 +19,88 @@ namespace Solstice { {TT::Comparison_LesserThan, NodeType::LesserThan}, }; + std::optional Node::getLiteral() const { + if (std::holds_alternative(data)) { + return std::get(data); + } + return {}; + } + std::optional Node::getIdentifier() const { + if (std::holds_alternative(data)) { + return std::get(data); + } + return {}; + } + + static inline std::string nodeTypeToString(NodeType type) { + switch (type) { + case NodeType::Root: + return "Root"; + case NodeType::Literal: + return "Literal"; + case NodeType::Identifier: + return "Identifier"; + case NodeType::FunctionBind: + return "FunctionBind"; + case NodeType::Bind: + return "Bind"; + case NodeType::Set: + return "Set"; + case NodeType::Lambda: + return "Lambda"; + case NodeType::FunctionCall: + return "FunctionCall"; + case NodeType::Add: + return "Add"; + case NodeType::Subtract: + return "Subtract"; + case NodeType::Multiply: + return "Multiply"; + case NodeType::Divide: + return "Divide"; + case NodeType::Equal: + return "Equal"; + case NodeType::NotEqual: + return "NotEqual"; + case NodeType::GreaterThan: + return "GreaterThan"; + case NodeType::LesserThan: + return "LesserThan"; + + } + } + + std::ostream& operator<<(std::ostream& stream, const Node& node) { + stream << "Node( Type=" << nodeTypeToString(node.type); + if (node.type == NodeType::Literal) { + auto lit = node.getLiteral(); + if (lit.has_value()) { + stream << ", Literal: " << *lit; + } + } else if (node.type == NodeType::Identifier) { + auto id = node.getIdentifier(); + if (id.has_value()) { + stream << ", Identifier: " << *id; + } + } + + if (!node.children.empty()) { + stream << ", Children: { "; + bool first = true; + for (const auto& node : node.children) { + if (first) { + first = false; + } else { + stream << ", "; + } + stream << node; + } + stream << " }"; + } + stream << " )"; + return stream; + } + std::optional Parser::peek(int64_t ahead) { if (current + ahead >= input.size() || current + ahead < 0) { return {}; diff --git a/src/parser/parser.hpp b/src/parser/parser.hpp index 40fc1f4..55558b9 100644 --- a/src/parser/parser.hpp +++ b/src/parser/parser.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -42,8 +43,13 @@ namespace Solstice { Node(NodeType type, const std::vector& children) : type(type), children(children) {} Node(const Literal& literal) : type(NodeType::Literal), data(literal) {} Node(const std::string& id) : type(NodeType::Identifier), data(id) {} + + std::optional getLiteral() const; + std::optional getIdentifier() const; }; + std::ostream& operator<<(std::ostream& stream, const Node& node); + class Parser { std::vector input;