Update to reduce copying of expressions
This commit is contained in:
		@@ -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 << ')';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user