diff --git a/cclox_src/main.cc b/cclox_src/main.cc index 493db57..76f035a 100644 --- a/cclox_src/main.cc +++ b/cclox_src/main.cc @@ -2,6 +2,7 @@ #include "error_handler.hh" #include "parser.hh" #include +#include #include ErrorHandler error_handler{}; @@ -16,11 +17,15 @@ int main(int argc, char *argv[]) { // // run_interpreter(argc, argv); - Unary left {Token{TokenType::MINUS, "-", Object{}, 1}, Literal{123}}; - Token op{TokenType::STAR, "*", Object{}, 1}; - Grouping right{Literal{45.67}}; + ExprPtr literal = std::make_shared(ExprType::LITERAL, Literal{123}); + ExprPtr left = std::make_shared(ExprType::UNARY, Unary{Token{TokenType::MINUS, "-", Object{}, 1}, literal}); - Binary expr {left, op, right}; + Token op{TokenType::STAR, "*", Object{}, 1}; + + ExprPtr gliteral = std::make_shared(ExprType::LITERAL, Literal{45.67}); + ExprPtr right = std::make_shared(ExprType::GROUPING, gliteral); + + Expr expr = {ExprType::BINARY, Binary{left, op, right}}; AstPrinter printer{}; std::cout << printer.print(expr) << '\n'; diff --git a/cclox_src/parser/expr.cc b/cclox_src/parser/expr.cc index 53b5613..5e3af02 100644 --- a/cclox_src/parser/expr.cc +++ b/cclox_src/parser/expr.cc @@ -1,20 +1,24 @@ #include "expr.hh" #include "../tokenizer.hh" +#include #include -#include -#include #include #include -std::string AstPrinter::print(const Expression &expr) { - return std::visit([this](auto &&node) -> std::string { - using T = std::decay_t; - - if constexpr(std::is_same_v) { - return parenthesize(node.op.lexeme, {node.left, node.right}); - } else if constexpr(std::is_same_v) { - return parenthesize("group", {node.expression}); - } else if constexpr(std::is_same_v) { +std::string AstPrinter::print(const Expr &expr) { + switch (expr.type) { + case ExprType::BINARY: { + Binary node = std::get(expr.value); + assert(node.left != NULL && node.right != NULL); + return parenthesize(node.op.lexeme, {*node.left, *node.right}); + } + case ExprType::GROUPING: { + Grouping node = std::get(expr.value); + assert(node.expression != NULL); + return parenthesize("group", {*node.expression}); + } + case ExprType::LITERAL: { + Literal node = std::get(expr.value); switch (node.value.type) { case ObjectType::NIL: return "nil"; @@ -28,22 +32,20 @@ std::string AstPrinter::print(const Expression &expr) { return std::to_string(value); } } - } else if constexpr(std::is_same_v) { - return parenthesize(node.op.lexeme, {node.right}); } - - return ""; - }, expr); + case ExprType::UNARY: { + Unary node = std::get(expr.value); + assert(node.right != NULL); + return parenthesize(node.op.lexeme, {*node.right}); + } + } } -std::string AstPrinter::parenthesize(const std::string &name, std::vector exprs) { +std::string AstPrinter::parenthesize(const std::string &name, std::vector exprs) { std::stringstream ss{}; ss << '(' << name; for (auto &expr : exprs) { - std::string value = std::visit([this](auto &&node) -> std::string { - return print(node); - }, expr); - ss << ' ' << value; + ss << ' ' << print(expr); } ss << ')'; diff --git a/cclox_src/parser/expr.hh b/cclox_src/parser/expr.hh index 3f0ecd3..41c5fdc 100644 --- a/cclox_src/parser/expr.hh +++ b/cclox_src/parser/expr.hh @@ -2,45 +2,61 @@ #define EXPR_HH #include "../tokenizer.hh" +#include #include #include -struct Expr {}; +struct Expr; -struct Binary : public Expr { - Binary(Expr left, Token op, Expr right) : left{left}, op{op}, right{right} {}; +using ExprPtr = std::shared_ptr; - Expr left; +struct Binary { + Binary(ExprPtr left, Token op, ExprPtr right) : left{left}, op{op}, right{right} {}; + + ExprPtr left; Token op; - Expr right; + ExprPtr right; }; -struct Grouping : public Expr { - Grouping(Expr expr) : expression{expr} {}; +struct Grouping { + Grouping(ExprPtr expr) : expression{expr} {}; - Expr expression; + ExprPtr expression; }; -struct Literal : public Expr { +struct Literal { Literal(Object value) : value{value} {}; Object value; }; -struct Unary : public Expr { - Unary(Token op, Expr right) : op{op}, right{right} {}; +struct Unary { + Unary(Token op, ExprPtr right) : op{op}, right{right} {}; Token op; - Expr right; + ExprPtr right; }; -using Expression = std::variant; +enum class ExprType { + BINARY, + GROUPING, + LITERAL, + UNARY, +}; + +using Expression = std::variant; + +struct Expr { + Expr(ExprType type, Expression value) : type{type}, value{value} {} + ExprType type; + Expression value; +}; class AstPrinter { public: - std::string print(const Expression &expr); + std::string print(const Expr &expr); private: - std::string parenthesize(const std::string &name, std::vector exprs); + std::string parenthesize(const std::string &name, std::vector exprs); }; #endif