valeri/src/compiler.cpp

115 lines
3 KiB
C++
Raw Normal View History

#include "compiler.hpp"
2024-08-04 19:38:56 +00:00
struct Context {
Context() {}
Context(Value&& env, Array&& constants)
: env(std::move(env)),
constants(std::move(constants)),
maxreg(0),
maxconst(0) {}
2024-08-09 22:45:06 +00:00
static Result<Context> create() {
auto env = TRY(Nil::create());
auto constants = TRY(Array::create());
2024-08-04 19:38:56 +00:00
return Context(std::move(env), std::move(constants));
}
2024-08-10 17:24:16 +00:00
uint64_t alloc_reg() {
uint64_t reg = maxreg;
++maxreg;
return reg;
}
2024-08-04 19:38:56 +00:00
Value env;
Array constants;
uint64_t maxreg;
uint64_t maxconst;
};
2024-08-10 17:24:16 +00:00
Result<Array> add_opcode(Array& opcodes, Oc opcode, OpArg arg1 = {0, 0},
OpArg arg2 = {0, 0}, OpArg arg3 = {0, 0},
OpArg arg4 = {0, 0}) {
Value oc = Value(TRY(Opcode::create(opcode, arg1, arg2, arg3, arg4)));
return opcodes.append(oc);
}
2024-08-10 10:17:20 +00:00
Result<bool> is_primitive_op(Symbol& sym) {
return TRY(sym.cmp("+")) == 0 || TRY(sym.cmp("-")) == 0 ||
TRY(sym.cmp("*")) == 0 || TRY(sym.cmp("/")) == 0;
2024-08-04 19:38:56 +00:00
return false;
}
2024-08-04 19:38:56 +00:00
Result<Value> Compiler::compile(Value& expr) {
2024-08-09 22:45:06 +00:00
auto context = TRY(Context::create());
2024-08-04 19:38:56 +00:00
TRY(compile_expr(context, expr));
2024-08-10 10:17:20 +00:00
return ERROR(NotImplemented);
2024-08-04 19:38:56 +00:00
}
Result<Expression> Compiler::compile_expr(Context& context, Value& expr) {
switch (expr.tag()) {
case Tag::Pair:
2024-08-04 19:38:56 +00:00
return compile_list(context, *expr.to<Pair>());
2024-08-10 17:24:16 +00:00
case Tag::Int64:
return compile_int64(context, *expr.to<Int64>());
case Tag::Nil:
case Tag::Bool:
case Tag::Float:
case Tag::String:
case Tag::Symbol:
case Tag::Syntax:
case Tag::Array:
case Tag::ByteArray:
case Tag::Dict:
2024-08-10 17:24:16 +00:00
case Tag::Opcode:
2024-08-10 10:17:20 +00:00
return ERROR(TypeMismatch);
}
2024-08-10 10:17:20 +00:00
return ERROR(TypeMismatch);
}
2024-08-10 10:17:20 +00:00
Result<Expression> Compiler::compile_primop(Context& context, Symbol& op,
Pair& expr) {
Value cur = TRY(expr.rest());
Array code = TRY(Array::create());
2024-08-10 17:24:16 +00:00
uint64_t reg = context.alloc_reg();
std::cout << "load-immediate r" << reg << ", " << 0 << "\n";
code = TRY(add_opcode(code, Oc::LoadImmediate, {0, (int64_t)reg}, {0, 0}));
2024-08-10 10:17:20 +00:00
while (!cur.is<Nil>()) {
Pair& pair = *cur.to<Pair>();
auto subexpr = TRY(pair.first());
auto comp = TRY(compile_expr(context, subexpr));
2024-08-10 17:24:16 +00:00
uint64_t res = context.alloc_reg();
std::cout << "add r" << res << ", r" << reg << ", r" << comp.reg << "\n";
reg = res;
2024-08-10 10:17:20 +00:00
cur = TRY(pair.rest());
}
2024-08-10 17:24:16 +00:00
Expression ex = Expression(reg, TRY(Array::create()));
return ex;
2024-08-10 10:17:20 +00:00
}
2024-08-10 17:24:16 +00:00
2024-08-04 19:38:56 +00:00
Result<Expression> Compiler::compile_list(Context& context, Pair& expr) {
2024-08-09 22:45:06 +00:00
auto first = TRY(expr.first());
2024-08-04 19:38:56 +00:00
if (first.is<Symbol>()) {
Symbol& sym = *first.to<Symbol>();
2024-08-10 10:17:20 +00:00
if (TRY(is_primitive_op(sym))) {
return compile_primop(context, sym, expr);
}
2024-08-04 19:38:56 +00:00
}
2024-08-10 10:17:20 +00:00
return ERROR(TypeMismatch);
}
2024-08-10 17:24:16 +00:00
Result<Expression> Compiler::compile_int64(Context& context, Int64& value) {
uint64_t reg = context.alloc_reg();
std::cout << "loadc r" << reg << ", " << value.value() << "\n";
Expression expr = Expression(reg, TRY(Array::create()));
return expr;
}