lily/src/ast.hpp

101 lines
3.3 KiB
C++

#pragma once
#include <string>
#include <memory>
#include "pattern.hpp"
#include "type.hpp"
#include "type_manager.hpp"
#include "compiler.hpp"
#include "binop.hpp"
namespace lily {
class type_env;
struct ast {
type* ast_type = nullptr;
virtual ~ast() = default;
virtual type* check(type_manager& mgr, std::shared_ptr<type_env> env) = 0;
virtual void compile(instruction_manager& mgr, std::vector<instruction*>& into, std::shared_ptr<compile_env> env) = 0;
type* typecheck(type_manager& mgr, std::shared_ptr<type_env> env);
};
typedef std::unique_ptr<ast> ast_ptr;
struct ast_num : ast {
int num;
ast_num(int i) : num(i) {}
~ast_num() = default;
type* check(type_manager& mgr, std::shared_ptr<type_env> env);
void compile(instruction_manager& mgr, std::vector<instruction*>& into, std::shared_ptr<compile_env> env);
};
struct ast_var : ast {
std::string name;
ast_var(std::string n) :
name(std::move(n)) {}
~ast_var() = default;
type* check(type_manager& mgr, std::shared_ptr<type_env> env);
void compile(instruction_manager& mgr, std::vector<instruction*>& into, std::shared_ptr<compile_env> env);
};
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;
type* check(type_manager& mgr, std::shared_ptr<type_env> env);
void compile(instruction_manager& mgr, std::vector<instruction*>& into, std::shared_ptr<compile_env> env);
};
struct ast_op : ast {
binop op;
std::unique_ptr<ast> left;
std::unique_ptr<ast> right;
ast_op(binop o, ast_ptr l, ast_ptr r) :
op(o), left(std::move(l)), right(std::move(r)) {}
~ast_op() = default;
type* check(type_manager& mgr, std::shared_ptr<type_env> env);
void compile(instruction_manager& mgr, std::vector<instruction*>& into, std::shared_ptr<compile_env> env);
};
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;
type* check(type_manager& mgr, std::shared_ptr<type_env> env);
void compile(instruction_manager& mgr, std::vector<instruction*>& into, std::shared_ptr<compile_env> env);
};
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;
type* check(type_manager& mgr, std::shared_ptr<type_env> env);
void compile(instruction_manager& mgr, std::vector<instruction*>& into, std::shared_ptr<compile_env> env);
};
struct ast_case : ast {
struct branch {
pattern_ptr pattern;
ast_ptr expr;
};
type* case_type;
ast_ptr of;
std::vector<branch> branches;
~ast_case() = default;
type* check(type_manager& mgr, std::shared_ptr<type_env> env);
void compile(instruction_manager& mgr, std::vector<instruction*>& into, std::shared_ptr<compile_env> env);
};
}