Update to reduce copying of expressions

This commit is contained in:
Abdelrahman Said 2025-06-22 12:39:47 +01:00
parent c6f9307253
commit a6e129eb12
2 changed files with 17 additions and 16 deletions

View File

@ -7,6 +7,7 @@
#include <vector>
#include <sstream>
// Copy constructor
Expr::Expr(const Expr &other) : type{other.type} {
switch(type) {
case ExprType::BINARY: {
@ -36,7 +37,7 @@ Expr::Expr(const Expr &other) : type{other.type} {
Expr::Expr(const Expr &&other) : type{other.type}, value{std::move(other.value)} {}
// Binary expressoin
Expr::Expr(Expr left, Token op, Expr right)
Expr::Expr(const Expr &left, Token op, const Expr &right)
: type{ExprType::BINARY}, value{std::make_shared<Binary>(left, op, right)} {}
// Literal expression
@ -44,12 +45,12 @@ Expr::Expr(Object value)
: type{ExprType::LITERAL}, value{std::make_shared<Literal>(value)} {}
// Unary expressoin
Expr::Expr(Token op, Expr right)
Expr::Expr(Token op, const Expr &right)
: type{ExprType::UNARY}, value{std::make_shared<Unary>(op, right)} {}
// Group expression
// Has to take an extra parameter to avoid conflicting with copy constructor
Expr::Expr(Expr expr, void *ptr)
Expr::Expr(const Expr &expr, void *ptr)
: type{ExprType::GROUPING}, value{std::make_shared<Grouping>(expr)} { (void)ptr; }
std::string AstPrinter::print(const Expr &expr) {
@ -57,12 +58,12 @@ std::string AstPrinter::print(const Expr &expr) {
case ExprType::BINARY: {
std::shared_ptr<Binary> binary = std::get<std::shared_ptr<Binary>>(expr.value);
assert(binary != nullptr);
return parenthesize(binary->op.lexeme, {binary->left, binary->right});
return parenthesize(binary->op.lexeme, {&binary->left, &binary->right});
}
case ExprType::GROUPING: {
std::shared_ptr<Grouping> group = std::get<std::shared_ptr<Grouping>>(expr.value);
assert(group != nullptr);
return parenthesize("group", {group->expr});
return parenthesize("group", {&group->expr});
}
case ExprType::LITERAL: {
std::shared_ptr<Literal> literal = std::get<std::shared_ptr<Literal>>(expr.value);
@ -84,16 +85,16 @@ std::string AstPrinter::print(const Expr &expr) {
case ExprType::UNARY: {
std::shared_ptr<Unary> unary = std::get<std::shared_ptr<Unary>>(expr.value);
assert(unary != nullptr);
return parenthesize(unary->op.lexeme, {unary->right});
return parenthesize(unary->op.lexeme, {&unary->right});
}
}
}
std::string AstPrinter::parenthesize(const std::string &name, std::vector<Expr> exprs) {
std::string AstPrinter::parenthesize(const std::string &name, std::vector<const Expr *> exprs) {
std::stringstream ss{};
ss << '(' << name;
for (auto &expr : exprs) {
ss << ' ' << print(expr);
for (const Expr *expr : exprs) {
ss << ' ' << print(*expr);
}
ss << ')';

View File

@ -34,31 +34,31 @@ struct Expr {
Expr(const Expr &&other);
// Binary expressoin
Expr(Expr left, Token op, Expr right);
Expr(const Expr &left, Token op, const Expr &right);
// Literal expression
Expr(Object value);
// Unary expressoin
Expr(Token op, Expr right);
Expr(Token op, const Expr &right);
// Group expression
// Has to take an extra parameter to avoid conflicting with copy constructor
Expr(Expr expr, void *ptr);
Expr(const Expr &expr, void *ptr);
ExprType type;
ExprVariant value;
};
struct Binary {
Binary(Expr left, Token op, Expr right) : left{left}, op{op}, right{right} {}
Binary(const Expr &left, Token op, const Expr &right) : left{left}, op{op}, right{right} {}
Expr left;
Token op;
Expr right;
};
struct Grouping {
Grouping(Expr expr) : expr{expr} {}
Grouping(const Expr &expr) : expr{expr} {}
Expr expr;
};
@ -68,7 +68,7 @@ struct Literal {
};
struct Unary {
Unary(Token op, Expr right) : op{op}, right{right} {}
Unary(Token op, const Expr &right) : op{op}, right{right} {}
Token op;
Expr right;
};
@ -77,7 +77,7 @@ class AstPrinter {
public:
std::string print(const Expr &expr);
private:
std::string parenthesize(const std::string &name, std::vector<Expr> exprs);
std::string parenthesize(const std::string &name, std::vector<const Expr *> exprs);
};
#endif