Start implementing the parser
This commit is contained in:
		@@ -1,17 +1,29 @@
 | 
			
		||||
#include "interpreter.hh"
 | 
			
		||||
#include "error_handler.hh"
 | 
			
		||||
#include "parser.hh"
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <sysexits.h>
 | 
			
		||||
 | 
			
		||||
ErrorHandler error_handler{};
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[]) {
 | 
			
		||||
  if (argc > 2) {
 | 
			
		||||
    std::cout << "Usage: cclox [script]\n";
 | 
			
		||||
    exit(EX_USAGE);
 | 
			
		||||
  }
 | 
			
		||||
  (void)argc;
 | 
			
		||||
  (void)argv;
 | 
			
		||||
  // if (argc > 2) {
 | 
			
		||||
  //   std::cout << "Usage: cclox [script]\n";
 | 
			
		||||
  //   exit(EX_USAGE);
 | 
			
		||||
  // }
 | 
			
		||||
  //
 | 
			
		||||
  // run_interpreter(argc, argv);
 | 
			
		||||
 | 
			
		||||
  run_interpreter(argc, argv);
 | 
			
		||||
  Unary left {Token{TokenType::MINUS, "-", Object{}, 1}, Literal{123}};
 | 
			
		||||
  Token op{TokenType::STAR, "*", Object{}, 1};
 | 
			
		||||
  Grouping right{Literal{45.67}};
 | 
			
		||||
 | 
			
		||||
  Binary expr {left, op, right};
 | 
			
		||||
 | 
			
		||||
  AstPrinter printer{};
 | 
			
		||||
  std::cout << printer.print(expr) << '\n';
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								cclox_src/parser.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								cclox_src/parser.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
#ifndef PARSER_CC
 | 
			
		||||
#define PARSER_CC
 | 
			
		||||
 | 
			
		||||
#include "parser/expr.cc"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										6
									
								
								cclox_src/parser.hh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								cclox_src/parser.hh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
#ifndef PARSER_HH
 | 
			
		||||
#define PARSER_HH
 | 
			
		||||
 | 
			
		||||
#include "parser/expr.hh"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										51
									
								
								cclox_src/parser/expr.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								cclox_src/parser/expr.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
#include "expr.hh"
 | 
			
		||||
#include "../tokenizer.hh"
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <type_traits>
 | 
			
		||||
#include <variant>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
 | 
			
		||||
std::string AstPrinter::print(const Expression &expr) {
 | 
			
		||||
  return std::visit([this](auto &&node) -> std::string {
 | 
			
		||||
    using T = std::decay_t<decltype(node)>;
 | 
			
		||||
 | 
			
		||||
    if constexpr(std::is_same_v<T, Binary>) {
 | 
			
		||||
      return parenthesize(node.op.lexeme, {node.left, node.right});
 | 
			
		||||
    } else if constexpr(std::is_same_v<T, Grouping>) {
 | 
			
		||||
      return parenthesize("group", {node.expression});
 | 
			
		||||
    } else if constexpr(std::is_same_v<T, Literal>) {
 | 
			
		||||
      switch (node.value.type) {
 | 
			
		||||
        case ObjectType::NIL:
 | 
			
		||||
          return "nil";
 | 
			
		||||
        case ObjectType::IDENTIFIER:
 | 
			
		||||
        case ObjectType::STRING_LIT: {
 | 
			
		||||
          std::string value = std::get<std::string>(node.value.value);
 | 
			
		||||
          return value;
 | 
			
		||||
        }
 | 
			
		||||
        case ObjectType::NUMBER: {
 | 
			
		||||
          double value = std::get<double>(node.value.value);
 | 
			
		||||
          return std::to_string(value);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } else if constexpr(std::is_same_v<T, Unary>) {
 | 
			
		||||
      return parenthesize(node.op.lexeme, {node.right});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return "";
 | 
			
		||||
  }, expr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string AstPrinter::parenthesize(const std::string &name, std::vector<Expression> exprs) {
 | 
			
		||||
  std::stringstream ss{};
 | 
			
		||||
  ss << '(' << name;
 | 
			
		||||
  for (auto &expr : exprs) {
 | 
			
		||||
    std::string value = std::visit([this](auto &&node) -> std::string {
 | 
			
		||||
      return print(node);
 | 
			
		||||
    }, expr);
 | 
			
		||||
    ss << ' ' << value;
 | 
			
		||||
  }
 | 
			
		||||
  ss << ')';
 | 
			
		||||
 | 
			
		||||
  return ss.str();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								cclox_src/parser/expr.hh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								cclox_src/parser/expr.hh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
#ifndef EXPR_HH
 | 
			
		||||
#define EXPR_HH
 | 
			
		||||
 | 
			
		||||
#include "../tokenizer.hh"
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <variant>
 | 
			
		||||
 | 
			
		||||
struct Expr {};
 | 
			
		||||
 | 
			
		||||
struct Binary : public Expr {
 | 
			
		||||
  Binary(Expr left, Token op, Expr right) : left{left}, op{op}, right{right} {};
 | 
			
		||||
 | 
			
		||||
  Expr left;
 | 
			
		||||
  Token op;
 | 
			
		||||
  Expr right;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Grouping : public Expr {
 | 
			
		||||
  Grouping(Expr expr) : expression{expr} {};
 | 
			
		||||
 | 
			
		||||
  Expr expression;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Literal : public Expr {
 | 
			
		||||
  Literal(Object value) : value{value} {};
 | 
			
		||||
 | 
			
		||||
  Object value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Unary : public Expr {
 | 
			
		||||
  Unary(Token op, Expr right) : op{op}, right{right} {};
 | 
			
		||||
 | 
			
		||||
  Token op;
 | 
			
		||||
  Expr right;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
using Expression = std::variant<Expr, Binary, Grouping, Literal, Unary>;
 | 
			
		||||
 | 
			
		||||
class AstPrinter {
 | 
			
		||||
public:
 | 
			
		||||
  std::string print(const Expression &expr);
 | 
			
		||||
private:
 | 
			
		||||
  std::string parenthesize(const std::string &name, std::vector<Expression> exprs);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user