Switch to macros for better readability and add printer.hh
This commit is contained in:
		@@ -18,13 +18,13 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
  // run_interpreter(argc, argv);
 | 
			
		||||
 | 
			
		||||
  Token unary_op{TokenType::MINUS, "-", Object{}, 1};
 | 
			
		||||
  Expr left{unary_op, Expr{123}};
 | 
			
		||||
  Expr left{Unary(unary_op, Literal(123))};
 | 
			
		||||
 | 
			
		||||
  Token op{TokenType::STAR, "*", Object{}, 1};
 | 
			
		||||
 | 
			
		||||
  Expr right{Expr{45.67}, nullptr};
 | 
			
		||||
  Expr right{Grouping(Literal(45.67))};
 | 
			
		||||
 | 
			
		||||
  Expr expr{left, op, right};
 | 
			
		||||
  Expr expr{Binary(left, op, right)};
 | 
			
		||||
 | 
			
		||||
  AstPrinter printer{};
 | 
			
		||||
  std::cout << printer.print(expr) << '\n';
 | 
			
		||||
 
 | 
			
		||||
@@ -2,5 +2,6 @@
 | 
			
		||||
#define PARSER_CC
 | 
			
		||||
 | 
			
		||||
#include "parser/expr.cc"
 | 
			
		||||
#include "parser/printer.cc"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -2,5 +2,6 @@
 | 
			
		||||
#define PARSER_HH
 | 
			
		||||
 | 
			
		||||
#include "parser/expr.hh"
 | 
			
		||||
#include "parser/printer.hh"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -2,101 +2,176 @@
 | 
			
		||||
#include "../tokenizer.hh"
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
 | 
			
		||||
Expr::Expr(ExprType type, ExprVariant value) : type{type}, value{value} {}
 | 
			
		||||
 | 
			
		||||
// Copy constructor
 | 
			
		||||
Expr::Expr(const Expr &other) : type{other.type} {
 | 
			
		||||
  switch(type) {
 | 
			
		||||
    case ExprType::BINARY: {
 | 
			
		||||
      std::shared_ptr<Binary> ptr = std::get<std::shared_ptr<Binary>>(other.value);
 | 
			
		||||
      value = std::make_shared<Binary>(*ptr);
 | 
			
		||||
      std::shared_ptr<_Binary> ptr = std::get<std::shared_ptr<_Binary>>(other.value);
 | 
			
		||||
      value = std::make_shared<_Binary>(*ptr);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::GROUPING: {
 | 
			
		||||
      std::shared_ptr<Grouping> ptr = std::get<std::shared_ptr<Grouping>>(other.value);
 | 
			
		||||
      value = std::make_shared<Grouping>(*ptr);
 | 
			
		||||
      std::shared_ptr<_Grouping> ptr = std::get<std::shared_ptr<_Grouping>>(other.value);
 | 
			
		||||
      value = std::make_shared<_Grouping>(*ptr);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::LITERAL: {
 | 
			
		||||
      std::shared_ptr<Literal> ptr = std::get<std::shared_ptr<Literal>>(other.value);
 | 
			
		||||
      value = std::make_shared<Literal>(*ptr);
 | 
			
		||||
      std::shared_ptr<_Literal> ptr = std::get<std::shared_ptr<_Literal>>(other.value);
 | 
			
		||||
      value = std::make_shared<_Literal>(*ptr);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::UNARY: {
 | 
			
		||||
      std::shared_ptr<Unary> ptr = std::get<std::shared_ptr<Unary>>(other.value);
 | 
			
		||||
      value = std::make_shared<Unary>(*ptr);
 | 
			
		||||
      std::shared_ptr<_Unary> ptr = std::get<std::shared_ptr<_Unary>>(other.value);
 | 
			
		||||
      value = std::make_shared<_Unary>(*ptr);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Move constructor
 | 
			
		||||
Expr::Expr(const Expr &&other) : type{other.type}, value{std::move(other.value)} {}
 | 
			
		||||
 | 
			
		||||
// Binary expressoin
 | 
			
		||||
Expr::Expr(const Expr &left, Token op, const Expr &right)
 | 
			
		||||
  : type{ExprType::BINARY}, value{std::make_shared<Binary>(left, op, right)} {}
 | 
			
		||||
 | 
			
		||||
// Literal expression
 | 
			
		||||
Expr::Expr(Object value)
 | 
			
		||||
  : type{ExprType::LITERAL}, value{std::make_shared<Literal>(value)} {}
 | 
			
		||||
 | 
			
		||||
// Unary expressoin
 | 
			
		||||
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(const Expr &expr, void *ptr)
 | 
			
		||||
  : type{ExprType::GROUPING}, value{std::make_shared<Grouping>(expr)} { (void)ptr; }
 | 
			
		||||
 | 
			
		||||
std::string AstPrinter::print(const Expr &expr) {
 | 
			
		||||
  switch (expr.type) {
 | 
			
		||||
Expr::Expr(const Expr &&other) : type{other.type}, value{std::move(other.value)} {
 | 
			
		||||
  switch(type) {
 | 
			
		||||
    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});
 | 
			
		||||
      std::shared_ptr<_Binary> ptr = std::get<std::shared_ptr<_Binary>>(other.value);
 | 
			
		||||
      ptr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::GROUPING: {
 | 
			
		||||
      std::shared_ptr<Grouping> group = std::get<std::shared_ptr<Grouping>>(expr.value);
 | 
			
		||||
      assert(group != nullptr);
 | 
			
		||||
      return parenthesize("group", {&group->expr});
 | 
			
		||||
      std::shared_ptr<_Grouping> ptr = std::get<std::shared_ptr<_Grouping>>(other.value);
 | 
			
		||||
      ptr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::LITERAL: {
 | 
			
		||||
      std::shared_ptr<Literal> literal = std::get<std::shared_ptr<Literal>>(expr.value);
 | 
			
		||||
      assert(literal != nullptr);
 | 
			
		||||
      switch (literal->value.type) {
 | 
			
		||||
        case ObjectType::NIL:
 | 
			
		||||
          return "nil";
 | 
			
		||||
        case ObjectType::IDENTIFIER:
 | 
			
		||||
        case ObjectType::STRING_LIT: {
 | 
			
		||||
          std::string value = std::get<std::string>(literal->value.value);
 | 
			
		||||
          return value;
 | 
			
		||||
        }
 | 
			
		||||
        case ObjectType::NUMBER: {
 | 
			
		||||
          double value = std::get<double>(literal->value.value);
 | 
			
		||||
          return std::to_string(value);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      std::shared_ptr<_Literal> ptr = std::get<std::shared_ptr<_Literal>>(other.value);
 | 
			
		||||
      ptr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    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});
 | 
			
		||||
      std::shared_ptr<_Unary> ptr = std::get<std::shared_ptr<_Unary>>(other.value);
 | 
			
		||||
      ptr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string AstPrinter::parenthesize(const std::string &name, std::vector<const Expr *> exprs) {
 | 
			
		||||
  std::stringstream ss{};
 | 
			
		||||
  ss << '(' << name;
 | 
			
		||||
  for (const Expr *expr : exprs) {
 | 
			
		||||
    ss << ' ' << print(*expr);
 | 
			
		||||
// Copy assignment
 | 
			
		||||
Expr &Expr::operator=(const Expr &other) {
 | 
			
		||||
  if (this == &other) {
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  ss << ')';
 | 
			
		||||
 | 
			
		||||
  return ss.str();
 | 
			
		||||
  switch(type) {
 | 
			
		||||
    case ExprType::BINARY: {
 | 
			
		||||
      std::shared_ptr<_Binary> ptr = std::get<std::shared_ptr<_Binary>>(value);
 | 
			
		||||
      ptr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::GROUPING: {
 | 
			
		||||
      std::shared_ptr<_Grouping> ptr = std::get<std::shared_ptr<_Grouping>>(value);
 | 
			
		||||
      ptr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::LITERAL: {
 | 
			
		||||
      std::shared_ptr<_Literal> ptr = std::get<std::shared_ptr<_Literal>>(value);
 | 
			
		||||
      ptr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::UNARY: {
 | 
			
		||||
      std::shared_ptr<_Unary> ptr = std::get<std::shared_ptr<_Unary>>(value);
 | 
			
		||||
      ptr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  type = other.type;
 | 
			
		||||
 | 
			
		||||
  switch(type) {
 | 
			
		||||
    case ExprType::BINARY: {
 | 
			
		||||
      std::shared_ptr<_Binary> ptr = std::get<std::shared_ptr<_Binary>>(other.value);
 | 
			
		||||
      value = std::make_shared<_Binary>(*ptr);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::GROUPING: {
 | 
			
		||||
      std::shared_ptr<_Grouping> ptr = std::get<std::shared_ptr<_Grouping>>(other.value);
 | 
			
		||||
      value = std::make_shared<_Grouping>(*ptr);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::LITERAL: {
 | 
			
		||||
      std::shared_ptr<_Literal> ptr = std::get<std::shared_ptr<_Literal>>(other.value);
 | 
			
		||||
      value = std::make_shared<_Literal>(*ptr);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::UNARY: {
 | 
			
		||||
      std::shared_ptr<_Unary> ptr = std::get<std::shared_ptr<_Unary>>(other.value);
 | 
			
		||||
      value = std::make_shared<_Unary>(*ptr);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Move assignment
 | 
			
		||||
Expr &Expr::operator=(const Expr &&other) {
 | 
			
		||||
  if (this == &other) {
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  switch(type) {
 | 
			
		||||
    case ExprType::BINARY: {
 | 
			
		||||
      std::shared_ptr<_Binary> ptr = std::get<std::shared_ptr<_Binary>>(value);
 | 
			
		||||
      ptr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::GROUPING: {
 | 
			
		||||
      std::shared_ptr<_Grouping> ptr = std::get<std::shared_ptr<_Grouping>>(value);
 | 
			
		||||
      ptr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::LITERAL: {
 | 
			
		||||
      std::shared_ptr<_Literal> ptr = std::get<std::shared_ptr<_Literal>>(value);
 | 
			
		||||
      ptr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::UNARY: {
 | 
			
		||||
      std::shared_ptr<_Unary> ptr = std::get<std::shared_ptr<_Unary>>(value);
 | 
			
		||||
      ptr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  type = other.type;
 | 
			
		||||
 | 
			
		||||
  switch(type) {
 | 
			
		||||
    case ExprType::BINARY: {
 | 
			
		||||
      std::shared_ptr<_Binary> optr = std::get<std::shared_ptr<_Binary>>(other.value);
 | 
			
		||||
      value = std::move(other.value);
 | 
			
		||||
      optr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::GROUPING: {
 | 
			
		||||
      std::shared_ptr<_Grouping> optr = std::get<std::shared_ptr<_Grouping>>(other.value);
 | 
			
		||||
      value = std::move(other.value);
 | 
			
		||||
      optr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::LITERAL: {
 | 
			
		||||
      std::shared_ptr<_Literal> optr = std::get<std::shared_ptr<_Literal>>(other.value);
 | 
			
		||||
      value = std::move(other.value);
 | 
			
		||||
      optr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::UNARY: {
 | 
			
		||||
      std::shared_ptr<_Unary> optr = std::get<std::shared_ptr<_Unary>>(other.value);
 | 
			
		||||
      value = std::move(other.value);
 | 
			
		||||
      optr.reset();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return *this;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,14 +3,13 @@
 | 
			
		||||
 | 
			
		||||
#include "../tokenizer.hh"
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <variant>
 | 
			
		||||
 | 
			
		||||
struct Expr;
 | 
			
		||||
struct Binary;
 | 
			
		||||
struct Grouping;
 | 
			
		||||
struct Literal;
 | 
			
		||||
struct Unary;
 | 
			
		||||
struct _Binary;
 | 
			
		||||
struct _Grouping;
 | 
			
		||||
struct _Literal;
 | 
			
		||||
struct _Unary;
 | 
			
		||||
 | 
			
		||||
enum class ExprType {
 | 
			
		||||
  BINARY,
 | 
			
		||||
@@ -20,64 +19,57 @@ enum class ExprType {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
using ExprVariant = std::variant<
 | 
			
		||||
  std::shared_ptr<Binary>,
 | 
			
		||||
  std::shared_ptr<Grouping>,
 | 
			
		||||
  std::shared_ptr<Literal>,
 | 
			
		||||
  std::shared_ptr<Unary>
 | 
			
		||||
  std::shared_ptr<_Binary>,
 | 
			
		||||
  std::shared_ptr<_Grouping>,
 | 
			
		||||
  std::shared_ptr<_Literal>,
 | 
			
		||||
  std::shared_ptr<_Unary>
 | 
			
		||||
>;
 | 
			
		||||
 | 
			
		||||
#define Binary(LEFT, OP, RIGHT) (Expr{ExprType::BINARY, std::make_shared<_Binary>(LEFT, OP, RIGHT)})
 | 
			
		||||
#define Grouping(EXPR) (Expr{ExprType::GROUPING, std::make_shared<_Grouping>(EXPR)})
 | 
			
		||||
#define Literal(VALUE) (Expr{ExprType::LITERAL, std::make_shared<_Literal>(VALUE)})
 | 
			
		||||
#define Unary(OP, RIGHT) (Expr{ExprType::UNARY, std::make_shared<_Unary>(OP, RIGHT)})
 | 
			
		||||
 | 
			
		||||
struct Expr {
 | 
			
		||||
  Expr(ExprType type, ExprVariant value);
 | 
			
		||||
 | 
			
		||||
  // Copy constructor
 | 
			
		||||
  Expr(const Expr &other);
 | 
			
		||||
 | 
			
		||||
  // Move constructor
 | 
			
		||||
  Expr(const Expr &&other);
 | 
			
		||||
 | 
			
		||||
  // Binary expressoin
 | 
			
		||||
  Expr(const Expr &left, Token op, const Expr &right);
 | 
			
		||||
  // Copy assignment
 | 
			
		||||
  Expr &operator=(const Expr &other);
 | 
			
		||||
 | 
			
		||||
  // Literal expression
 | 
			
		||||
  Expr(Object value);
 | 
			
		||||
 | 
			
		||||
  // Unary expressoin
 | 
			
		||||
  Expr(Token op, const Expr &right);
 | 
			
		||||
 | 
			
		||||
  // Group expression
 | 
			
		||||
  // Has to take an extra parameter to avoid conflicting with copy constructor
 | 
			
		||||
  Expr(const Expr &expr, void *ptr);
 | 
			
		||||
  // Move assignment
 | 
			
		||||
  Expr &operator=(const Expr &&other);
 | 
			
		||||
 | 
			
		||||
  ExprType type;
 | 
			
		||||
  ExprVariant value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Binary {
 | 
			
		||||
  Binary(const Expr &left, Token op, const Expr &right) : left{left}, op{op}, right{right} {}
 | 
			
		||||
struct _Binary {
 | 
			
		||||
  _Binary(const Expr &left, Token op, const Expr &right) : left{left}, op{op}, right{right} {}
 | 
			
		||||
  Expr left;
 | 
			
		||||
  Token op;
 | 
			
		||||
  Expr right;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Grouping {
 | 
			
		||||
  Grouping(const Expr &expr) : expr{expr} {}
 | 
			
		||||
struct _Grouping {
 | 
			
		||||
  _Grouping(const Expr &expr) : expr{expr} {}
 | 
			
		||||
  Expr expr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Literal {
 | 
			
		||||
  Literal(Object value) : value{value} {}
 | 
			
		||||
struct _Literal {
 | 
			
		||||
  _Literal(Object value) : value{value} {}
 | 
			
		||||
  Object value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Unary {
 | 
			
		||||
  Unary(Token op, const Expr &right) : op{op}, right{right} {}
 | 
			
		||||
struct _Unary {
 | 
			
		||||
  _Unary(Token op, const Expr &right) : op{op}, right{right} {}
 | 
			
		||||
  Token op;
 | 
			
		||||
  Expr right;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class AstPrinter {
 | 
			
		||||
public:
 | 
			
		||||
  std::string print(const Expr &expr);
 | 
			
		||||
private:
 | 
			
		||||
  std::string parenthesize(const std::string &name, std::vector<const Expr *> exprs);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								cclox_src/parser/printer.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								cclox_src/parser/printer.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
#include "printer.hh"
 | 
			
		||||
#include "expr.hh"
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
 | 
			
		||||
std::string AstPrinter::print(const Expr &expr) {
 | 
			
		||||
  switch (expr.type) {
 | 
			
		||||
    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});
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::GROUPING: {
 | 
			
		||||
      std::shared_ptr<_Grouping> group = std::get<std::shared_ptr<_Grouping>>(expr.value);
 | 
			
		||||
      assert(group != nullptr);
 | 
			
		||||
      return parenthesize("group", {&group->expr});
 | 
			
		||||
    }
 | 
			
		||||
    case ExprType::LITERAL: {
 | 
			
		||||
      std::shared_ptr<_Literal> literal = std::get<std::shared_ptr<_Literal>>(expr.value);
 | 
			
		||||
      assert(literal != nullptr);
 | 
			
		||||
      switch (literal->value.type) {
 | 
			
		||||
        case ObjectType::NIL:
 | 
			
		||||
          return "nil";
 | 
			
		||||
        case ObjectType::IDENTIFIER:
 | 
			
		||||
        case ObjectType::STRING_LIT: {
 | 
			
		||||
          std::string value = std::get<std::string>(literal->value.value);
 | 
			
		||||
          return value;
 | 
			
		||||
        }
 | 
			
		||||
        case ObjectType::NUMBER: {
 | 
			
		||||
          double value = std::get<double>(literal->value.value);
 | 
			
		||||
          return std::to_string(value);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    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});
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string AstPrinter::parenthesize(const std::string &name, std::vector<const Expr *> exprs) {
 | 
			
		||||
  std::stringstream ss{};
 | 
			
		||||
  ss << '(' << name;
 | 
			
		||||
  for (const Expr *expr : exprs) {
 | 
			
		||||
    ss << ' ' << print(*expr);
 | 
			
		||||
  }
 | 
			
		||||
  ss << ')';
 | 
			
		||||
 | 
			
		||||
  return ss.str();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								cclox_src/parser/printer.hh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								cclox_src/parser/printer.hh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
#ifndef PRINTER_HH
 | 
			
		||||
#define PRINTER_HH
 | 
			
		||||
 | 
			
		||||
#include "expr.hh"
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
class AstPrinter {
 | 
			
		||||
public:
 | 
			
		||||
  std::string print(const Expr &expr);
 | 
			
		||||
private:
 | 
			
		||||
  std::string parenthesize(const std::string &name, std::vector<const Expr *> exprs);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user