Compare commits
	
		
			2 Commits
		
	
	
		
			2f0c4be7bf
			...
			ae87a3b4a3
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					ae87a3b4a3 | ||
| 
						 | 
					d4f4b23c64 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +1,3 @@
 | 
				
			|||||||
cclox
 | 
					cclox
 | 
				
			||||||
clox
 | 
					clox
 | 
				
			||||||
 | 
					*.dSYM
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@
 | 
				
			|||||||
#include "error_handler.hh"
 | 
					#include "error_handler.hh"
 | 
				
			||||||
#include "parser.hh"
 | 
					#include "parser.hh"
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
#include <sysexits.h>
 | 
					#include <sysexits.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ErrorHandler error_handler{};
 | 
					ErrorHandler error_handler{};
 | 
				
			||||||
@@ -16,11 +17,15 @@ int main(int argc, char *argv[]) {
 | 
				
			|||||||
  //
 | 
					  //
 | 
				
			||||||
  // run_interpreter(argc, argv);
 | 
					  // run_interpreter(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Unary left {Token{TokenType::MINUS, "-", Object{}, 1}, Literal{123}};
 | 
					  ExprPtr literal = std::make_shared<Expr>(ExprType::LITERAL, Literal{123});
 | 
				
			||||||
  Token op{TokenType::STAR, "*", Object{}, 1};
 | 
					  ExprPtr left = std::make_shared<Expr>(ExprType::UNARY, Unary{Token{TokenType::MINUS, "-", Object{}, 1}, literal});
 | 
				
			||||||
  Grouping right{Literal{45.67}};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Binary expr {left, op, right};
 | 
					  Token op{TokenType::STAR, "*", Object{}, 1};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ExprPtr gliteral = std::make_shared<Expr>(ExprType::LITERAL, Literal{45.67});
 | 
				
			||||||
 | 
					  ExprPtr right = std::make_shared<Expr>(ExprType::GROUPING, gliteral);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Expr expr = {ExprType::BINARY, Binary{left, op, right}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  AstPrinter printer{};
 | 
					  AstPrinter printer{};
 | 
				
			||||||
  std::cout << printer.print(expr) << '\n';
 | 
					  std::cout << printer.print(expr) << '\n';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,20 +1,24 @@
 | 
				
			|||||||
#include "expr.hh"
 | 
					#include "expr.hh"
 | 
				
			||||||
#include "../tokenizer.hh"
 | 
					#include "../tokenizer.hh"
 | 
				
			||||||
 | 
					#include <cassert>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
#include <type_traits>
 | 
					 | 
				
			||||||
#include <variant>
 | 
					 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
#include <sstream>
 | 
					#include <sstream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::string AstPrinter::print(const Expression &expr) {
 | 
					std::string AstPrinter::print(const Expr &expr) {
 | 
				
			||||||
  return std::visit([this](auto &&node) -> std::string {
 | 
					  switch (expr.type) {
 | 
				
			||||||
    using T = std::decay_t<decltype(node)>;
 | 
					    case ExprType::BINARY: {
 | 
				
			||||||
 | 
					      Binary node = std::get<Binary>(expr.value);
 | 
				
			||||||
    if constexpr(std::is_same_v<T, Binary>) {
 | 
					      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});
 | 
				
			||||||
    } else if constexpr(std::is_same_v<T, Grouping>) {
 | 
					    }
 | 
				
			||||||
      return parenthesize("group", {node.expression});
 | 
					    case ExprType::GROUPING: {
 | 
				
			||||||
    } else if constexpr(std::is_same_v<T, Literal>) {
 | 
					      Grouping node = std::get<Grouping>(expr.value);
 | 
				
			||||||
 | 
					      assert(node.expression != NULL);
 | 
				
			||||||
 | 
					      return parenthesize("group", {*node.expression});
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    case ExprType::LITERAL: {
 | 
				
			||||||
 | 
					      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";
 | 
				
			||||||
@@ -28,22 +32,20 @@ std::string AstPrinter::print(const Expression &expr) {
 | 
				
			|||||||
          return std::to_string(value);
 | 
					          return std::to_string(value);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else if constexpr(std::is_same_v<T, Unary>) {
 | 
					    }
 | 
				
			||||||
      return parenthesize(node.op.lexeme, {node.right});
 | 
					    case ExprType::UNARY: {
 | 
				
			||||||
 | 
					      Unary node = std::get<Unary>(expr.value);
 | 
				
			||||||
 | 
					      assert(node.right != NULL);
 | 
				
			||||||
 | 
					      return parenthesize(node.op.lexeme, {*node.right});
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return "";
 | 
					std::string AstPrinter::parenthesize(const std::string &name, std::vector<Expr> exprs) {
 | 
				
			||||||
  }, expr);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
std::string AstPrinter::parenthesize(const std::string &name, std::vector<Expression> exprs) {
 | 
					 | 
				
			||||||
  std::stringstream ss{};
 | 
					  std::stringstream ss{};
 | 
				
			||||||
  ss << '(' << name;
 | 
					  ss << '(' << name;
 | 
				
			||||||
  for (auto &expr : exprs) {
 | 
					  for (auto &expr : exprs) {
 | 
				
			||||||
    std::string value = std::visit([this](auto &&node) -> std::string {
 | 
					    ss << ' ' << print(expr);
 | 
				
			||||||
      return print(node);
 | 
					 | 
				
			||||||
    }, expr);
 | 
					 | 
				
			||||||
    ss << ' ' << value;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  ss << ')';
 | 
					  ss << ')';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,45 +2,61 @@
 | 
				
			|||||||
#define EXPR_HH
 | 
					#define EXPR_HH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../tokenizer.hh"
 | 
					#include "../tokenizer.hh"
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
#include <variant>
 | 
					#include <variant>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Expr {};
 | 
					struct Expr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Binary : public Expr {
 | 
					using ExprPtr = std::shared_ptr<Expr>;
 | 
				
			||||||
  Binary(Expr left, Token op, Expr right) : left{left}, op{op}, right{right} {};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Expr left;
 | 
					struct Binary {
 | 
				
			||||||
 | 
					  Binary(ExprPtr left, Token op, ExprPtr right) : left{left}, op{op}, right{right} {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ExprPtr left;
 | 
				
			||||||
  Token op;
 | 
					  Token op;
 | 
				
			||||||
  Expr right;
 | 
					  ExprPtr right;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Grouping : public Expr {
 | 
					struct Grouping {
 | 
				
			||||||
  Grouping(Expr expr) : expression{expr} {};
 | 
					  Grouping(ExprPtr expr) : expression{expr} {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Expr expression;
 | 
					  ExprPtr expression;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Literal : public Expr {
 | 
					struct Literal {
 | 
				
			||||||
  Literal(Object value) : value{value} {};
 | 
					  Literal(Object value) : value{value} {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Object value;
 | 
					  Object value;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Unary : public Expr {
 | 
					struct Unary {
 | 
				
			||||||
  Unary(Token op, Expr right) : op{op}, right{right} {};
 | 
					  Unary(Token op, ExprPtr right) : op{op}, right{right} {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Token op;
 | 
					  Token op;
 | 
				
			||||||
  Expr right;
 | 
					  ExprPtr right;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using Expression = std::variant<Expr, Binary, Grouping, Literal, Unary>;
 | 
					enum class ExprType {
 | 
				
			||||||
 | 
					  BINARY,
 | 
				
			||||||
 | 
					  GROUPING,
 | 
				
			||||||
 | 
					  LITERAL,
 | 
				
			||||||
 | 
					  UNARY,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using Expression = std::variant<Binary, Grouping, Literal, Unary>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Expr {
 | 
				
			||||||
 | 
					  Expr(ExprType type, Expression value) : type{type}, value{value} {}
 | 
				
			||||||
 | 
					  ExprType type;
 | 
				
			||||||
 | 
					  Expression value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AstPrinter {
 | 
					class AstPrinter {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  std::string print(const Expression &expr);
 | 
					  std::string print(const Expr &expr);
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  std::string parenthesize(const std::string &name, std::vector<Expression> exprs);
 | 
					  std::string parenthesize(const std::string &name, std::vector<Expr> exprs);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user