Improved solution with inline functions

This commit is contained in:
Abdelrahman Said 2025-06-20 23:25:12 +01:00
parent de85b0d93c
commit c78e694f87
3 changed files with 33 additions and 43 deletions

View File

@ -18,13 +18,15 @@ int main(int argc, char *argv[]) {
// run_interpreter(argc, argv); // run_interpreter(argc, argv);
Token unary_op{TokenType::MINUS, "-", Object{}, 1}; Token unary_op{TokenType::MINUS, "-", Object{}, 1};
ExprPtr left = UnaryExprPtr(unary_op, LiteralExprPtr(123)); Expr left_literal = Literal(123);
Expr left = Unary(unary_op, left_literal.to_expr_ptr());
Token op{TokenType::STAR, "*", Object{}, 1}; Token op{TokenType::STAR, "*", Object{}, 1};
ExprPtr right = GroupingExprPtr(LiteralExprPtr(45.67)); Expr right_literal = Literal(45.67);
Expr right = Grouping(right_literal.to_expr_ptr());
Expr expr = BinaryExpr(left, op, right); Expr expr = Binary(left.to_expr_ptr(), op, right.to_expr_ptr());
AstPrinter printer{}; AstPrinter printer{};
std::cout << printer.print(expr) << '\n'; std::cout << printer.print(expr) << '\n';

View File

@ -8,17 +8,17 @@
std::string AstPrinter::print(const Expr &expr) { std::string AstPrinter::print(const Expr &expr) {
switch (expr.type) { switch (expr.type) {
case ExprType::BINARY: { case ExprType::BINARY: {
Binary node = std::get<Binary>(expr.value); _Binary node = std::get<_Binary>(expr.value);
assert(node.left != NULL && node.right != NULL); assert(node.left != NULL && node.right != NULL);
return parenthesize(node.op.lexeme, {*node.left, *node.right}); return parenthesize(node.op.lexeme, {*node.left, *node.right});
} }
case ExprType::GROUPING: { case ExprType::GROUPING: {
Grouping node = std::get<Grouping>(expr.value); _Grouping node = std::get<_Grouping>(expr.value);
assert(node.expression != NULL); assert(node.expression != NULL);
return parenthesize("group", {*node.expression}); return parenthesize("group", {*node.expression});
} }
case ExprType::LITERAL: { case ExprType::LITERAL: {
Literal node = std::get<Literal>(expr.value); _Literal node = std::get<_Literal>(expr.value);
switch (node.value.type) { switch (node.value.type) {
case ObjectType::NIL: case ObjectType::NIL:
return "nil"; return "nil";
@ -34,7 +34,7 @@ std::string AstPrinter::print(const Expr &expr) {
} }
} }
case ExprType::UNARY: { case ExprType::UNARY: {
Unary node = std::get<Unary>(expr.value); _Unary node = std::get<_Unary>(expr.value);
assert(node.right != NULL); assert(node.right != NULL);
return parenthesize(node.op.lexeme, {*node.right}); return parenthesize(node.op.lexeme, {*node.right});
} }

View File

@ -6,55 +6,25 @@
#include <string> #include <string>
#include <variant> #include <variant>
#define BinaryExpr(LEFT, OP, RIGHT) ( \
Expr{ \
.type = ExprType::BINARY, \
.value = Binary{.left = LEFT, .op = OP, .right = RIGHT} \
} \
)
#define GroupingExpr(EXPR) ( \
Expr{ \
.type = ExprType::GROUPING, \
.value = Grouping{.expression = EXPR} \
} \
)
#define LiteralExpr(VALUE) ( \
Expr{ \
.type = ExprType::LITERAL, \
.value = Literal{.value = VALUE} \
} \
)
#define UnaryExpr(OP, RIGHT) ( \
Expr{ \
.type = ExprType::UNARY, \
.value = Unary{.op = OP, .right = RIGHT} \
} \
)
#define BinaryExprPtr(LEFT, OP, RIGHT) (std::make_shared<Expr>(BinaryExpr(LEFT, OP, RIGHT)))
#define GroupingExprPtr(EXPR) (std::make_shared<Expr>(GroupingExpr(EXPR)))
#define LiteralExprPtr(VALUE) (std::make_shared<Expr>(LiteralExpr(VALUE)))
#define UnaryExprPtr(OP, RIGHT) (std::make_shared<Expr>(UnaryExpr(OP, RIGHT)))
struct Expr; struct Expr;
using ExprPtr = std::shared_ptr<Expr>; using ExprPtr = std::shared_ptr<Expr>;
struct Binary { struct _Binary {
ExprPtr left; ExprPtr left;
Token op; Token op;
ExprPtr right; ExprPtr right;
}; };
struct Grouping { struct _Grouping {
ExprPtr expression; ExprPtr expression;
}; };
struct Literal { struct _Literal {
Object value; Object value;
}; };
struct Unary { struct _Unary {
Token op; Token op;
ExprPtr right; ExprPtr right;
}; };
@ -66,13 +36,31 @@ enum class ExprType {
UNARY, UNARY,
}; };
using Expression = std::variant<Binary, Grouping, Literal, Unary>; using ExprVariant = std::variant<_Binary, _Grouping, _Literal, _Unary>;
struct Expr { struct Expr {
ExprType type; ExprType type;
Expression value; ExprVariant value;
ExprPtr to_expr_ptr() { return std::make_shared<Expr>(*this); }
}; };
inline Expr Binary(ExprPtr left, Token op, ExprPtr right) {
return Expr{ExprType::BINARY, _Binary{left, op, right}};
}
inline Expr Grouping(ExprPtr expr) {
return Expr{ExprType::GROUPING, _Grouping{expr}};
}
inline Expr Literal(Object value) {
return Expr{ExprType::LITERAL, _Literal{value}};
}
inline Expr Unary(Token op, ExprPtr right) {
return Expr{ExprType::UNARY, _Unary{op, right}};
}
class AstPrinter { class AstPrinter {
public: public:
std::string print(const Expr &expr); std::string print(const Expr &expr);