156 lines
4.3 KiB
C++
156 lines
4.3 KiB
C++
#pragma once
|
|
#include <string>
|
|
#include <vector>
|
|
#include "binop.hpp"
|
|
#include "llvm.hpp"
|
|
|
|
namespace lily {
|
|
struct instruction {
|
|
virtual ~instruction() = default;
|
|
virtual std::ostream& to_stream(std::ostream& os) = 0;
|
|
virtual void gen_llvm(llvm_context& ctx) = 0;
|
|
};
|
|
|
|
std::ostream& operator<<(std::ostream& os, instruction& inst);
|
|
|
|
struct instruction_slide : instruction {
|
|
int amount;
|
|
|
|
instruction_slide(int a) : amount(a) {}
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_alloc : instruction {
|
|
int amount;
|
|
|
|
instruction_alloc(int a) : amount(a) {}
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_pop : instruction {
|
|
int amount;
|
|
|
|
instruction_pop(int a) : amount(a) {}
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_unwind : instruction {
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_push_global : instruction {
|
|
std::string name;
|
|
|
|
instruction_push_global(std::string n) : name(std::move(n)) {}
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_push_int : instruction {
|
|
int value;
|
|
|
|
instruction_push_int(int v) : value(v) {}
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_push_str : instruction {
|
|
std::string str;
|
|
|
|
instruction_push_str(std::string s) : str(std::move(s)) {}
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_push : instruction {
|
|
int offset;
|
|
|
|
instruction_push(int o) : offset(o) {}
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_mkapp : instruction {
|
|
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_eval : instruction {
|
|
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_op : instruction {
|
|
binop op;
|
|
|
|
instruction_op(binop o) : op(o) {}
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_eq : instruction {
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_cond : instruction {
|
|
std::vector<instruction*> true_branch;
|
|
std::vector<instruction*> false_branch;
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_update : instruction {
|
|
int offset;
|
|
|
|
instruction_update(int o) : offset(o) {}
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_pack : instruction {
|
|
int constructor;
|
|
int arity;
|
|
|
|
instruction_pack(int c, int a) :
|
|
constructor(c), arity(a) {}
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_split : instruction {
|
|
int arity;
|
|
|
|
instruction_split(int a) : arity(a) {}
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
struct instruction_jump : instruction {
|
|
std::vector<std::vector<instruction*>> instructions;
|
|
std::map<int, int> const_instructions;
|
|
std::ostream& to_stream(std::ostream& os);
|
|
void gen_llvm(llvm_context& ctx);
|
|
};
|
|
|
|
class instruction_manager {
|
|
private:
|
|
std::vector<std::unique_ptr<instruction>> instructions;
|
|
public:
|
|
template <typename T, typename ... Ts>
|
|
T* add_instruction(Ts ... ts) {
|
|
auto new_inst = std::unique_ptr<T>(new T(ts...));
|
|
T* raw = new_inst.get();
|
|
instructions.push_back(std::move(new_inst));
|
|
return raw;
|
|
}
|
|
};
|
|
|
|
}
|