#pragma once #include "common.hpp" struct Context; struct Expression { Expression() {} Expression(Array&& code) : reg(0), code(std::move(code)) {} static Result create() { Array c = TRY(Array::create()); return Expression(std::move(c)); } Result add_opcode(Oc opcode, OpArg arg1 = {0, 0}, OpArg arg2 = {0, 0}, OpArg arg3 = {0, 0}, OpArg arg4 = {0, 0}); Result add_code(Array& c) { code = TRY(code.concat(c)); return Result(); } uint64_t reg; Array code; }; class Compiler { public: Compiler() {} Compiler(String&& fname) : _fname(std::move(fname)) {} static Result create(const String& fname); Result compile(const Value& expr); Result compile_expr(Context& context, const Value& expr); Result compile_list(Context& context, const Value& expr); Result compile_primop(Context& context, Symbol& op, const Value& expr); Result compile_comparison(Context& context, Symbol& op, const Value& expr); Result compile_constant(Context& context, const Value& value); Result compile_symbol(Context& context, const Value& value); Result compile_if(Context& context, Symbol& op, const Value& expr); Result compile_when(Context& context, Symbol& op, const Value& expr); Result compile_and(Context& context, Symbol& op, const Value& expr); Result compile_or(Context& context, Symbol& op, const Value& expr); Result compile_not(Context& context, Symbol& op, const Value& expr); Result compile_def(Context& context, Symbol& op, const Value& expr); Result compile_quote(Context& context, Symbol& op, const Value& expr); Result compile_syntax(Context& context, Symbol& op, const Value& expr); Result compile_fn(Context& context, Symbol& op, const Value& expr); Result compile_let(Context& context, Symbol& op, const Value& expr); Result compile_body(Context& context, const Value& expr); Result compile_function_call(Context& context, const Value& expr); Result syntax_error(const Value& expr, const char* message); private: String _fname; }; Result compile(const String& fname, const Value& expr);