diff --git a/src/common.cpp b/src/common.cpp index 7aefbf0..e6ec737 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -328,7 +328,7 @@ Result StackFrame::get(uint64_t idx) const { return Value::create(_value->data[idx].get()); } -Result StackFrame::set(uint64_t idx, const Value& val) { +Result StackFrame::set(uint64_t idx, const Value& val) const { uint64_t size = std::max(_value->size, idx + 1); auto pod = TRY(arena_alloc(sizeof(OffPtr) * size)); pod->header.tag = Tag::StackFrame; diff --git a/src/common.hpp b/src/common.hpp index 7448353..0bc4914 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -1114,7 +1114,7 @@ class StackFrame : public Object { using Object::get; Result get(uint64_t idx) const; - Result set(uint64_t idx, const Value& val); + Result set(uint64_t idx, const Value& val) const; Result settop(uint64_t idx) const; Result parent() const; Result fun() const; diff --git a/src/stdlib.cpp b/src/stdlib.cpp index 43ac346..8d882d2 100644 --- a/src/stdlib.cpp +++ b/src/stdlib.cpp @@ -5,7 +5,7 @@ #include "sourcerange.hpp" #include "writer.hpp" -typedef Result (*StdlibFunctionIdPtr)(const Array& params); +typedef Result (*StdlibFunctionIdPtr)(const StackFrame& stack); struct StdlibFunctionEntry { const char* name; @@ -13,11 +13,12 @@ struct StdlibFunctionEntry { StdlibFunctionIdPtr fun_ptr; }; -Result stdlib_unknown(const Array& params) { +Result stdlib_unknown(const StackFrame& stack) { return ERROR(NotImplemented); } -Result stdlib_print(const Array& params) { +Result stdlib_print(const StackFrame& stack) { + auto params = TRY(stack.get(0)); auto size = TRY(params.size()); for (uint64_t i = 0; i < size; i++) { Value param = TRY(params.get(i)); @@ -33,19 +34,25 @@ Result stdlib_print(const Array& params) { } } - return Value(TRY(Nil::create())); + auto nil = Value(TRY(Nil::create())); + auto res = TRY(stack.set(0, nil)); + + return res.ret(0); } -Result stdlib_println(const Array& params) { - TRY(stdlib_print(params)); +Result stdlib_println(const StackFrame& stack) { + auto res = TRY(stdlib_print(stack)); std::cout << "\n"; - return Value(TRY(Nil::create())); + return res; } -Result stdlib_prn(const Array& params) { return ERROR(NotImplemented); } +Result stdlib_prn(const StackFrame& stack) { + return ERROR(NotImplemented); +} -Result stdlib_assert(const Array& params) { +Result stdlib_assert(const StackFrame& stack) { + auto params = TRY(stack.get(0)); auto size = TRY(params.size()); for (uint64_t i = 0; i < size; i++) { Value param = TRY(params.get(i)); @@ -54,40 +61,59 @@ Result stdlib_assert(const Array& params) { if (!v) return ERROR(AssertionFailed); } - return Value(TRY(Nil::create())); + auto nil = Value(TRY(Nil::create())); + auto res = TRY(stack.set(0, nil)); + + return res.ret(0); } -Result stdlib_dict(const Array& params) { - Value d = TRY(Dict::create(params)); - return d; +Result stdlib_dict(const StackFrame& stack) { + auto params = TRY(stack.get(0)); + if (!params.is()) return ERROR(TypeMismatch); + Value d = TRY(Dict::create(*params.to())); + + auto res = TRY(stack.set(0, d)); + return res.ret(0); } -Result stdlib_list(const Array& params) { - Value d = TRY(Pair::create(params)); - return d; +Result stdlib_list(const StackFrame& stack) { + auto params = TRY(stack.get(0)); + if (!params.is()) return ERROR(TypeMismatch); + Value d = TRY(Pair::create(*params.to())); + + auto res = TRY(stack.set(0, d)); + return res.ret(0); } -Result stdlib_array(const Array& params) { - Array array_copy = TRY(params.copy()); - return Value(std::move(array_copy)); +Result stdlib_array(const StackFrame& stack) { + auto params = TRY(stack.get(0)); + + auto res = TRY(stack.set(0, params)); + return res.ret(0); } -Result stdlib_get(const Array& params) { +Result stdlib_get(const StackFrame& stack) { + auto params = TRY(stack.get(0)); auto size = TRY(params.size()); if (size != 2) return ERROR(ArgumentCountMismatch); + Value collection = TRY(params.get(0)); Value key = TRY(params.get(1)); - return TRY(collection.get(key)); + + auto val = TRY(collection.get(key)); + + auto res = TRY(stack.set(0, val)); + return res.ret(0); } -Result stdlib_srcloc(const Array& params) { - Array array_copy = TRY(params.copy()); +Result stdlib_srcloc(const StackFrame& stack) { + auto params = TRY(stack.get(0)); auto size = TRY(params.size()); if (size != 6) return ERROR(ArgumentCountMismatch); SourceRange sr; for (uint64_t i = 0; i < 6; i++) { - auto val = TRY(array_copy.get(i)); + auto val = TRY(params.get(i)); if (!val.is()) return ERROR(TypeMismatch); int64_t intval = val.to()->value(); switch (i) { @@ -114,16 +140,25 @@ Result stdlib_srcloc(const Array& params) { } } - return Value(TRY(SrcLoc::create(sr))); + auto val = Value(TRY(SrcLoc::create(sr))); + + auto res = TRY(stack.set(0, val)); + return res.ret(0); } -Result stdlib_size(const Array& params) { +Result stdlib_size(const StackFrame& stack) { + auto params = TRY(stack.get(0)); auto size = TRY(params.size()); + if (size != 1) return ERROR(ArgumentCountMismatch); + auto param = TRY(params.get(0)); auto psize = TRY(param.size()); - return Value(TRY(Int64::create((int64_t)psize))); + auto val = Value(TRY(Int64::create((int64_t)psize))); + + auto res = TRY(stack.set(0, val)); + return res.ret(0); } #define STDLIB_FUNCTION(name, id) \ @@ -180,13 +215,13 @@ Result get_stdlib_function(const Symbol& name) { return fun_id; } -Result call_stdlib_function(StdlibFunctionId fun_id, - const Array& params) { +Result call_stdlib_function(StdlibFunctionId fun_id, + const StackFrame& stack) { if (fun_id == StdlibFunctionId(0) || fun_id >= StdlibFunctionId::Max) { return ERROR(KeyError); } - return function_entries[(uint64_t)fun_id].fun_ptr(params); + return function_entries[(uint64_t)fun_id].fun_ptr(stack); } Result get_stdlib_function_name(StdlibFunctionId fun_id) { diff --git a/src/stdlib.hpp b/src/stdlib.hpp index 4c71ec6..c04fd9a 100644 --- a/src/stdlib.hpp +++ b/src/stdlib.hpp @@ -22,8 +22,9 @@ enum class StdlibFunctionId : uint64_t { class Value; class Symbol; class Array; +class StackFrame; Result get_stdlib_function_name(StdlibFunctionId fun_id); Result get_stdlib_function(const Symbol& name); -Result call_stdlib_function(StdlibFunctionId fun_id, - const Array& params); +Result call_stdlib_function(StdlibFunctionId fun_id, + const StackFrame& stack); diff --git a/src/vm.cpp b/src/vm.cpp index 7f57206..2a6535f 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -278,20 +278,11 @@ Result VM::step_bytecode() { } Result VM::step_native() { - // foo auto fun = TRY(_stack.fun()); if (!fun.is()) return ERROR(TypeMismatch); auto fun_id = fun.to()->fun_id(); - auto params = TRY(_stack.get(0)); - if (!params.is()) return ERROR(TypeMismatch); - - auto res = TRY(call_stdlib_function(fun_id, *params.to())); - - auto top = TRY(_stack.size()); - _stack = TRY(_stack.set(top, res)); - _stack = TRY(_stack.ret(top)); - + _stack = TRY(call_stdlib_function(fun_id, _stack)); _stack = TRY(_stack.incpc()); return Result(); }