diff --git a/src/common.cpp b/src/common.cpp index 3e0720a..87605d2 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -84,39 +84,60 @@ Result syntax_unwrap(Value& val) { return syntax->get_value(); } -Result Nil::copy() const { return Value(Nil()); } +Result Nil::copy_value() const { return Value(Nil()); } -Result Int64::copy() const { return Value(Int64(TRY(_value.copy()))); } -Result Float::copy() const { return Value(Float(TRY(_value.copy()))); } +Result Int64::copy_value() const { + return Value(Int64(TRY(_value.copy()))); +} +Result Float::copy_value() const { + return Value(Float(TRY(_value.copy()))); +} -Result Array::copy() const { return Value(Array(TRY(_value.copy()))); } +Result Array::copy_value() const { + return Value(Array(TRY(_value.copy()))); +} +Result Array::copy() const { return Array(TRY(_value.copy())); } -Result ByteArray::copy() const { +Result ByteArray::copy_value() const { return Value(ByteArray(TRY(_value.copy()))); } -Result Dict::copy() const { return Value(Dict(TRY(_value.copy()))); } +Result Dict::copy_value() const { + return Value(Dict(TRY(_value.copy()))); +} -Result String::copy() const { return Value(String(TRY(_value.copy()))); } +Result String::copy_value() const { + return Value(String(TRY(_value.copy()))); +} -Result Symbol::copy() const { return Value(Symbol(TRY(_value.copy()))); } +Result Symbol::copy_value() const { + return Value(Symbol(TRY(_value.copy()))); +} -Result Syntax::copy() const { return Value(Syntax(TRY(_value.copy()))); } +Result Syntax::copy_value() const { + return Value(Syntax(TRY(_value.copy()))); +} -Result Pair::copy() const { return Value(Pair(TRY(_value.copy()))); } +Result Pair::copy_value() const { + return Value(Pair(TRY(_value.copy()))); +} -Result Bool::copy() const { return Value(Bool(TRY(_value.copy()))); } +Result Bool::copy_value() const { + return Value(Bool(TRY(_value.copy()))); +} -Result Opcode::copy() const { return Value(Opcode(TRY(_value.copy()))); } +Result Opcode::copy_value() const { + return Value(Opcode(TRY(_value.copy()))); +} -Result Function::copy() const { +Result Function::copy_value() const { return Value(Function(TRY(_value.copy()))); } -Result Function::copy_function() const { - return Function(TRY(_value.copy())); -} +Result Function::copy() const { return Function(TRY(_value.copy())); } -Result Stack::copy() const { return Value(Stack(TRY(_value.copy()))); } +Result Stack::copy_value() const { + return Value(Stack(TRY(_value.copy()))); +} Result Stack::get(uint64_t idx) const { if (idx >= _value->top) return ERROR(KeyError); @@ -163,7 +184,7 @@ Result Pair::rest() { } Result 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()); pod->header.tag = Tag::Function; pod->arity = arity; @@ -178,12 +199,12 @@ Result Function::name() const { return Value::create(_value->name.get()); } -Result Function::code() const { - return Value::create(_value->code.get()); +Result Function::code() const { + return Array::create((PodArray*)_value->code.get()); } -Result Function::constants() const { - return Value::create(_value->constants.get()); +Result Function::constants() const { + return Array::create((PodArray*)_value->constants.get()); } Result reverse(Value& val) { @@ -316,11 +337,45 @@ Result Dict::find(const Value& key) const { return left; } +Result Object::add(const Object&) const { return ERROR(NotImplemented); } +Result Object::add(const Int64&) const { return ERROR(NotImplemented); } + +Result Object::sub(const Object&) const { return ERROR(NotImplemented); } +Result Object::sub_inv(const Int64&) const { + return ERROR(NotImplemented); +} + +Result Object::mul(const Object&) const { return ERROR(NotImplemented); } +Result Object::mul(const Int64&) const { return ERROR(NotImplemented); } + +Result Object::div(const Object&) const { return ERROR(NotImplemented); } +Result Object::div_inv(const Int64&) const { + return ERROR(NotImplemented); +} +Result Int64::add(const Object& rhs) const { return rhs.add(*this); } +Result Int64::add(const Int64& rhs) const { + return Value(TRY(Int64::create(value() + rhs.value()))); +} + +Result Int64::mul(const Object& rhs) const { return rhs.mul(*this); } +Result Int64::mul(const Int64& rhs) const { + return Value(TRY(Int64::create(value() * rhs.value()))); +} + +Result Int64::sub(const Object& rhs) const { return rhs.sub_inv(*this); } +Result Int64::sub_inv(const Int64& rhs) const { + return Value(TRY(Int64::create(rhs.value() - value()))); +} + +Result Int64::div(const Object& rhs) const { return rhs.div_inv(*this); } +Result Int64::div_inv(const Int64& rhs) const { + return Value(TRY(Int64::create(rhs.value() / value()))); +} + Result Int64::cmp(const Float& rhs) const { return (_value->value > rhs._value->value) - (_value->value < rhs._value->value); } - Result Float::cmp(const Int64& rhs) const { return (_value->value > rhs._value->value) - (_value->value < rhs._value->value); diff --git a/src/common.hpp b/src/common.hpp index 5a8b43f..d116dda 100644 --- a/src/common.hpp +++ b/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 copy() const = 0; + virtual Result 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 cmp(const ByteArray&) const { return cmp_tag(tag(), Tag::ByteArray); } + virtual Result cmp(const Opcode& rhs) const { + return cmp_tag(tag(), Tag::Opcode); + } + virtual Result cmp(const char* rhs) const { + return ERROR(NotImplemented); + } + virtual Result cmp(const Stack& rhs) const { + return ERROR(NotImplemented); + } + + virtual Result add(const Object&) const; + virtual Result add(const Int64&) const; + + virtual Result sub(const Object&) const; + virtual Result sub_inv(const Int64&) const; + + virtual Result mul(const Object&) const; + virtual Result mul(const Int64&) const; + + virtual Result div(const Object&) const; + virtual Result div_inv(const Int64&) const; + virtual Result get(const Value& key) const; Object() = default; @@ -97,7 +121,8 @@ class Nil : public Object { return Nil(TRY(MkGcRoot(pod))); } - virtual Result copy() const final; + virtual Result copy_value() const final; + Result 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 copy() const final; + virtual Result copy_value() const final; + Result copy() const; Result get(uint64_t idx) const; virtual Result get(const Value& key) const final; @@ -165,7 +191,7 @@ class Array : public Object { return Array(TRY(MkGcRoot(pod))); } - Result sub(uint64_t start, uint64_t end) { + Result slice(uint64_t start, uint64_t end) { if (start > end) return ERROR(IndexOutOfRange); uint64_t res_size = end - start; auto pod = TRY(arena_alloc(res_size * sizeof(PodObject*))); @@ -230,7 +256,8 @@ class ByteArray : public Object { static Result create(const String& str); uint64_t size() const { return _value->size; } - virtual Result copy() const final; + virtual Result copy_value() const final; + Result copy() const; Result 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 sub(uint64_t start, uint64_t end) { + Result slice(uint64_t start, uint64_t end) { if (start > end) return ERROR(IndexOutOfRange); uint64_t res_size = end - start; auto pod = TRY(arena_alloc(res_size * sizeof(char))); @@ -321,7 +348,8 @@ class Dict : public Object { return Dict(TRY(MkGcRoot(pod))); } - virtual Result copy() const final; + virtual Result copy_value() const final; + Result copy() const; virtual Result get(const Value& key) const final; @@ -419,7 +447,8 @@ class String : public Object { } uint64_t size() const { return _value->size; } - virtual Result copy() const final; + virtual Result copy_value() const final; + Result copy() const; Result 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 sub(uint64_t start, uint64_t end) { + Result slice(uint64_t start, uint64_t end) { if (start > end) return ERROR(IndexOutOfRange); uint64_t res_size = end - start; auto pod = TRY(arena_alloc(res_size * sizeof(char32_t))); @@ -561,7 +590,8 @@ class Symbol : public Object { } static Result create(String& rhs); - virtual Result copy() const final; + virtual Result copy_value() const final; + Result copy() const; uint64_t size() const { return _value->size; } @@ -595,7 +625,8 @@ class Syntax : public Object { Result get_value(); - virtual Result copy() const final; + virtual Result copy_value() const final; + Result copy() const; private: GcRoot _value; @@ -621,7 +652,8 @@ class Pair : public Object { Result first(); Result rest(); - virtual Result copy() const final; + virtual Result copy_value() const final; + Result copy() const; private: GcRoot _value; @@ -645,6 +677,18 @@ class Int64 : public Object { } virtual Result cmp(const Float& rhs) const final; + virtual Result add(const Object& rhs) const final; + virtual Result add(const Int64& rhs) const final; + + virtual Result mul(const Object& rhs) const final; + virtual Result mul(const Int64& rhs) const final; + + virtual Result sub(const Object& rhs) const final; + virtual Result sub_inv(const Int64& rhs) const final; + + virtual Result div(const Object& rhs) const final; + virtual Result div_inv(const Int64& rhs) const final; + virtual void move(Object* obj) final { new (obj) Int64(std::move(_value)); } static Result create(PodInt64* obj) { @@ -661,7 +705,8 @@ class Int64 : public Object { int64_t value() const { return _value->value; } - virtual Result copy() const final; + virtual Result copy_value() const final; + Result copy() const; private: GcRoot _value; @@ -701,7 +746,8 @@ class Float : public Object { double value() const { return _value->value; } - virtual Result copy() const final; + virtual Result copy_value() const final; + Result copy() const; private: GcRoot _value; @@ -734,7 +780,8 @@ class Bool : public Object { bool value() const { return _value->value; } - virtual Result copy() const final; + virtual Result copy_value() const final; + Result copy() const; private: GcRoot _value; @@ -779,7 +826,8 @@ class Opcode : public Object { OpArg arg3() const { return _value->arg3; } OpArg arg4() const { return _value->arg4; } - virtual Result copy() const final; + virtual Result copy_value() const final; + Result copy() const; private: GcRoot _value; @@ -812,16 +860,16 @@ class Function : public Object { } static Result 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 name() const; - Result code() const; - Result constants() const; + Result code() const; + Result constants() const; - virtual Result copy() const final; - virtual Result copy_function() const final; + virtual Result copy_value() const final; + Result copy() const; private: GcRoot _value; @@ -864,7 +912,8 @@ class Stack : public Object { return Stack(TRY(MkGcRoot(pod))); } - virtual Result copy() const final; + virtual Result copy_value() const final; + Result copy() const; private: GcRoot _value; @@ -925,6 +974,22 @@ class Value { return ((Object*)buf)->cmp(*(Object*)rhs.buf); } + Result add(const Value& rhs) const { + return ((Object*)buf)->add(*(Object*)rhs.buf); + } + + Result mul(const Value& rhs) const { + return ((Object*)buf)->mul(*(Object*)rhs.buf); + } + + Result sub(const Value& rhs) const { + return ((Object*)buf)->sub(*(Object*)rhs.buf); + } + + Result div(const Value& rhs) const { + return ((Object*)buf)->div(*(Object*)rhs.buf); + } + Result get(Value& key) { return ((Object*)buf)->get(key); } Result get(int64_t key) { Value k = TRY(Int64::create(key)); @@ -935,7 +1000,7 @@ class Value { // Result operator==(Value& rhs) { return TRY(cmp(rhs)) == 0; } // Result operator!=(Value& rhs) { return TRY(cmp(rhs)) != 0; } - Result copy() const { return ((Object*)buf)->copy(); } + Result copy() const { return ((Object*)buf)->copy_value(); } private: uint8_t buf[24]; diff --git a/src/compiler.cpp b/src/compiler.cpp index 427cc6b..788ea41 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -67,12 +67,10 @@ Result 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 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 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})); diff --git a/src/reader.cpp b/src/reader.cpp index 74de2fa..92dcb9c 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -296,7 +296,7 @@ Result 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); diff --git a/src/vli.cpp b/src/vli.cpp index d79e30d..ae84e4d 100644 --- a/src/vli.cpp +++ b/src/vli.cpp @@ -10,7 +10,7 @@ StaticArena<64 * 1024 * 1024> arena; Result 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 run() { auto res = TRY(vm.run(fun)); + TRY(debug_print(res)); + return Result(); } diff --git a/src/vm.cpp b/src/vm.cpp index 84ac922..29a6ecc 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -7,7 +7,7 @@ Result VM::setreg(uint64_t idx, const Value& value) { return Result(); } -Result VM::getconst(uint64_t idx) { return ERROR(NotImplemented); } +Result VM::getconst(uint64_t idx) { return _constants.get(idx); } Result VM::get(bool is_const, uint64_t idx) { if (is_const) return getconst(idx); @@ -16,22 +16,71 @@ Result VM::get(bool is_const, uint64_t idx) { Result 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(); +} + +Result 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(); +} + +Result 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(); +} + +Result 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(); +} + +Result 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(); } Result VM::step() { - auto code = TRY(_fun.code()); - if (!code.is()) return ERROR(TypeMismatch); - Array& code_arr = *code.to(); - - auto opcode = TRY(code_arr.get(_pc)); + auto opcode = TRY(_code.get(_pc)); if (!opcode.is()) return ERROR(TypeMismatch); Opcode& oc = *opcode.to(); 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 VM::step() { // Result Int64::copy() const { return Value(Int64(TRY(_value.copy()))); // } Result 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(); } diff --git a/src/vm.hpp b/src/vm.hpp index e1b8e89..6b66797 100644 --- a/src/vm.hpp +++ b/src/vm.hpp @@ -18,6 +18,10 @@ class VM { Result step(); Result vm_mov(Opcode& oc); + Result vm_add(Opcode& oc); + Result vm_mul(Opcode& oc); + Result vm_sub(Opcode& oc); + Result vm_div(Opcode& oc); Result get(bool is_const, uint64_t idx); Result getconst(uint64_t idx); @@ -31,4 +35,5 @@ class VM { Array _constants; uint64_t _pc; uint64_t _base; + Value _res; }; diff --git a/src/writer.cpp b/src/writer.cpp index 5a6a5f4..e0deb41 100644 --- a/src/writer.cpp +++ b/src/writer.cpp @@ -157,7 +157,7 @@ Result Writer::write_syntax(const Syntax& val) { Result 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()) { diff --git a/src/writer.hpp b/src/writer.hpp index 40996e5..33ab5e2 100644 --- a/src/writer.hpp +++ b/src/writer.hpp @@ -34,6 +34,6 @@ Result write_one(const T& value) requires std::derived_from { auto w = Writer(); - auto v = DIEX(value.copy()); + auto v = DIEX(value.copy_value()); return w.write_one(v); } diff --git a/test/test.hpp b/test/test.hpp index 95fea0a..a8eab22 100644 --- a/test/test.hpp +++ b/test/test.hpp @@ -49,7 +49,7 @@ Result to_value(const Value& val) { return val.copy(); } template requires std::derived_from Result to_value(T& val) { - return val.copy(); + return val.copy_value(); } template