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

View File

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