#pragma once #include #include #include "pattern.hpp" namespace lily { struct ast { virtual ~ast() = default; }; typedef std::unique_ptr ast_ptr; struct ast_num : ast { int num; ast_num(int i) : num(i) {} ~ast_num() = default; }; struct ast_var : ast { std::string name; ast_var(std::string n) : name(std::move(n)) {} ~ast_var() = default; }; struct ast_app : ast { ast_ptr left; ast_ptr right; ast_app(ast_ptr l, ast_ptr r) : left(std::move(l)), right(std::move(r)) {} ~ast_app() = default; }; struct ast_op : ast { enum class op { add, subtract, times, divide } op; std::unique_ptr left; std::unique_ptr right; ast_op(enum op o, ast_ptr l, ast_ptr r) : op(o), left(std::move(l)), right(std::move(r)) {} ~ast_op() = default; }; struct ast_let : ast { std::string name; ast_ptr expr; ast_ptr in; ast_let(std::string n, ast_ptr e, ast_ptr i) : name(std::move(n)), expr(std::move(e)), in(std::move(i)) {} ~ast_let() = default; }; struct ast_letrec : ast_let { ast_letrec(std::string n, ast_ptr e, ast_ptr i) : ast_let(std::move(n), std::move(e), std::move(i)) {} ~ast_letrec() = default; }; struct ast_case : ast { struct branch { pattern_ptr pattern; ast_ptr expr; }; ast_ptr of; std::vector branches; ~ast_case() = default; }; }