diff --git a/include/pocketpy/common/utils.h b/include/pocketpy/common/utils.h index f11604da..3a8399a1 100644 --- a/include/pocketpy/common/utils.h +++ b/include/pocketpy/common/utils.h @@ -1,5 +1,8 @@ #pragma once +#include "stdio.h" +#include "stdlib.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/include/pocketpy/compiler/expr.h b/include/pocketpy/compiler/expr.h new file mode 100644 index 00000000..e20cfae6 --- /dev/null +++ b/include/pocketpy/compiler/expr.h @@ -0,0 +1,52 @@ +// #pragma once + +// #include +// #include "pocketpy/common/memorypool.h" +// #include "pocketpy/compiler/lexer.h" + +// #ifdef __cplusplus +// extern "C" { +// #endif + +// struct pk_Expr; +// struct pk_CodeEmitContext; + +// struct pk_ExprVt{ +// void (*dtor)(pk_Expr*); +// /* reflections */ +// bool (*is_literal)(const pk_Expr*); +// bool (*is_json_object)(const pk_Expr*); +// bool (*is_attrib)(const pk_Expr*); +// bool (*is_subscr)(const pk_Expr*); +// bool (*is_compare)(const pk_Expr*); +// int (*star_level)(const pk_Expr*); +// bool (*is_tuple)(const pk_Expr*); +// bool (*is_name)(const pk_Expr*); +// /* emit */ +// void (*emit_)(pk_Expr*, pk_CodeEmitContext*); +// bool (*emit_del)(pk_Expr*, pk_CodeEmitContext*); +// bool (*emit_store)(pk_Expr*, pk_CodeEmitContext*); +// void (*emit_inplace)(pk_Expr*, pk_CodeEmitContext*); +// bool (*emit_store_inplace)(pk_Expr*, pk_CodeEmitContext*); +// }; + +// typedef struct pk_Expr{ +// pk_ExprVt* vt; +// int line; +// } pk_Expr; + +// void pk_ExprVt__ctor(pk_ExprVt* vt); +// void pk_Expr__emit_(pk_Expr* self, pk_CodeEmitContext* ctx); +// bool pk_Expr__emit_del(pk_Expr* self, pk_CodeEmitContext* ctx); +// bool pk_Expr__emit_store(pk_Expr* self, pk_CodeEmitContext* ctx); +// void pk_Expr__emit_inplace(pk_Expr* self, pk_CodeEmitContext* ctx); +// bool pk_Expr__emit_store_inplace(pk_Expr* self, pk_CodeEmitContext* ctx); +// void pk_Expr__delete(pk_Expr* self); + +// typedef struct pk_CodeEmitContext{ + +// } pk_CodeEmitContext; + +// #ifdef __cplusplus +// } +// #endif diff --git a/include/pocketpy/compiler/expr.hpp b/include/pocketpy/compiler/expr.hpp index 840af49b..90fbe46c 100644 --- a/include/pocketpy/compiler/expr.hpp +++ b/include/pocketpy/compiler/expr.hpp @@ -10,48 +10,7 @@ struct Expr; typedef small_vector Expr_vector; -static bool default_false(const Expr*) { return false; } -static int default_zero(const Expr*) { return 0; } -static void default_dtor(Expr*) {} - -struct ExprVt{ - void (*dtor)(Expr*); - /* reflections */ - bool (*is_literal)(const Expr*); - bool (*is_json_object)(const Expr*); - bool (*is_attrib)(const Expr*); - bool (*is_subscr)(const Expr*); - bool (*is_compare)(const Expr*); - int (*star_level)(const Expr*); - bool (*is_tuple)(const Expr*); - bool (*is_name)(const Expr*); - /* emit */ - void (*emit_)(Expr*, CodeEmitContext*); - bool (*emit_del)(Expr*, CodeEmitContext*); - bool (*emit_store)(Expr*, CodeEmitContext*); - void (*emit_inplace)(Expr*, CodeEmitContext*); - bool (*emit_store_inplace)(Expr*, CodeEmitContext*); -}; - -void ExprVt__ctor(ExprVt* vt){ - vt->dtor = default_dtor; - vt->is_literal = default_false; - vt->is_json_object = default_false; - vt->is_attrib = default_false; - vt->is_subscr = default_false; - vt->is_compare = default_false; - vt->star_level = default_zero; - vt->is_tuple = default_false; - vt->is_name = default_false; - vt->emit_ = NULL; // must be set - vt->emit_del = NULL; - vt->emit_store = NULL; - vt->emit_inplace = NULL; - vt->emit_store_inplace = NULL; -} - struct Expr { - ExprVt* vt; int line = 0; virtual ~Expr() = default; virtual void emit_(CodeEmitContext* ctx) = 0; @@ -80,36 +39,6 @@ struct Expr { [[nodiscard]] virtual bool emit_store_inplace(CodeEmitContext* ctx) { return emit_store(ctx); } }; -void pk_Expr__emit_(Expr* self, CodeEmitContext* ctx){ - assert(self->vt->emit_); - self->vt->emit_(self, ctx); -} - -bool pk_Expr__emit_del(Expr* self, CodeEmitContext* ctx){ - if(!self->vt->emit_del) return false; - return self->vt->emit_del(self, ctx); -} - -bool pk_Expr__emit_store(Expr* self, CodeEmitContext* ctx){ - if(!self->vt->emit_store) return false; - return self->vt->emit_store(self, ctx); -} - -void pk_Expr__emit_inplace(Expr* self, CodeEmitContext* ctx){ - if(!self->vt->emit_inplace){ - pk_Expr__emit_(self, ctx); - return; - } - self->vt->emit_inplace(self, ctx); -} - -bool pk_Expr__emit_store_inplace(Expr* self, CodeEmitContext* ctx){ - if(!self->vt->emit_store_inplace){ - return pk_Expr__emit_store(self, ctx); - } - return self->vt->emit_store_inplace(self, ctx); -} - inline void delete_expr(Expr* p) noexcept{ if(!p) return; p->~Expr(); diff --git a/include/pocketpy/interpreter/bindings.hpp b/include/pocketpy/interpreter/bindings.hpp index b5bf1ea5..00d05d55 100644 --- a/include/pocketpy/interpreter/bindings.hpp +++ b/include/pocketpy/interpreter/bindings.hpp @@ -175,7 +175,7 @@ PyObject* VM::bind_field(PyObject* obj, const char* name, F T::*field) { return obj; \ }, \ {}, \ - BindType::STATICMETHOD); \ + BindType_STATICMETHOD); \ vm->bind_func(type, "tostruct", 1, [](VM* vm, ArgsView args) { \ wT& self = _CAST(wT&, args[0]); \ return vm->new_user_object(&self, sizeof(wT)); \ diff --git a/include/pocketpy/interpreter/vm.hpp b/include/pocketpy/interpreter/vm.hpp index 43f7e3bf..78840f72 100644 --- a/include/pocketpy/interpreter/vm.hpp +++ b/include/pocketpy/interpreter/vm.hpp @@ -362,25 +362,25 @@ public: #endif #if PK_REGION("General Bindings") - PyObject* bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType::DEFAULT); - PyObject* bind_func(Type type, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType::DEFAULT){ + PyObject* bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType_FUNCTION); + PyObject* bind_func(Type type, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType_FUNCTION){ return bind_func(_t(type), name, argc, fn, std::move(userdata), bt); } PyObject* bind_property(PyObject*, const char*, NativeFuncC fget, NativeFuncC fset=nullptr); template PyObject* bind_field(PyObject*, const char*, F T::*); - PyObject* bind(PyObject*, const char*, NativeFuncC, any userdata={}, BindType bt=BindType::DEFAULT); + PyObject* bind(PyObject*, const char*, NativeFuncC, any userdata={}, BindType bt=BindType_FUNCTION); template - PyObject* bind(PyObject*, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT); + PyObject* bind(PyObject*, const char*, Ret(*)(Params...), BindType bt=BindType_FUNCTION); template - PyObject* bind(PyObject*, const char*, Ret(T::*)(Params...), BindType bt=BindType::DEFAULT); + PyObject* bind(PyObject*, const char*, Ret(T::*)(Params...), BindType bt=BindType_FUNCTION); - PyObject* bind(PyObject*, const char*, const char*, NativeFuncC, any userdata={}, BindType bt=BindType::DEFAULT); + PyObject* bind(PyObject*, const char*, const char*, NativeFuncC, any userdata={}, BindType bt=BindType_FUNCTION); template - PyObject* bind(PyObject*, const char*, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT); + PyObject* bind(PyObject*, const char*, const char*, Ret(*)(Params...), BindType bt=BindType_FUNCTION); template - PyObject* bind(PyObject*, const char*, const char*, Ret(T::*)(Params...), BindType bt=BindType::DEFAULT); + PyObject* bind(PyObject*, const char*, const char*, Ret(T::*)(Params...), BindType bt=BindType_FUNCTION); #endif #if PK_REGION("Error Reporting Methods") diff --git a/include/pocketpy/objects/codeobject.h b/include/pocketpy/objects/codeobject.h new file mode 100644 index 00000000..610ef64b --- /dev/null +++ b/include/pocketpy/objects/codeobject.h @@ -0,0 +1,57 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BC_NOARG 0 +#define BC_KEEPLINE -1 + +typedef enum BindType { + BindType_FUNCTION, + BindType_STATICMETHOD, + BindType_CLASSMETHOD, +} BindType; + +typedef enum FuncType { + FuncType_UNSET, + FuncType_NORMAL, + FuncType_SIMPLE, + FuncType_EMPTY, + FuncType_GENERATOR, +} FuncType; + +typedef enum NameScope { + NAME_LOCAL, + NAME_GLOBAL, + NAME_GLOBAL_UNKNOWN +} NameScope; + +typedef enum CodeBlockType { + NO_BLOCK, + FOR_LOOP, + WHILE_LOOP, + CONTEXT_MANAGER, + TRY_EXCEPT, +} CodeBlockType; + +typedef enum Opcode { + #define OPCODE(name) OP_##name, + #include "pocketpy/xmacros/opcodes.h" + #undef OPCODE +} Opcode; + +typedef struct Bytecode { + uint8_t op; + uint16_t arg; +} Bytecode; + +void Bytecode__set_signed_arg(Bytecode* self, int arg); +bool Bytecode__is_forward_jump(const Bytecode* self); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/pocketpy/objects/codeobject.hpp b/include/pocketpy/objects/codeobject.hpp index 56a03882..8e448a3b 100644 --- a/include/pocketpy/objects/codeobject.hpp +++ b/include/pocketpy/objects/codeobject.hpp @@ -6,49 +6,12 @@ #include "pocketpy/objects/namedict.hpp" #include "pocketpy/objects/sourcedata.h" #include "pocketpy/common/smallmap.h" +#include "pocketpy/objects/codeobject.h" namespace pkpy { typedef PyVar (*NativeFuncC)(VM*, ArgsView); -enum class BindType { - DEFAULT, - STATICMETHOD, - CLASSMETHOD, -}; - -enum NameScope { NAME_LOCAL, NAME_GLOBAL, NAME_GLOBAL_UNKNOWN }; - -enum Opcode : uint8_t { - -#define OPCODE(name) OP_##name, -#include "pocketpy/xmacros/opcodes.h" -#undef OPCODE -}; - -struct Bytecode { - uint8_t op; - uint16_t arg; - - void set_signed_arg(int arg) { - assert(arg >= INT16_MIN && arg <= INT16_MAX); - this->arg = (int16_t)arg; - } - - bool is_forward_jump() const { return op >= OP_JUMP_FORWARD && op <= OP_LOOP_BREAK; } -}; - -enum class CodeBlockType { - NO_BLOCK, - FOR_LOOP, - WHILE_LOOP, - CONTEXT_MANAGER, - TRY_EXCEPT, -}; - -const inline uint8_t BC_NOARG = 0; -const inline int BC_KEEPLINE = -1; - struct CodeBlock { CodeBlockType type; int parent; // parent index in blocks @@ -116,14 +79,6 @@ struct CodeObject { } }; -enum class FuncType { - UNSET, - NORMAL, - SIMPLE, - EMPTY, - GENERATOR, -}; - struct FuncDecl { struct KwArg { int index; // index in co->varnames @@ -142,7 +97,7 @@ struct FuncDecl { const char* docstring; // docstring of this function (weak ref) - FuncType type = FuncType::UNSET; + FuncType type = FuncType_UNSET; c11_smallmap_n2i kw_to_index; void add_kwarg(int index, StrName key, PyVar value) { diff --git a/src/compiler/compiler.cpp b/src/compiler/compiler.cpp index 56a21fc0..c51f5273 100644 --- a/src/compiler/compiler.cpp +++ b/src/compiler/compiler.cpp @@ -60,9 +60,9 @@ Error* Compiler::pop_context() noexcept{ for(int i = 0; i < codes.size(); i++) { Bytecode& bc = codes[i]; if(bc.op == OP_LOOP_CONTINUE) { - bc.set_signed_arg(ctx()->co->blocks[bc.arg].start - i); + Bytecode__set_signed_arg(&bc, ctx()->co->blocks[bc.arg].start - i); } else if(bc.op == OP_LOOP_BREAK) { - bc.set_signed_arg(ctx()->co->blocks[bc.arg].get_break_end() - i); + Bytecode__set_signed_arg(&bc, ctx()->co->blocks[bc.arg].get_break_end() - i); } } // pre-compute func->is_simple @@ -71,7 +71,7 @@ Error* Compiler::pop_context() noexcept{ // check generator for(Bytecode bc: func->code->codes) { if(bc.op == OP_YIELD_VALUE || bc.op == OP_FOR_ITER_YIELD_VALUE) { - func->type = FuncType::GENERATOR; + func->type = FuncType_GENERATOR; for(Bytecode bc: func->code->codes) { if(bc.op == OP_RETURN_VALUE && bc.arg == BC_NOARG) { return SyntaxError("'return' with argument inside generator function"); @@ -80,26 +80,26 @@ Error* Compiler::pop_context() noexcept{ break; } } - if(func->type == FuncType::UNSET) { + if(func->type == FuncType_UNSET) { bool is_simple = true; if(func->kwargs.size() > 0) is_simple = false; if(func->starred_arg >= 0) is_simple = false; if(func->starred_kwarg >= 0) is_simple = false; if(is_simple) { - func->type = FuncType::SIMPLE; + func->type = FuncType_SIMPLE; bool is_empty = false; if(func->code->codes.size() == 1) { Bytecode bc = func->code->codes[0]; if(bc.op == OP_RETURN_VALUE && bc.arg == 1) { is_empty = true; } } - if(is_empty) func->type = FuncType::EMPTY; + if(is_empty) func->type = FuncType_EMPTY; } else - func->type = FuncType::NORMAL; + func->type = FuncType_NORMAL; } - assert(func->type != FuncType::UNSET); + assert(func->type != FuncType_UNSET); } contexts.back().s_clean(); contexts.pop_back(); @@ -822,7 +822,7 @@ Error* Compiler::compile_try_except() noexcept{ i64 target = ctx()->co->codes.size() + 2; ctx()->emit_(OP_LOAD_CONST, ctx()->add_const(VAR(target)), BC_KEEPLINE); int i = ctx()->emit_(OP_JUMP_FORWARD, BC_NOARG, BC_KEEPLINE); - ctx()->co->codes[i].set_signed_arg(finally_entry - i); + Bytecode__set_signed_arg(&ctx()->co->codes[i], finally_entry - i); } ctx()->emit_(OP_RE_RAISE, BC_NOARG, BC_KEEPLINE); @@ -833,7 +833,7 @@ Error* Compiler::compile_try_except() noexcept{ i64 target = ctx()->co->codes.size() + 2; ctx()->emit_(OP_LOAD_CONST, ctx()->add_const(VAR(target)), BC_KEEPLINE); int i = ctx()->emit_(OP_JUMP_FORWARD, BC_NOARG, BC_KEEPLINE); - ctx()->co->codes[i].set_signed_arg(finally_entry - i); + Bytecode__set_signed_arg(&ctx()->co->codes[i], finally_entry - i); } return NULL; } diff --git a/src/compiler/expr.c b/src/compiler/expr.c new file mode 100644 index 00000000..5674d119 --- /dev/null +++ b/src/compiler/expr.c @@ -0,0 +1,59 @@ +// #include "pocketpy/compiler/expr.h" +// #include "pocketpy/common/memorypool.h" + +// static bool default_false(const pk_Expr*) { return false; } +// static int default_zero(const pk_Expr*) { return 0; } +// static void default_dtor(pk_Expr*) {} + +// void pk_ExprVt__ctor(pk_ExprVt* vt){ +// vt->dtor = default_dtor; +// vt->is_literal = default_false; +// vt->is_json_object = default_false; +// vt->is_attrib = default_false; +// vt->is_subscr = default_false; +// vt->is_compare = default_false; +// vt->star_level = default_zero; +// vt->is_tuple = default_false; +// vt->is_name = default_false; +// vt->emit_ = NULL; // must be set +// vt->emit_del = NULL; +// vt->emit_store = NULL; +// vt->emit_inplace = NULL; +// vt->emit_store_inplace = NULL; +// } + +// void pk_Expr__emit_(pk_Expr* self, pk_CodeEmitContext* ctx){ +// assert(self->vt->emit_); +// self->vt->emit_(self, ctx); +// } + +// bool pk_Expr__emit_del(pk_Expr* self, pk_CodeEmitContext* ctx){ +// if(!self->vt->emit_del) return false; +// return self->vt->emit_del(self, ctx); +// } + +// bool pk_Expr__emit_store(pk_Expr* self, pk_CodeEmitContext* ctx){ +// if(!self->vt->emit_store) return false; +// return self->vt->emit_store(self, ctx); +// } + +// void pk_Expr__emit_inplace(pk_Expr* self, pk_CodeEmitContext* ctx){ +// if(!self->vt->emit_inplace){ +// pk_Expr__emit_(self, ctx); +// return; +// } +// self->vt->emit_inplace(self, ctx); +// } + +// bool pk_Expr__emit_store_inplace(pk_Expr* self, pk_CodeEmitContext* ctx){ +// if(!self->vt->emit_store_inplace){ +// return pk_Expr__emit_store(self, ctx); +// } +// return self->vt->emit_store_inplace(self, ctx); +// } + +// void pk_Expr__delete(pk_Expr* self){ +// if(!self) return; +// self->vt->dtor(self); +// PoolExpr_dealloc(self); +// } \ No newline at end of file diff --git a/src/compiler/expr.cpp b/src/compiler/expr.cpp index aa09921d..dc518fdd 100644 --- a/src/compiler/expr.cpp +++ b/src/compiler/expr.cpp @@ -101,7 +101,7 @@ int CodeEmitContext::emit_int(i64 value, int line) noexcept{ void CodeEmitContext::patch_jump(int index) noexcept{ int target = co->codes.size(); - co->codes[index].set_signed_arg(target - index); + Bytecode__set_signed_arg(&co->codes[index], target - index); } bool CodeEmitContext::add_label(StrName name) noexcept{ diff --git a/src/interpreter/cffi.cpp b/src/interpreter/cffi.cpp index fb7f120b..f4f16106 100644 --- a/src/interpreter/cffi.cpp +++ b/src/interpreter/cffi.cpp @@ -84,7 +84,7 @@ void Struct::_register(VM* vm, PyObject* mod, PyObject* type) { return vm->new_user_object(std::move(buffer)); }, {}, - BindType::STATICMETHOD); + BindType_STATICMETHOD); vm->bind__repr__(type->as(), [](VM* vm, PyVar obj) { Struct& self = _CAST(Struct&, obj); diff --git a/src/interpreter/vm.cpp b/src/interpreter/vm.cpp index 0bc5add3..ab7218e5 100644 --- a/src/interpreter/vm.cpp +++ b/src/interpreter/vm.cpp @@ -738,7 +738,7 @@ PyObject* VM::new_module(Str name, Str package) { static std::string _opcode_argstr(VM* vm, int i, Bytecode byte, const CodeObject* co) { SStream ss; - if(byte.is_forward_jump()) { + if(Bytecode__is_forward_jump(&byte)){ std::string argStr = std::to_string((int16_t)byte.arg); ss << (i64)(int16_t)byte.arg; ss << " (to " << (i64)((int16_t)byte.arg + i) << ")"; @@ -784,7 +784,9 @@ Str VM::disassemble(CodeObject_ co) { vector jumpTargets; for(int i = 0; i < co->codes.size(); i++) { Bytecode byte = co->codes[i]; - if(byte.is_forward_jump()) { jumpTargets.push_back((int16_t)byte.arg + i); } + if(Bytecode__is_forward_jump(&byte)) { + jumpTargets.push_back((int16_t)byte.arg + i); + } } SStream ss; int prev_line = -1; @@ -1070,14 +1072,14 @@ PyVar VM::vectorcall(int ARGC, int KWARGC, bool op_call) { const CodeObject* co = fn.decl->code.get(); switch(fn.decl->type) { - case FuncType::NORMAL: + case FuncType_NORMAL: __prepare_py_call(__vectorcall_buffer, args, kwargs, fn.decl); // copy buffer back to stack s_data.reset(_base + co->nlocals); for(int j = 0; j < co->nlocals; j++) _base[j] = __vectorcall_buffer[j]; break; - case FuncType::SIMPLE: + case FuncType_SIMPLE: if(args.size() != fn.decl->args.size()) TypeError(_S(co->name, "() takes ", @@ -1092,7 +1094,7 @@ PyVar VM::vectorcall(int ARGC, int KWARGC, bool op_call) { // initialize local variables to PY_NULL std::memset(p1, 0, (char*)s_data._sp - (char*)p1); break; - case FuncType::EMPTY: + case FuncType_EMPTY: if(args.size() != fn.decl->args.size()) TypeError(_S(co->name, "() takes ", @@ -1103,7 +1105,7 @@ PyVar VM::vectorcall(int ARGC, int KWARGC, bool op_call) { if(!kwargs.empty()) TypeError(_S(co->name, "() takes no keyword arguments")); s_data.reset(p0); return None; - case FuncType::GENERATOR: + case FuncType_GENERATOR: __prepare_py_call(__vectorcall_buffer, args, kwargs, fn.decl); s_data.reset(p0); callstack.emplace(nullptr, co, fn._module, callable.get(), nullptr); @@ -1360,9 +1362,9 @@ void VM::setattr(PyVar obj, StrName name, PyVar value) { PyObject* VM::bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, any userdata, BindType bt) { PyObject* nf = new_object(tp_native_func, fn, argc, std::move(userdata)).get(); switch(bt) { - case BindType::DEFAULT: break; - case BindType::STATICMETHOD: nf = new_object(tp_staticmethod, nf).get(); break; - case BindType::CLASSMETHOD: nf = new_object(tp_classmethod, nf).get(); break; + case BindType_FUNCTION: break; + case BindType_STATICMETHOD: nf = new_object(tp_staticmethod, nf).get(); break; + case BindType_CLASSMETHOD: nf = new_object(tp_classmethod, nf).get(); break; } if(obj != nullptr) obj->attr().set(name, nf); return nf; @@ -1385,9 +1387,9 @@ PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Native PyObject* f_obj = new_object(tp_native_func, fn, decl, std::move(userdata)).get(); switch(bt) { - case BindType::STATICMETHOD: f_obj = new_object(tp_staticmethod, f_obj).get(); break; - case BindType::CLASSMETHOD: f_obj = new_object(tp_classmethod, f_obj).get(); break; - case BindType::DEFAULT: break; + case BindType_STATICMETHOD: f_obj = new_object(tp_staticmethod, f_obj).get(); break; + case BindType_CLASSMETHOD: f_obj = new_object(tp_classmethod, f_obj).get(); break; + case BindType_FUNCTION: break; } if(obj != nullptr) obj->attr().set(decl->code->name, f_obj); return f_obj; diff --git a/src/modules/linalg.cpp b/src/modules/linalg.cpp index 3b1cb77b..531c1894 100644 --- a/src/modules/linalg.cpp +++ b/src/modules/linalg.cpp @@ -152,7 +152,7 @@ void Vec2::_register(VM* vm, PyObject* mod, PyObject* type) { return VAR(Tuple(VAR(ret), VAR(current_velocity_))); }, {}, - BindType::STATICMETHOD); + BindType_STATICMETHOD); // @staticmethod vm->bind( @@ -168,7 +168,7 @@ void Vec2::_register(VM* vm, PyObject* mod, PyObject* type) { return VAR(val); }, {}, - BindType::STATICMETHOD); + BindType_STATICMETHOD); vm->bind__repr__(type->as(), [](VM* vm, PyVar obj) -> Str { Vec2 self = _CAST(Vec2, obj); @@ -452,7 +452,7 @@ void Mat3x3::_register(VM* vm, PyObject* mod, PyObject* type) { return vm->new_user_object(Mat3x3::zeros()); }, {}, - BindType::STATICMETHOD); + BindType_STATICMETHOD); // @staticmethod vm->bind_func( @@ -463,7 +463,7 @@ void Mat3x3::_register(VM* vm, PyObject* mod, PyObject* type) { return vm->new_user_object(Mat3x3::ones()); }, {}, - BindType::STATICMETHOD); + BindType_STATICMETHOD); // @staticmethod vm->bind_func( @@ -474,7 +474,7 @@ void Mat3x3::_register(VM* vm, PyObject* mod, PyObject* type) { return vm->new_user_object(Mat3x3::identity()); }, {}, - BindType::STATICMETHOD); + BindType_STATICMETHOD); /*************** affine transformations ***************/ // @staticmethod @@ -488,7 +488,7 @@ void Mat3x3::_register(VM* vm, PyObject* mod, PyObject* type) { return vm->new_user_object(Mat3x3::trs(t, r, s)); }, {}, - BindType::STATICMETHOD); + BindType_STATICMETHOD); vm->bind(type, "copy_trs_(self, t: vec2, r: float, s: vec2)", [](VM* vm, ArgsView args) { Mat3x3& self = _CAST(Mat3x3&, args[0]); diff --git a/src/objects/codeobject.c b/src/objects/codeobject.c new file mode 100644 index 00000000..d3406606 --- /dev/null +++ b/src/objects/codeobject.c @@ -0,0 +1,13 @@ +#include "pocketpy/objects/codeobject.h" +#include "pocketpy/common/utils.h" + +void Bytecode__set_signed_arg(Bytecode* self, int arg) { + if(arg < INT16_MIN || arg > INT16_MAX) { + PK_FATAL_ERROR("set_signed_arg: %d is out of range", arg); + } + self->arg = (int16_t)arg; +} + +bool Bytecode__is_forward_jump(const Bytecode* self) { + return self->op >= OP_JUMP_FORWARD && self->op <= OP_LOOP_BREAK; +}