More ergonomic solution using macros, but still needs improvement
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							@@ -13,7 +13,7 @@ CLOX_OUT  = clox
 | 
				
			|||||||
all: cclox clox
 | 
					all: cclox clox
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cclox: ${CCLOX_SRC}
 | 
					cclox: ${CCLOX_SRC}
 | 
				
			||||||
	${CXX} ${CFLAGS} ${CCLOX_SRC} -o ${CCLOX_OUT}
 | 
						${CXX} -std=c++20 ${CFLAGS} ${CCLOX_SRC} -o ${CCLOX_OUT}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
clox: ${CLOX_SRC}
 | 
					clox: ${CLOX_SRC}
 | 
				
			||||||
	${CC} ${CFLAGS} ${CLOX_SRC} -o ${CLOX_OUT}
 | 
						${CC} ${CFLAGS} ${CLOX_SRC} -o ${CLOX_OUT}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,24 +17,14 @@ int main(int argc, char *argv[]) {
 | 
				
			|||||||
  //
 | 
					  //
 | 
				
			||||||
  // run_interpreter(argc, argv);
 | 
					  // run_interpreter(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ExprPtr left = std::make_shared<Expr>(
 | 
					  Token unary_op{TokenType::MINUS, "-", Object{}, 1};
 | 
				
			||||||
    make_expr(
 | 
					  ExprPtr left = UnaryExprPtr(unary_op, LiteralExprPtr(123));
 | 
				
			||||||
      Unary{
 | 
					 | 
				
			||||||
        Token{TokenType::MINUS, "-", Object{}, 1},
 | 
					 | 
				
			||||||
        std::make_shared<Expr>(make_expr(Literal{123}))
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Token op{TokenType::STAR, "*", Object{}, 1};
 | 
					  Token op{TokenType::STAR, "*", Object{}, 1};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ExprPtr right = std::make_shared<Expr>(
 | 
					  ExprPtr right = GroupingExprPtr(LiteralExprPtr(45.67));
 | 
				
			||||||
    make_expr(
 | 
					 | 
				
			||||||
      Grouping{std::make_shared<Expr>(make_expr(Literal{45.67}))}
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Expr expr = {ExprType::BINARY, Binary{left, op, right}};
 | 
					  Expr expr = BinaryExpr(left, op, right);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  AstPrinter printer{};
 | 
					  AstPrinter printer{};
 | 
				
			||||||
  std::cout << printer.print(expr) << '\n';
 | 
					  std::cout << printer.print(expr) << '\n';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,26 +5,6 @@
 | 
				
			|||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
#include <sstream>
 | 
					#include <sstream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <>
 | 
					 | 
				
			||||||
Expr make_expr<Binary>(Binary value) {
 | 
					 | 
				
			||||||
  return Expr(ExprType::BINARY, value);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template <>
 | 
					 | 
				
			||||||
Expr make_expr<Grouping>(Grouping value) {
 | 
					 | 
				
			||||||
  return Expr(ExprType::GROUPING, value);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template <>
 | 
					 | 
				
			||||||
Expr make_expr<Literal>(Literal value) {
 | 
					 | 
				
			||||||
  return Expr(ExprType::LITERAL, value);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template <>
 | 
					 | 
				
			||||||
Expr make_expr<Unary>(Unary value) {
 | 
					 | 
				
			||||||
  return Expr(ExprType::UNARY, value);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
std::string AstPrinter::print(const Expr &expr) {
 | 
					std::string AstPrinter::print(const Expr &expr) {
 | 
				
			||||||
  switch (expr.type) {
 | 
					  switch (expr.type) {
 | 
				
			||||||
    case ExprType::BINARY: {
 | 
					    case ExprType::BINARY: {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,33 +6,55 @@
 | 
				
			|||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
#include <variant>
 | 
					#include <variant>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BinaryExpr(LEFT, OP, RIGHT) ( \
 | 
				
			||||||
 | 
					      Expr{ \
 | 
				
			||||||
 | 
					        .type = ExprType::BINARY, \
 | 
				
			||||||
 | 
					        .value = Binary{.left = LEFT, .op = OP, .right = RIGHT} \
 | 
				
			||||||
 | 
					      } \
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					#define GroupingExpr(EXPR) ( \
 | 
				
			||||||
 | 
					      Expr{ \
 | 
				
			||||||
 | 
					        .type = ExprType::GROUPING, \
 | 
				
			||||||
 | 
					        .value = Grouping{.expression = EXPR} \
 | 
				
			||||||
 | 
					      } \
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					#define LiteralExpr(VALUE) ( \
 | 
				
			||||||
 | 
					      Expr{ \
 | 
				
			||||||
 | 
					        .type = ExprType::LITERAL, \
 | 
				
			||||||
 | 
					        .value = Literal{.value = VALUE} \
 | 
				
			||||||
 | 
					      } \
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					#define UnaryExpr(OP, RIGHT) ( \
 | 
				
			||||||
 | 
					      Expr{ \
 | 
				
			||||||
 | 
					        .type = ExprType::UNARY, \
 | 
				
			||||||
 | 
					        .value = Unary{.op = OP, .right = RIGHT} \
 | 
				
			||||||
 | 
					      } \
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BinaryExprPtr(LEFT, OP, RIGHT) (std::make_shared<Expr>(BinaryExpr(LEFT, OP, RIGHT)))
 | 
				
			||||||
 | 
					#define GroupingExprPtr(EXPR) (std::make_shared<Expr>(GroupingExpr(EXPR)))
 | 
				
			||||||
 | 
					#define LiteralExprPtr(VALUE) (std::make_shared<Expr>(LiteralExpr(VALUE)))
 | 
				
			||||||
 | 
					#define UnaryExprPtr(OP, RIGHT) (std::make_shared<Expr>(UnaryExpr(OP, RIGHT)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Expr;
 | 
					struct Expr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using ExprPtr = std::shared_ptr<Expr>;
 | 
					using ExprPtr = std::shared_ptr<Expr>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Binary {
 | 
					struct Binary {
 | 
				
			||||||
  Binary(ExprPtr left, Token op, ExprPtr right) : left{left}, op{op}, right{right} {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ExprPtr left;
 | 
					  ExprPtr left;
 | 
				
			||||||
  Token op;
 | 
					  Token op;
 | 
				
			||||||
  ExprPtr right;
 | 
					  ExprPtr right;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Grouping {
 | 
					struct Grouping {
 | 
				
			||||||
  Grouping(ExprPtr expr) : expression{expr} {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ExprPtr expression;
 | 
					  ExprPtr expression;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Literal {
 | 
					struct Literal {
 | 
				
			||||||
  Literal(Object value) : value{value} {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Object value;
 | 
					  Object value;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Unary {
 | 
					struct Unary {
 | 
				
			||||||
  Unary(Token op, ExprPtr right) : op{op}, right{right} {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Token op;
 | 
					  Token op;
 | 
				
			||||||
  ExprPtr right;
 | 
					  ExprPtr right;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -47,14 +69,10 @@ enum class ExprType {
 | 
				
			|||||||
using Expression = std::variant<Binary, Grouping, Literal, Unary>;
 | 
					using Expression = std::variant<Binary, Grouping, Literal, Unary>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Expr {
 | 
					struct Expr {
 | 
				
			||||||
  Expr(ExprType type, Expression value) : type{type}, value{value} {}
 | 
					 | 
				
			||||||
  ExprType type;
 | 
					  ExprType type;
 | 
				
			||||||
  Expression value;
 | 
					  Expression value;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename T>
 | 
					 | 
				
			||||||
Expr make_expr(T value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class AstPrinter {
 | 
					class AstPrinter {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  std::string print(const Expr &expr);
 | 
					  std::string print(const Expr &expr);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user