mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 12:00:18 +00:00
support @property.setter
This commit is contained in:
parent
e8ad5b5784
commit
e124f635c1
@ -23,7 +23,7 @@
|
||||
#include <bitset>
|
||||
#include <deque>
|
||||
|
||||
#define PK_VERSION "1.2.9"
|
||||
#define PK_VERSION "1.3.0"
|
||||
|
||||
#include "config.h"
|
||||
#include "export.h"
|
||||
|
@ -23,6 +23,7 @@ OPCODE(LOAD_NAME)
|
||||
OPCODE(LOAD_NONLOCAL)
|
||||
OPCODE(LOAD_GLOBAL)
|
||||
OPCODE(LOAD_ATTR)
|
||||
OPCODE(LOAD_CLASS_GLOBAL)
|
||||
OPCODE(LOAD_METHOD)
|
||||
OPCODE(LOAD_SUBSCR)
|
||||
|
||||
|
@ -133,7 +133,8 @@ public:
|
||||
PyObject* StopIteration;
|
||||
PyObject* _main; // __main__ module
|
||||
|
||||
PyObject* _last_exception;
|
||||
PyObject* _last_exception; // last exception
|
||||
PyObject* _curr_class; // current class being defined
|
||||
|
||||
#if PK_ENABLE_CEVAL_CALLBACK
|
||||
void (*_ceval_on_step)(VM*, Frame*, Bytecode bc) = nullptr;
|
||||
|
@ -182,10 +182,22 @@ __NEXT_STEP:;
|
||||
_0 = vm->builtins->attr().try_get_likely_found(_name);
|
||||
if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
||||
vm->NameError(_name);
|
||||
}DISPATCH();
|
||||
TARGET(LOAD_ATTR)
|
||||
} DISPATCH();
|
||||
TARGET(LOAD_ATTR){
|
||||
TOP() = getattr(TOP(), StrName(byte.arg));
|
||||
DISPATCH();
|
||||
} DISPATCH();
|
||||
TARGET(LOAD_CLASS_GLOBAL){
|
||||
PK_ASSERT(_curr_class != nullptr);
|
||||
StrName _name(byte.arg);
|
||||
PyObject* _0 = getattr(_curr_class, _name, false);
|
||||
if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
||||
// load global if attribute not found
|
||||
_0 = frame->f_globals().try_get_likely_found(_name);
|
||||
if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
||||
_0 = vm->builtins->attr().try_get_likely_found(_name);
|
||||
if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
||||
vm->NameError(_name);
|
||||
} DISPATCH();
|
||||
TARGET(LOAD_METHOD){
|
||||
PyObject* _0;
|
||||
TOP() = get_unbound_method(TOP(), StrName(byte.arg), &_0, true, true);
|
||||
@ -723,15 +735,18 @@ __NEXT_STEP:;
|
||||
PyObject* _0 = POPX(); // super
|
||||
if(_0 == None) _0 = _t(tp_object);
|
||||
check_non_tagged_type(_0, tp_type);
|
||||
PyObject* _1 = new_type_object(frame->_module, _name, PK_OBJ_GET(Type, _0));
|
||||
PUSH(_1);
|
||||
_curr_class = new_type_object(frame->_module, _name, PK_OBJ_GET(Type, _0));
|
||||
} DISPATCH();
|
||||
TARGET(END_CLASS) {
|
||||
PK_ASSERT(_curr_class != nullptr);
|
||||
_curr_class = nullptr;
|
||||
} DISPATCH();
|
||||
TARGET(END_CLASS) POP(); DISPATCH();
|
||||
TARGET(STORE_CLASS_ATTR){
|
||||
PK_ASSERT(_curr_class != nullptr);
|
||||
StrName _name(byte.arg);
|
||||
PyObject* _0 = POPX();
|
||||
if(is_non_tagged_type(_0, tp_function)){
|
||||
PK_OBJ_GET(Function, _0)._class = TOP();
|
||||
PK_OBJ_GET(Function, _0)._class = _curr_class;
|
||||
}
|
||||
TOP()->attr().set(_name, _0);
|
||||
} DISPATCH();
|
||||
@ -793,8 +808,8 @@ __NEXT_STEP:;
|
||||
} DISPATCH();
|
||||
|
||||
#if !PK_ENABLE_COMPUTED_GOTO
|
||||
static_assert(OP_DEC_GLOBAL == 106);
|
||||
case 107: case 108: case 109: case 110: case 111: case 112: case 113: case 114: case 115: case 116: case 117: case 118: case 119: case 120: case 121: case 122: case 123: case 124: case 125: case 126: case 127: case 128: case 129: case 130: case 131: case 132: case 133: case 134: case 135: case 136: case 137: case 138: case 139: case 140: case 141: case 142: case 143: case 144: case 145: case 146: case 147: case 148: case 149: case 150: case 151: case 152: case 153: case 154: case 155: case 156: case 157: case 158: case 159: case 160: case 161: case 162: case 163: case 164: case 165: case 166: case 167: case 168: case 169: case 170: case 171: case 172: case 173: case 174: case 175: case 176: case 177: case 178: case 179: case 180: case 181: case 182: case 183: case 184: case 185: case 186: case 187: case 188: case 189: case 190: case 191: case 192: case 193: case 194: case 195: case 196: case 197: case 198: case 199: case 200: case 201: case 202: case 203: case 204: case 205: case 206: case 207: case 208: case 209: case 210: case 211: case 212: case 213: case 214: case 215: case 216: case 217: case 218: case 219: case 220: case 221: case 222: case 223: case 224: case 225: case 226: case 227: case 228: case 229: case 230: case 231: case 232: case 233: case 234: case 235: case 236: case 237: case 238: case 239: case 240: case 241: case 242: case 243: case 244: case 245: case 246: case 247: case 248: case 249: case 250: case 251: case 252: case 253: case 254: case 255: FATAL_ERROR(); break;
|
||||
static_assert(OP_DEC_GLOBAL == 107);
|
||||
case 108: case 109: case 110: case 111: case 112: case 113: case 114: case 115: case 116: case 117: case 118: case 119: case 120: case 121: case 122: case 123: case 124: case 125: case 126: case 127: case 128: case 129: case 130: case 131: case 132: case 133: case 134: case 135: case 136: case 137: case 138: case 139: case 140: case 141: case 142: case 143: case 144: case 145: case 146: case 147: case 148: case 149: case 150: case 151: case 152: case 153: case 154: case 155: case 156: case 157: case 158: case 159: case 160: case 161: case 162: case 163: case 164: case 165: case 166: case 167: case 168: case 169: case 170: case 171: case 172: case 173: case 174: case 175: case 176: case 177: case 178: case 179: case 180: case 181: case 182: case 183: case 184: case 185: case 186: case 187: case 188: case 189: case 190: case 191: case 192: case 193: case 194: case 195: case 196: case 197: case 198: case 199: case 200: case 201: case 202: case 203: case 204: case 205: case 206: case 207: case 208: case 209: case 210: case 211: case 212: case 213: case 214: case 215: case 216: case 217: case 218: case 219: case 220: case 221: case 222: case 223: case 224: case 225: case 226: case 227: case 228: case 229: case 230: case 231: case 232: case 233: case 234: case 235: case 236: case 237: case 238: case 239: case 240: case 241: case 242: case 243: case 244: case 245: case 246: case 247: case 248: case 249: case 250: case 251: case 252: case 253: case 254: case 255: FATAL_ERROR(); break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
11
src/expr.cpp
11
src/expr.cpp
@ -127,8 +127,15 @@ namespace pkpy{
|
||||
ctx->emit_(OP_LOAD_FAST, index, line);
|
||||
}else{
|
||||
Opcode op = ctx->level <= 1 ? OP_LOAD_GLOBAL : OP_LOAD_NONLOCAL;
|
||||
// we cannot determine the scope when calling exec()/eval()
|
||||
if(scope == NAME_GLOBAL_UNKNOWN) op = OP_LOAD_NAME;
|
||||
if(ctx->is_compiling_class && scope == NAME_GLOBAL){
|
||||
// if we are compiling a class, we should use OP_LOAD_ATTR_GLOBAL instead of OP_LOAD_GLOBAL
|
||||
// this supports @property.setter
|
||||
op = OP_LOAD_CLASS_GLOBAL;
|
||||
// exec()/eval() won't work with OP_LOAD_ATTR_GLOBAL in class body
|
||||
}else{
|
||||
// we cannot determine the scope when calling exec()/eval()
|
||||
if(scope == NAME_GLOBAL_UNKNOWN) op = OP_LOAD_NAME;
|
||||
}
|
||||
ctx->emit_(op, StrName(name).index, line);
|
||||
}
|
||||
}
|
||||
|
@ -1653,6 +1653,12 @@ void add_module_gc(VM* vm){
|
||||
void VM::post_init(){
|
||||
init_builtins(this);
|
||||
|
||||
bind_method<1>("property", "setter", [](VM* vm, ArgsView args) {
|
||||
Property& self = _CAST(Property&, args[0]);
|
||||
self.setter = args[1];
|
||||
return args[0];
|
||||
});
|
||||
|
||||
// type
|
||||
bind__getitem__(tp_type, [](VM* vm, PyObject* self, PyObject* _){
|
||||
PK_UNUSED(_);
|
||||
|
@ -1192,6 +1192,7 @@ void ManagedHeap::mark() {
|
||||
for(PyObject* obj: vm->s_data) PK_OBJ_MARK(obj);
|
||||
if(_gc_marker_ex) _gc_marker_ex(vm);
|
||||
if(vm->_last_exception) PK_OBJ_MARK(vm->_last_exception);
|
||||
if(vm->_curr_class) PK_OBJ_MARK(vm->_curr_class);
|
||||
if(vm->_c.error != nullptr) PK_OBJ_MARK(vm->_c.error);
|
||||
}
|
||||
|
||||
|
@ -109,3 +109,13 @@ class B(A):
|
||||
# assert B.a == 1 ...bug here
|
||||
assert B.b == 3
|
||||
assert B.c == 4
|
||||
|
||||
class A:
|
||||
x = 1
|
||||
x = x + 1
|
||||
y = 1
|
||||
z = x + y
|
||||
|
||||
assert A.x == 2
|
||||
assert A.y == 1
|
||||
assert A.z == 3
|
||||
|
@ -810,12 +810,29 @@ try:
|
||||
except:
|
||||
pass
|
||||
|
||||
class Vector2:
|
||||
def __init__(self) -> None:
|
||||
self._x = 0
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
return self._x
|
||||
|
||||
@x.setter
|
||||
def x(self, val):
|
||||
self._x = val
|
||||
|
||||
v = Vector2()
|
||||
assert v.x == 0
|
||||
v.x = 10
|
||||
assert v.x == 10
|
||||
|
||||
# /************ module timeit ************/
|
||||
import timeit
|
||||
|
||||
def aaa():
|
||||
for i in range(100):
|
||||
for j in range(100):
|
||||
for i in range(10):
|
||||
for j in range(10):
|
||||
pass
|
||||
|
||||
assert type(timeit.timeit(aaa, 2)) is float
|
||||
|
Loading…
x
Reference in New Issue
Block a user