Skip to content

Commit

Permalink
refactor pt.2... at stmt/block
Browse files Browse the repository at this point in the history
  • Loading branch information
amanuel2 committed Jul 9, 2024
1 parent 9f01e7c commit 93dbf39
Show file tree
Hide file tree
Showing 10 changed files with 418 additions and 315 deletions.
52 changes: 27 additions & 25 deletions include/ast/decl.hh
Original file line number Diff line number Diff line change
Expand Up @@ -22,48 +22,55 @@ namespace rift
{
namespace ast
{
class Decl: public Accept<Tokens>
__DEFAULT_FORWARD_VA(
DeclStmt,
DeclVar,
DeclFunc
);

/// @class Visitor
/// @brief Visitor pattern for expressions
template <typename T>
class DeclVisitor
{
virtual T visit_decl_stmt(const DeclStmt<T>& decl) const;
virtual T visit_decl_var(const DeclVar<T>& decl) const;
virtual T visit_decl_func(const DeclFunc<T>& decl) const;
};

/// @class Decl
/// @brief Declarations acceptor
template <typename T>
class Decl: public Accept
{
public:
virtual Tokens accept(const Visitor &visitor) const = 0;
virtual T accept(const Visitor &visitor) const = 0;
virtual ~Decl() = default;
friend class Visitor;
friend class DeclStmt;
friend class DeclVar;
};

template <typename T>
class DeclStmt: public Decl
{
public:
DeclStmt(std::unique_ptr<Stmt> stmt) : stmt(std::move(stmt)) {};
Tokens accept(const Visitor &visitor) const override { return visitor.visit_decl_stmt(*this); }

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
// must uncomment visit_printer in printer.hh
string accept_printer(const Visitor& visitor) const override { return "unimplemented"; }
#pragma clang diagnostic pop
T accept(const Visitor &visitor) const override { return visitor.visit_decl_stmt(*this); }

std::unique_ptr<Stmt> stmt;
};

template <typename T>
class DeclVar: public Decl
{
public:
DeclVar(const Token &identifier): identifier(identifier), expr(nullptr) {};
DeclVar(const Token &identifier, std::unique_ptr<Expr> expr): identifier(identifier), expr(std::move(expr)) {};
Tokens accept(const Visitor &visitor) const override { return visitor.visit_decl_var(*this); }

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
// must uncomment visit_printer in printer.hh
string accept_printer(const Visitor& visitor) const override { return "unimplemented"; }
#pragma clang diagnostic pop
T accept(const Visitor &visitor) const override { return visitor.visit_decl_var(*this); }

const Token& identifier;
std::unique_ptr<Expr> expr;
};

template <typename T>
class DeclFunc : public Decl
{
public:
Expand All @@ -80,12 +87,7 @@ namespace rift

std::unique_ptr<Func> func;

Tokens accept(const Visitor &visitor) const override { return visitor.visit_decl_func(*this); };
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
// must uncomment visit_printer in printer.hh
string accept_printer(const Visitor& visitor) const override { return "unimplemented"; }
#pragma clang diagnostic pop
T accept(const Visitor &visitor) const override { return visitor.visit_decl_func(*this); };
};
}
}
96 changes: 61 additions & 35 deletions include/ast/expr.hh
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,50 @@ namespace rift
{
namespace ast
{
/// @note forward declrations
__DEFAULT_FORWARD_NONE_VA(

__DEFAULT_FORWARD_VA(
Assign,
Binary,
Grouping,
Literal,
Unary
);

__DEFAULT_FORWARD_VA(
Call,
Ternary,
VarExpr
)

/// @class Visitor
/// @brief Visitor pattern for expressions
template <typename T>
class ExprVisitor
{
public:
/// @example x = 1 + 2;
virtual T visit_assign(const Assign<T>& expr) const;
/// @example 1 + 2
virtual T visit_binary(const Binary<T>& expr) const;
/// @example (1 + 2)
virtual T visit_grouping(const Grouping<T>& expr) const;
/// @example 1
virtual T visit_literal(const Literal<T>& expr) const;
/// @example x
virtual T visit_var_expr(const VarExpr<T>& expr) const;
/// @example -1
virtual T visit_unary(const Unary<T>& expr) const;
/// @example (true) ? 1 : 2
virtual T visit_ternary(const Ternary<T>& expr) const;
/// @example x = foo(1, 2)
virtual T visit_call(const Call<T>& expr) const;
};

/// @class Expr
/// @tparam T: <Token(Eval), string(ASTPrinter)>
/// @brief Base class for all expressions
/// Acceptor in the visitor pattern usefull for accepting Expr/Stmt/Decl
/// to be evaluated via the visitor
/// @details Types of expression include
/// - Binary: An expression with two operands and an operator
/// - Example: 1 + 2
Expand All @@ -48,126 +82,118 @@ namespace rift
/// - Example: 1
/// - Unary: An expression with a single operator and a single operand
/// - Example: -1
class Expr : public Accept<Token>
template <typename T>
class Expr
{
public:
virtual Token accept(const Visitor& visitor) const override = 0;
virtual string accept_printer(const Visitor& visitor) const override = 0;
virtual T accept(const ExprVisitor& visitor) const = 0;
virtual ~Expr() = default;
};


#pragma mark - Concrete Expressions

using Exprs = std::unordered_map<std::string, std::unique_ptr<Expr>>;
template <typename T>
class Call : public Expr
{
public:
using Exprs = std::unordered_map<std::string, std::unique_ptr<Expr<T>>>;
Call(Token name, Exprs&& args): name(name), args(std::move(args)) {};

Token name; // expr -> Literal::Identifier
Exprs args;

inline Token accept(const Visitor& visitor) const override { return visitor.visit_call(*this); }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
inline string accept_printer(const Visitor& visitor) const override { return "unimplemented"; }
#pragma clang diagnostic pop
inline T accept(const ExprVisitor& visitor) const override { return visitor.visit_call(*this); }
};

template <typename T>
class Ternary : public Expr
{
public:
Ternary(std::unique_ptr<Expr> condition, std::unique_ptr<Expr> left, std::unique_ptr<Expr> right): condition(std::move(condition)), left(std::move(left)), right(std::move(right)) {};
Ternary(std::unique_ptr<Expr<Token>> condition, std::unique_ptr<Expr<Token>> left, std::unique_ptr<Expr<Token>> right): condition(std::move(condition)), left(std::move(left)), right(std::move(right)) {};
std::unique_ptr<Expr> condition;
std::unique_ptr<Expr> left;
std::unique_ptr<Expr> right;

inline Token accept(const Visitor& visitor) const override { return visitor.visit_ternary(*this); }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
inline string accept_printer(const Visitor& visitor) const override { return "unimplemented"; }
#pragma clang diagnostic pop
inline T accept(const ExprVisitor& visitor) const override { return visitor.visit_ternary(*this); }
};

template <typename T>
class Assign : public Expr
{
public:
Assign(Token name, std::unique_ptr<Expr> value): name(name), value(std::move(value)) {};
Assign(Token name, std::unique_ptr<Expr<Token>> value): name(name), value(std::move(value)) {};
Token name;
std::unique_ptr<Expr> value;

inline Token accept(const Visitor& visitor) const override { return visitor.visit_assign(*this); }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
inline string accept_printer(const Visitor& visitor) const override { return "unimplemented"; }
#pragma clang diagnostic pop
inline T accept(const ExprVisitor& visitor) const override { return visitor.visit_assign(*this); }
};

/// @class Binary
/// @param left The left operand
/// @param op The operator
/// @param right The right operand
// template <typename T = Token, typename V = Token>
template <typename T>
class Binary : public Expr
{
public:
Binary(std::unique_ptr<Expr> left, Token op, std::unique_ptr<Expr> right): op(op), left(std::move(left)), right(std::move(right)) {};
Binary(std::unique_ptr<Expr<Token>> left, Token op, std::unique_ptr<Expr<Token>> right): op(op), left(std::move(left)), right(std::move(right)) {};
Token op;
std::unique_ptr<Expr> left;
std::unique_ptr<Expr> right;

inline Token accept(const Visitor& visitor) const override { return visitor.visit_binary(*this); }
inline string accept_printer(const Visitor& visitor) const override { return visitor.print_binary(*this); }
inline T accept(const ExprVisitor& visitor) const override { return visitor.visit_binary(*this); }
};

/// @class Grouping
/// @param expr The subexpression
template <typename T>
class Grouping : public Expr
{
public:
Grouping(std::unique_ptr<Expr> expr): expr(std::move(expr)) {};
std::unique_ptr<Expr> expr;

inline Token accept(const Visitor& visitor) const override {return visitor.visit_grouping(*this);}
inline string accept_printer(const Visitor& visitor) const override {return visitor.print_grouping(*this);}
inline T accept(const ExprVisitor& visitor) const override {return visitor.visit_grouping(*this);}
};

/// @class Unary
/// @param op The operator
/// @param expr The operand
template <typename T>
class Unary : public Expr
{
public:
Unary(Token op, std::unique_ptr<Expr> expr): op(op), expr(std::move(expr)) {};
Unary(Token op, std::unique_ptr<Expr<T>> expr): op(op), expr(std::move(expr)) {};
Token op;
std::unique_ptr<Expr> expr;

inline Token accept(const Visitor& visitor) const override {return visitor.visit_unary(*this);}
inline string accept_printer(const Visitor& visitor) const override {return visitor.print_unary(*this);}
inline T accept(const ExprVisitor& visitor) const override {return visitor.visit_unary(*this);}
};

/// @class VarExpr
/// @param value The value of the variable
template <typename T>
class VarExpr: public Expr
{
public:
VarExpr(Token value): value(value) {};
Token value;

inline Token accept(const Visitor &visitor) const override {return visitor.visit_var_expr(*this);}
inline string accept_printer(const Visitor& visitor) const override {return visitor.print_var_expr(*this);}
inline T accept(const ExprVisitor &visitor) const override {return visitor.visit_var_expr(*this);}
};

/// @class Literal
/// @param value The value of the literal
template <typename T>
class Literal: public Expr
{
public:
Literal(Token value): value(value) {};
Token value;

inline Token accept(const Visitor &visitor) const override {return visitor.visit_literal(*this);}
inline string accept_printer(const Visitor& visitor) const override {return visitor.print_literal(*this);}
inline T accept(const ExprVisitor &visitor) const override {return visitor.visit_literal(*this);}
};
}
};
34 changes: 0 additions & 34 deletions include/ast/grmr.hh
Original file line number Diff line number Diff line change
Expand Up @@ -126,49 +126,15 @@ namespace rift
{
public:
/* Evaluator */
/* expr */
virtual Token visit_assign(const Assign& expr) const;
virtual Token visit_binary(const Binary& expr) const;
virtual Token visit_grouping(const Grouping& expr) const;
virtual Token visit_literal(const Literal& expr) const;
virtual Token visit_var_expr(const VarExpr& expr) const;
virtual Token visit_unary(const Unary& expr) const;
virtual Token visit_ternary(const Ternary& expr) const;
virtual Token visit_call(const Call& expr) const;

/* stmt */
/// @note TokenType::IGNORE is used to ignore statements returning void
virtual Token visit_expr_stmt(const StmtExpr& stmt) const;
virtual Token visit_print_stmt(const StmtPrint& stmt) const;
virtual Token visit_if_stmt(const StmtIf& stmt) const;
virtual Token visit_return_stmt(const StmtReturn& stmt) const;
virtual Token visit_block_stmt(const Block& block) const;
virtual Token visit_for_stmt(const For& decl) const;

/* decl */
virtual Tokens visit_decl_stmt(const DeclStmt& decl) const;
virtual Tokens visit_decl_var(const DeclVar& decl) const;
virtual Tokens visit_decl_func(const DeclFunc& decl) const;

/* prgm */
virtual Tokens visit_program(const Program& prgm) const;


/* Printer */
/* expr */
virtual string print_binary(const Binary& expr) const;
virtual string print_grouping(const Grouping& expr) const;
virtual string print_unary(const Unary& expr) const;
virtual string print_literal(const Literal& expr) const;
virtual string print_var_expr(const VarExpr& expr) const;

/* stmt */
// virtual void print_expr_stmt(const StmtExpr& expr) const;
// virtual void print_print_stmt(const StmtPrint& expr) const;
// virtual void print_var_stmt(const StmtVar& expr) const;

/* virtual void print_program(const Program& prgm) const; */

/* Resolver */
/* expr */
virtual Token resolve_assign(const ResolverAssign& expr) const;
Expand Down
Loading

0 comments on commit 93dbf39

Please sign in to comment.