Make primitive arithmetic operations compile to bytecode

This commit is contained in:
Konstantin Nazarov 2024-08-11 19:25:37 +01:00
parent 8a50f99340
commit d3471ed1af
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
2 changed files with 30 additions and 9 deletions

View file

@ -98,6 +98,19 @@ Result<Expression> Compiler::compile_primop(Context& context, Symbol& op,
Value cur = TRY(expr.rest());
Expression ex = TRY(Expression::create());
Oc opcode = Oc::Unknown;
const char* name = "";
if (TRY(op.cmp("+")) == 0) {
opcode = Oc::Add;
name = "add";
} else if (TRY(op.cmp("*")) == 0) {
opcode = Oc::Mul;
name = "mul";
} else {
return ERROR(NotImplemented);
}
if (cur.is<Nil>()) {
uint64_t reg = context.alloc_reg();
int64_t zero = TRY(context.add_const(TRY(Value::create((int64_t)0))));
@ -113,7 +126,8 @@ Result<Expression> Compiler::compile_primop(Context& context, Symbol& op,
auto comp = TRY(compile_expr(context, subexpr));
ex.add_code(comp.code);
uint64_t reg = comp.reg;
uint64_t firstreg = comp.reg;
uint64_t reg = firstreg;
cur = TRY(pair.rest());
@ -125,15 +139,24 @@ Result<Expression> Compiler::compile_primop(Context& context, Symbol& op,
ex.add_code(comp.code);
uint64_t res = context.alloc_reg();
std::cout << "add r" << res << ", r" << reg << ", r" << comp.reg << "\n";
TRY(ex.add_opcode(Oc::Add, {0, (int64_t)res}, {0, (int64_t)reg},
auto rest = TRY(pair.rest());
uint64_t res = 0;
if (rest.is<Nil>())
res = firstreg;
else
res = context.alloc_reg();
std::cout << name << " r" << res << ", r" << reg << ", r" << comp.reg
<< "\n";
TRY(ex.add_opcode(opcode, {0, (int64_t)res}, {0, (int64_t)reg},
{0, (int64_t)comp.reg}));
reg = res;
cur = TRY(pair.rest());
cur = std::move(rest);
}
context.maxreg = firstreg + 1;
ex.reg = reg;
return std::move(ex);
}

View file

@ -9,13 +9,11 @@
StaticArena<64 * 1024 * 1024> arena;
int main() {
auto s = DIEX(String::create("(+ (+ 1 2 3) 4)"));
auto s = DIEX(String::create("(* (+ 1 2 3) 4)"));
auto reader = Reader(s);
auto r = DIEX(reader.read_one());
auto writer = Writer();
auto s2 = DIEX(writer.write_one(r));
auto s2 = DIEX(write_one(r));
DIEX(arena_gc());