Enable execution of primitive arithmetic bytecode
This commit is contained in:
parent
040eb540b1
commit
3a117c9b1f
10 changed files with 247 additions and 67 deletions
101
src/common.cpp
101
src/common.cpp
|
@ -84,39 +84,60 @@ Result<Value> syntax_unwrap(Value& val) {
|
|||
return syntax->get_value();
|
||||
}
|
||||
|
||||
Result<Value> Nil::copy() const { return Value(Nil()); }
|
||||
Result<Value> Nil::copy_value() const { return Value(Nil()); }
|
||||
|
||||
Result<Value> Int64::copy() const { return Value(Int64(TRY(_value.copy()))); }
|
||||
Result<Value> Float::copy() const { return Value(Float(TRY(_value.copy()))); }
|
||||
Result<Value> Int64::copy_value() const {
|
||||
return Value(Int64(TRY(_value.copy())));
|
||||
}
|
||||
Result<Value> Float::copy_value() const {
|
||||
return Value(Float(TRY(_value.copy())));
|
||||
}
|
||||
|
||||
Result<Value> Array::copy() const { return Value(Array(TRY(_value.copy()))); }
|
||||
Result<Value> Array::copy_value() const {
|
||||
return Value(Array(TRY(_value.copy())));
|
||||
}
|
||||
Result<Array> Array::copy() const { return Array(TRY(_value.copy())); }
|
||||
|
||||
Result<Value> ByteArray::copy() const {
|
||||
Result<Value> ByteArray::copy_value() const {
|
||||
return Value(ByteArray(TRY(_value.copy())));
|
||||
}
|
||||
|
||||
Result<Value> Dict::copy() const { return Value(Dict(TRY(_value.copy()))); }
|
||||
Result<Value> Dict::copy_value() const {
|
||||
return Value(Dict(TRY(_value.copy())));
|
||||
}
|
||||
|
||||
Result<Value> String::copy() const { return Value(String(TRY(_value.copy()))); }
|
||||
Result<Value> String::copy_value() const {
|
||||
return Value(String(TRY(_value.copy())));
|
||||
}
|
||||
|
||||
Result<Value> Symbol::copy() const { return Value(Symbol(TRY(_value.copy()))); }
|
||||
Result<Value> Symbol::copy_value() const {
|
||||
return Value(Symbol(TRY(_value.copy())));
|
||||
}
|
||||
|
||||
Result<Value> Syntax::copy() const { return Value(Syntax(TRY(_value.copy()))); }
|
||||
Result<Value> Syntax::copy_value() const {
|
||||
return Value(Syntax(TRY(_value.copy())));
|
||||
}
|
||||
|
||||
Result<Value> Pair::copy() const { return Value(Pair(TRY(_value.copy()))); }
|
||||
Result<Value> Pair::copy_value() const {
|
||||
return Value(Pair(TRY(_value.copy())));
|
||||
}
|
||||
|
||||
Result<Value> Bool::copy() const { return Value(Bool(TRY(_value.copy()))); }
|
||||
Result<Value> Bool::copy_value() const {
|
||||
return Value(Bool(TRY(_value.copy())));
|
||||
}
|
||||
|
||||
Result<Value> Opcode::copy() const { return Value(Opcode(TRY(_value.copy()))); }
|
||||
Result<Value> Opcode::copy_value() const {
|
||||
return Value(Opcode(TRY(_value.copy())));
|
||||
}
|
||||
|
||||
Result<Value> Function::copy() const {
|
||||
Result<Value> Function::copy_value() const {
|
||||
return Value(Function(TRY(_value.copy())));
|
||||
}
|
||||
Result<Function> Function::copy_function() const {
|
||||
return Function(TRY(_value.copy()));
|
||||
}
|
||||
Result<Function> Function::copy() const { return Function(TRY(_value.copy())); }
|
||||
|
||||
Result<Value> Stack::copy() const { return Value(Stack(TRY(_value.copy()))); }
|
||||
Result<Value> Stack::copy_value() const {
|
||||
return Value(Stack(TRY(_value.copy())));
|
||||
}
|
||||
|
||||
Result<Value> Stack::get(uint64_t idx) const {
|
||||
if (idx >= _value->top) return ERROR(KeyError);
|
||||
|
@ -163,7 +184,7 @@ Result<Value> Pair::rest() {
|
|||
}
|
||||
|
||||
Result<Function> Function::create(const Value& name, uint64_t arity,
|
||||
const Value& constants, const Value& code) {
|
||||
const Array& constants, const Array& code) {
|
||||
auto pod = TRY(arena_alloc<PodFunction>());
|
||||
pod->header.tag = Tag::Function;
|
||||
pod->arity = arity;
|
||||
|
@ -178,12 +199,12 @@ Result<Value> Function::name() const {
|
|||
return Value::create(_value->name.get());
|
||||
}
|
||||
|
||||
Result<Value> Function::code() const {
|
||||
return Value::create(_value->code.get());
|
||||
Result<Array> Function::code() const {
|
||||
return Array::create((PodArray*)_value->code.get());
|
||||
}
|
||||
|
||||
Result<Value> Function::constants() const {
|
||||
return Value::create(_value->constants.get());
|
||||
Result<Array> Function::constants() const {
|
||||
return Array::create((PodArray*)_value->constants.get());
|
||||
}
|
||||
|
||||
Result<Value> reverse(Value& val) {
|
||||
|
@ -316,11 +337,45 @@ Result<uint64_t> Dict::find(const Value& key) const {
|
|||
return left;
|
||||
}
|
||||
|
||||
Result<Value> Object::add(const Object&) const { return ERROR(NotImplemented); }
|
||||
Result<Value> Object::add(const Int64&) const { return ERROR(NotImplemented); }
|
||||
|
||||
Result<Value> Object::sub(const Object&) const { return ERROR(NotImplemented); }
|
||||
Result<Value> Object::sub_inv(const Int64&) const {
|
||||
return ERROR(NotImplemented);
|
||||
}
|
||||
|
||||
Result<Value> Object::mul(const Object&) const { return ERROR(NotImplemented); }
|
||||
Result<Value> Object::mul(const Int64&) const { return ERROR(NotImplemented); }
|
||||
|
||||
Result<Value> Object::div(const Object&) const { return ERROR(NotImplemented); }
|
||||
Result<Value> Object::div_inv(const Int64&) const {
|
||||
return ERROR(NotImplemented);
|
||||
}
|
||||
Result<Value> Int64::add(const Object& rhs) const { return rhs.add(*this); }
|
||||
Result<Value> Int64::add(const Int64& rhs) const {
|
||||
return Value(TRY(Int64::create(value() + rhs.value())));
|
||||
}
|
||||
|
||||
Result<Value> Int64::mul(const Object& rhs) const { return rhs.mul(*this); }
|
||||
Result<Value> Int64::mul(const Int64& rhs) const {
|
||||
return Value(TRY(Int64::create(value() * rhs.value())));
|
||||
}
|
||||
|
||||
Result<Value> Int64::sub(const Object& rhs) const { return rhs.sub_inv(*this); }
|
||||
Result<Value> Int64::sub_inv(const Int64& rhs) const {
|
||||
return Value(TRY(Int64::create(rhs.value() - value())));
|
||||
}
|
||||
|
||||
Result<Value> Int64::div(const Object& rhs) const { return rhs.div_inv(*this); }
|
||||
Result<Value> Int64::div_inv(const Int64& rhs) const {
|
||||
return Value(TRY(Int64::create(rhs.value() / value())));
|
||||
}
|
||||
|
||||
Result<short> Int64::cmp(const Float& rhs) const {
|
||||
return (_value->value > rhs._value->value) -
|
||||
(_value->value < rhs._value->value);
|
||||
}
|
||||
|
||||
Result<short> Float::cmp(const Int64& rhs) const {
|
||||
return (_value->value > rhs._value->value) -
|
||||
(_value->value < rhs._value->value);
|
||||
|
|
111
src/common.hpp
111
src/common.hpp
|
@ -26,13 +26,15 @@ class Pair;
|
|||
class Array;
|
||||
class ByteArray;
|
||||
class Writer;
|
||||
class Opcode;
|
||||
class Stack;
|
||||
|
||||
short cmp_tag(Tag lhs, Tag rhs);
|
||||
|
||||
class Object {
|
||||
public:
|
||||
virtual Tag tag() const = 0;
|
||||
virtual Result<Value> copy() const = 0;
|
||||
virtual Result<Value> copy_value() const = 0;
|
||||
virtual PodObject* pod() const = 0;
|
||||
virtual void move(Object*) = 0;
|
||||
virtual ~Object() = default;
|
||||
|
@ -68,6 +70,28 @@ class Object {
|
|||
virtual Result<short> cmp(const ByteArray&) const {
|
||||
return cmp_tag(tag(), Tag::ByteArray);
|
||||
}
|
||||
virtual Result<short> cmp(const Opcode& rhs) const {
|
||||
return cmp_tag(tag(), Tag::Opcode);
|
||||
}
|
||||
virtual Result<short> cmp(const char* rhs) const {
|
||||
return ERROR(NotImplemented);
|
||||
}
|
||||
virtual Result<short> cmp(const Stack& rhs) const {
|
||||
return ERROR(NotImplemented);
|
||||
}
|
||||
|
||||
virtual Result<Value> add(const Object&) const;
|
||||
virtual Result<Value> add(const Int64&) const;
|
||||
|
||||
virtual Result<Value> sub(const Object&) const;
|
||||
virtual Result<Value> sub_inv(const Int64&) const;
|
||||
|
||||
virtual Result<Value> mul(const Object&) const;
|
||||
virtual Result<Value> mul(const Int64&) const;
|
||||
|
||||
virtual Result<Value> div(const Object&) const;
|
||||
virtual Result<Value> div_inv(const Int64&) const;
|
||||
|
||||
virtual Result<Value> get(const Value& key) const;
|
||||
|
||||
Object() = default;
|
||||
|
@ -97,7 +121,8 @@ class Nil : public Object {
|
|||
return Nil(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Nil> copy() const;
|
||||
|
||||
virtual void move(Object* obj) final { new (obj) Nil(std::move(_value)); }
|
||||
|
||||
|
@ -139,7 +164,8 @@ class Array : public Object {
|
|||
}
|
||||
|
||||
uint64_t size() const { return _value->size; }
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Array> copy() const;
|
||||
|
||||
Result<Value> get(uint64_t idx) const;
|
||||
virtual Result<Value> get(const Value& key) const final;
|
||||
|
@ -165,7 +191,7 @@ class Array : public Object {
|
|||
return Array(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
Result<Array> sub(uint64_t start, uint64_t end) {
|
||||
Result<Array> slice(uint64_t start, uint64_t end) {
|
||||
if (start > end) return ERROR(IndexOutOfRange);
|
||||
uint64_t res_size = end - start;
|
||||
auto pod = TRY(arena_alloc<PodArray>(res_size * sizeof(PodObject*)));
|
||||
|
@ -230,7 +256,8 @@ class ByteArray : public Object {
|
|||
static Result<ByteArray> create(const String& str);
|
||||
|
||||
uint64_t size() const { return _value->size; }
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<ByteArray> copy() const;
|
||||
|
||||
Result<char> operator[](uint64_t idx) const {
|
||||
if (idx >= _value->size) return ERROR(IndexOutOfRange);
|
||||
|
@ -275,7 +302,7 @@ class ByteArray : public Object {
|
|||
return ByteArray(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
Result<ByteArray> sub(uint64_t start, uint64_t end) {
|
||||
Result<ByteArray> slice(uint64_t start, uint64_t end) {
|
||||
if (start > end) return ERROR(IndexOutOfRange);
|
||||
uint64_t res_size = end - start;
|
||||
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
|
||||
|
@ -321,7 +348,8 @@ class Dict : public Object {
|
|||
return Dict(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Dict> copy() const;
|
||||
|
||||
virtual Result<Value> get(const Value& key) const final;
|
||||
|
||||
|
@ -419,7 +447,8 @@ class String : public Object {
|
|||
}
|
||||
|
||||
uint64_t size() const { return _value->size; }
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<String> copy() const;
|
||||
|
||||
Result<char32_t> operator[](uint64_t idx) const {
|
||||
if (idx >= _value->size) return ERROR(IndexOutOfRange);
|
||||
|
@ -467,7 +496,7 @@ class String : public Object {
|
|||
return String(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
Result<String> sub(uint64_t start, uint64_t end) {
|
||||
Result<String> slice(uint64_t start, uint64_t end) {
|
||||
if (start > end) return ERROR(IndexOutOfRange);
|
||||
uint64_t res_size = end - start;
|
||||
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
|
||||
|
@ -561,7 +590,8 @@ class Symbol : public Object {
|
|||
}
|
||||
|
||||
static Result<Symbol> create(String& rhs);
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Symbol> copy() const;
|
||||
|
||||
uint64_t size() const { return _value->size; }
|
||||
|
||||
|
@ -595,7 +625,8 @@ class Syntax : public Object {
|
|||
|
||||
Result<Value> get_value();
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Syntax> copy() const;
|
||||
|
||||
private:
|
||||
GcRoot<PodSyntax> _value;
|
||||
|
@ -621,7 +652,8 @@ class Pair : public Object {
|
|||
Result<Value> first();
|
||||
Result<Value> rest();
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Pair> copy() const;
|
||||
|
||||
private:
|
||||
GcRoot<PodPair> _value;
|
||||
|
@ -645,6 +677,18 @@ class Int64 : public Object {
|
|||
}
|
||||
virtual Result<short> cmp(const Float& rhs) const final;
|
||||
|
||||
virtual Result<Value> add(const Object& rhs) const final;
|
||||
virtual Result<Value> add(const Int64& rhs) const final;
|
||||
|
||||
virtual Result<Value> mul(const Object& rhs) const final;
|
||||
virtual Result<Value> mul(const Int64& rhs) const final;
|
||||
|
||||
virtual Result<Value> sub(const Object& rhs) const final;
|
||||
virtual Result<Value> sub_inv(const Int64& rhs) const final;
|
||||
|
||||
virtual Result<Value> div(const Object& rhs) const final;
|
||||
virtual Result<Value> div_inv(const Int64& rhs) const final;
|
||||
|
||||
virtual void move(Object* obj) final { new (obj) Int64(std::move(_value)); }
|
||||
|
||||
static Result<Int64> create(PodInt64* obj) {
|
||||
|
@ -661,7 +705,8 @@ class Int64 : public Object {
|
|||
|
||||
int64_t value() const { return _value->value; }
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Int64> copy() const;
|
||||
|
||||
private:
|
||||
GcRoot<PodInt64> _value;
|
||||
|
@ -701,7 +746,8 @@ class Float : public Object {
|
|||
|
||||
double value() const { return _value->value; }
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Float> copy() const;
|
||||
|
||||
private:
|
||||
GcRoot<PodFloat> _value;
|
||||
|
@ -734,7 +780,8 @@ class Bool : public Object {
|
|||
|
||||
bool value() const { return _value->value; }
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Bool> copy() const;
|
||||
|
||||
private:
|
||||
GcRoot<PodBool> _value;
|
||||
|
@ -779,7 +826,8 @@ class Opcode : public Object {
|
|||
OpArg arg3() const { return _value->arg3; }
|
||||
OpArg arg4() const { return _value->arg4; }
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Opcode> copy() const;
|
||||
|
||||
private:
|
||||
GcRoot<PodOpcode> _value;
|
||||
|
@ -812,16 +860,16 @@ class Function : public Object {
|
|||
}
|
||||
|
||||
static Result<Function> create(const Value& name, uint64_t arity,
|
||||
const Value& constants, const Value& code);
|
||||
const Array& constants, const Array& code);
|
||||
|
||||
uint64_t arity() { return _value->arity; }
|
||||
|
||||
Result<Value> name() const;
|
||||
Result<Value> code() const;
|
||||
Result<Value> constants() const;
|
||||
Result<Array> code() const;
|
||||
Result<Array> constants() const;
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Function> copy_function() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Function> copy() const;
|
||||
|
||||
private:
|
||||
GcRoot<PodFunction> _value;
|
||||
|
@ -864,7 +912,8 @@ class Stack : public Object {
|
|||
return Stack(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Stack> copy() const;
|
||||
|
||||
private:
|
||||
GcRoot<PodStack> _value;
|
||||
|
@ -925,6 +974,22 @@ class Value {
|
|||
return ((Object*)buf)->cmp(*(Object*)rhs.buf);
|
||||
}
|
||||
|
||||
Result<Value> add(const Value& rhs) const {
|
||||
return ((Object*)buf)->add(*(Object*)rhs.buf);
|
||||
}
|
||||
|
||||
Result<Value> mul(const Value& rhs) const {
|
||||
return ((Object*)buf)->mul(*(Object*)rhs.buf);
|
||||
}
|
||||
|
||||
Result<Value> sub(const Value& rhs) const {
|
||||
return ((Object*)buf)->sub(*(Object*)rhs.buf);
|
||||
}
|
||||
|
||||
Result<Value> div(const Value& rhs) const {
|
||||
return ((Object*)buf)->div(*(Object*)rhs.buf);
|
||||
}
|
||||
|
||||
Result<Value> get(Value& key) { return ((Object*)buf)->get(key); }
|
||||
Result<Value> get(int64_t key) {
|
||||
Value k = TRY(Int64::create(key));
|
||||
|
@ -935,7 +1000,7 @@ class Value {
|
|||
// Result<bool> operator==(Value& rhs) { return TRY(cmp(rhs)) == 0; }
|
||||
// Result<bool> operator!=(Value& rhs) { return TRY(cmp(rhs)) != 0; }
|
||||
|
||||
Result<Value> copy() const { return ((Object*)buf)->copy(); }
|
||||
Result<Value> copy() const { return ((Object*)buf)->copy_value(); }
|
||||
|
||||
private:
|
||||
uint8_t buf[24];
|
||||
|
|
|
@ -67,12 +67,10 @@ Result<Value> Compiler::compile(Value& expr) {
|
|||
TRY(ex.add_opcode(Oc::Ret, {0, (int64_t)ex.reg}));
|
||||
|
||||
Value name = TRY(Nil::create());
|
||||
Value constants = TRY(context.constants.copy());
|
||||
Value code = TRY(ex.code.copy());
|
||||
// TRY(debug_print(constants));
|
||||
// TRY(debug_print(code));
|
||||
// TRY(debug_print(context.constants));
|
||||
// TRY(debug_print(ex.code));
|
||||
|
||||
auto fun = TRY(Function::create(name, 0, constants, code));
|
||||
auto fun = TRY(Function::create(name, 0, context.constants, ex.code));
|
||||
return Value(std::move(fun));
|
||||
}
|
||||
|
||||
|
@ -110,6 +108,10 @@ Result<Expression> Compiler::compile_primop(Context& context, Symbol& op,
|
|||
opcode = Oc::Add;
|
||||
} else if (TRY(op.cmp("*")) == 0) {
|
||||
opcode = Oc::Mul;
|
||||
} else if (TRY(op.cmp("-")) == 0) {
|
||||
opcode = Oc::Sub;
|
||||
} else if (TRY(op.cmp("/")) == 0) {
|
||||
opcode = Oc::Div;
|
||||
} else {
|
||||
return ERROR(NotImplemented);
|
||||
}
|
||||
|
@ -177,7 +179,7 @@ Result<Expression> Compiler::compile_int64(Context& context, Int64& value) {
|
|||
Expression ex = TRY(Expression::create());
|
||||
uint64_t reg = context.alloc_reg();
|
||||
|
||||
int64_t c = TRY(context.add_const(TRY(value.copy())));
|
||||
int64_t c = TRY(context.add_const(TRY(value.copy_value())));
|
||||
|
||||
TRY(ex.add_opcode(Oc::Mov, {0, (int64_t)reg}, {1, (int64_t)c}));
|
||||
|
||||
|
|
|
@ -296,7 +296,7 @@ Result<Value> Reader::read_symbol() {
|
|||
|
||||
size_t end = position_.offset;
|
||||
|
||||
String str = TRY(_str.sub(start, end));
|
||||
String str = TRY(_str.slice(start, end));
|
||||
|
||||
if (!is_separator(get()) && !is_eof()) return ERROR(ReadError);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
StaticArena<64 * 1024 * 1024> arena;
|
||||
|
||||
Result<void> run() {
|
||||
auto code_str = TRY(String::create("(* (+ 1 2 3) 4)"));
|
||||
auto code_str = TRY(String::create("(* (+ 1 2 3) (/ 4 2))"));
|
||||
auto reader = Reader(code_str);
|
||||
|
||||
auto parsed = TRY(reader.read_one());
|
||||
|
@ -30,6 +30,8 @@ Result<void> run() {
|
|||
|
||||
auto res = TRY(vm.run(fun));
|
||||
|
||||
TRY(debug_print(res));
|
||||
|
||||
return Result<void>();
|
||||
}
|
||||
|
||||
|
|
71
src/vm.cpp
71
src/vm.cpp
|
@ -7,7 +7,7 @@ Result<void> VM::setreg(uint64_t idx, const Value& value) {
|
|||
return Result<void>();
|
||||
}
|
||||
|
||||
Result<Value> VM::getconst(uint64_t idx) { return ERROR(NotImplemented); }
|
||||
Result<Value> VM::getconst(uint64_t idx) { return _constants.get(idx); }
|
||||
|
||||
Result<Value> VM::get(bool is_const, uint64_t idx) {
|
||||
if (is_const) return getconst(idx);
|
||||
|
@ -16,22 +16,71 @@ Result<Value> VM::get(bool is_const, uint64_t idx) {
|
|||
|
||||
Result<void> VM::vm_mov(Opcode& oc) {
|
||||
uint64_t acc = (uint64_t)oc.arg1().arg;
|
||||
setreg(acc, TRY(Nil::create()));
|
||||
return ERROR(NotImplemented);
|
||||
Value val = TRY(get(oc.arg2().is_const, (uint64_t)oc.arg2().arg));
|
||||
setreg(acc, val);
|
||||
return Result<void>();
|
||||
}
|
||||
|
||||
Result<void> VM::vm_add(Opcode& oc) {
|
||||
uint64_t acc = (uint64_t)oc.arg1().arg;
|
||||
Value val1 = TRY(get(oc.arg2().is_const, (uint64_t)oc.arg2().arg));
|
||||
Value val2 = TRY(get(oc.arg3().is_const, (uint64_t)oc.arg3().arg));
|
||||
Value res = TRY(val1.add(val2));
|
||||
setreg(acc, res);
|
||||
return Result<void>();
|
||||
}
|
||||
|
||||
Result<void> VM::vm_mul(Opcode& oc) {
|
||||
uint64_t acc = (uint64_t)oc.arg1().arg;
|
||||
Value val1 = TRY(get(oc.arg2().is_const, (uint64_t)oc.arg2().arg));
|
||||
Value val2 = TRY(get(oc.arg3().is_const, (uint64_t)oc.arg3().arg));
|
||||
Value res = TRY(val1.mul(val2));
|
||||
setreg(acc, res);
|
||||
return Result<void>();
|
||||
}
|
||||
|
||||
Result<void> VM::vm_sub(Opcode& oc) {
|
||||
uint64_t acc = (uint64_t)oc.arg1().arg;
|
||||
Value val1 = TRY(get(oc.arg2().is_const, (uint64_t)oc.arg2().arg));
|
||||
Value val2 = TRY(get(oc.arg3().is_const, (uint64_t)oc.arg3().arg));
|
||||
Value res = TRY(val1.sub(val2));
|
||||
setreg(acc, res);
|
||||
return Result<void>();
|
||||
}
|
||||
|
||||
Result<void> VM::vm_div(Opcode& oc) {
|
||||
uint64_t acc = (uint64_t)oc.arg1().arg;
|
||||
Value val1 = TRY(get(oc.arg2().is_const, (uint64_t)oc.arg2().arg));
|
||||
Value val2 = TRY(get(oc.arg3().is_const, (uint64_t)oc.arg3().arg));
|
||||
Value res = TRY(val1.div(val2));
|
||||
setreg(acc, res);
|
||||
return Result<void>();
|
||||
}
|
||||
|
||||
Result<void> VM::step() {
|
||||
auto code = TRY(_fun.code());
|
||||
if (!code.is<Array>()) return ERROR(TypeMismatch);
|
||||
Array& code_arr = *code.to<Array>();
|
||||
|
||||
auto opcode = TRY(code_arr.get(_pc));
|
||||
auto opcode = TRY(_code.get(_pc));
|
||||
if (!opcode.is<Opcode>()) return ERROR(TypeMismatch);
|
||||
Opcode& oc = *opcode.to<Opcode>();
|
||||
|
||||
switch (oc.opcode()) {
|
||||
case Oc::Mov:
|
||||
TRY(vm_mov(oc));
|
||||
break;
|
||||
case Oc::Add:
|
||||
TRY(vm_add(oc));
|
||||
break;
|
||||
case Oc::Mul:
|
||||
TRY(vm_mul(oc));
|
||||
break;
|
||||
case Oc::Sub:
|
||||
TRY(vm_sub(oc));
|
||||
break;
|
||||
case Oc::Div:
|
||||
TRY(vm_div(oc));
|
||||
break;
|
||||
case Oc::Ret:
|
||||
_res = TRY(getreg((uint64_t)oc.arg1().arg));
|
||||
return ERROR(EndOfProgram);
|
||||
default:
|
||||
return ERROR(NotImplemented);
|
||||
}
|
||||
|
@ -44,16 +93,18 @@ Result<void> VM::step() {
|
|||
// Result<Value> Int64::copy() const { return Value(Int64(TRY(_value.copy())));
|
||||
// }
|
||||
Result<Value> VM::run(const Function& fun) {
|
||||
_fun = TRY(fun.copy_function());
|
||||
_fun = TRY(fun.copy());
|
||||
_pc = 0;
|
||||
_base = 0;
|
||||
_code = TRY(fun.code());
|
||||
_constants = TRY(fun.constants());
|
||||
|
||||
while (true) {
|
||||
auto rc = step();
|
||||
if (!rc.has_error()) continue;
|
||||
|
||||
// TODO: return real value
|
||||
if (rc.error() == ErrorCode::EndOfProgram) return Value(TRY(Nil::create()));
|
||||
if (rc.error() == ErrorCode::EndOfProgram) return TRY(_res.copy());
|
||||
|
||||
return rc.error();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,10 @@ class VM {
|
|||
|
||||
Result<void> step();
|
||||
Result<void> vm_mov(Opcode& oc);
|
||||
Result<void> vm_add(Opcode& oc);
|
||||
Result<void> vm_mul(Opcode& oc);
|
||||
Result<void> vm_sub(Opcode& oc);
|
||||
Result<void> vm_div(Opcode& oc);
|
||||
|
||||
Result<Value> get(bool is_const, uint64_t idx);
|
||||
Result<Value> getconst(uint64_t idx);
|
||||
|
@ -31,4 +35,5 @@ class VM {
|
|||
Array _constants;
|
||||
uint64_t _pc;
|
||||
uint64_t _base;
|
||||
Value _res;
|
||||
};
|
||||
|
|
|
@ -157,7 +157,7 @@ Result<String> Writer::write_syntax(const Syntax& val) {
|
|||
Result<String> Writer::write_pair(const Pair& val) {
|
||||
String res = TRY(String::create("("));
|
||||
|
||||
Value cur = TRY(val.copy());
|
||||
Value cur = TRY(val.copy_value());
|
||||
|
||||
bool is_first = true;
|
||||
while (!cur.is<Nil>()) {
|
||||
|
|
|
@ -34,6 +34,6 @@ Result<String> write_one(const T& value)
|
|||
requires std::derived_from<T, Object>
|
||||
{
|
||||
auto w = Writer();
|
||||
auto v = DIEX(value.copy());
|
||||
auto v = DIEX(value.copy_value());
|
||||
return w.write_one(v);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ Result<Value> to_value(const Value& val) { return val.copy(); }
|
|||
template <class T>
|
||||
requires std::derived_from<T, Object>
|
||||
Result<Value> to_value(T& val) {
|
||||
return val.copy();
|
||||
return val.copy_value();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
|
Loading…
Reference in a new issue