mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
0.3.0
This commit is contained in:
parent
1999726c18
commit
bc17e61463
@ -60,7 +60,7 @@ public:
|
|||||||
rules[TK("%")] = { nullptr, METHOD(exprBinaryOp), PREC_FACTOR };
|
rules[TK("%")] = { nullptr, METHOD(exprBinaryOp), PREC_FACTOR };
|
||||||
rules[TK("+")] = { nullptr, METHOD(exprBinaryOp), PREC_TERM };
|
rules[TK("+")] = { nullptr, METHOD(exprBinaryOp), PREC_TERM };
|
||||||
rules[TK("-")] = { METHOD(exprUnaryOp), METHOD(exprBinaryOp), PREC_TERM };
|
rules[TK("-")] = { METHOD(exprUnaryOp), METHOD(exprBinaryOp), PREC_TERM };
|
||||||
rules[TK("*")] = { nullptr, METHOD(exprBinaryOp), PREC_FACTOR };
|
rules[TK("*")] = { METHOD(exprUnaryOp), METHOD(exprBinaryOp), PREC_FACTOR };
|
||||||
rules[TK("/")] = { nullptr, METHOD(exprBinaryOp), PREC_FACTOR };
|
rules[TK("/")] = { nullptr, METHOD(exprBinaryOp), PREC_FACTOR };
|
||||||
rules[TK("//")] = { nullptr, METHOD(exprBinaryOp), PREC_FACTOR };
|
rules[TK("//")] = { nullptr, METHOD(exprBinaryOp), PREC_FACTOR };
|
||||||
rules[TK("**")] = { nullptr, METHOD(exprBinaryOp), PREC_EXPONENT };
|
rules[TK("**")] = { nullptr, METHOD(exprBinaryOp), PREC_EXPONENT };
|
||||||
@ -450,6 +450,7 @@ public:
|
|||||||
case TK("-"): emitCode(OP_UNARY_NEGATIVE); break;
|
case TK("-"): emitCode(OP_UNARY_NEGATIVE); break;
|
||||||
case TK("not"): emitCode(OP_UNARY_NOT); break;
|
case TK("not"): emitCode(OP_UNARY_NOT); break;
|
||||||
case TK("&"): emitCode(OP_UNARY_REF); break;
|
case TK("&"): emitCode(OP_UNARY_REF); break;
|
||||||
|
case TK("*"): emitCode(OP_UNARY_DEREF); break;
|
||||||
default: UNREACHABLE();
|
default: UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
src/obj.h
11
src/obj.h
@ -10,11 +10,10 @@ const _Int _Int_MAX_NEG = -9223372036854775807LL;
|
|||||||
const _Float _FLOAT_INF_POS = INFINITY;
|
const _Float _FLOAT_INF_POS = INFINITY;
|
||||||
const _Float _FLOAT_INF_NEG = -INFINITY;
|
const _Float _FLOAT_INF_NEG = -INFINITY;
|
||||||
|
|
||||||
#define PK_VERSION "0.2.9"
|
#define PK_VERSION "0.3.0"
|
||||||
|
|
||||||
class CodeObject;
|
class CodeObject;
|
||||||
class BasePointer;
|
class BasePointer;
|
||||||
class Pointer;
|
|
||||||
class VM;
|
class VM;
|
||||||
class Frame;
|
class Frame;
|
||||||
class PkExportedResource {};
|
class PkExportedResource {};
|
||||||
@ -23,12 +22,6 @@ typedef std::shared_ptr<const BasePointer> _Pointer;
|
|||||||
typedef PyVar (*_CppFunc)(VM*, const pkpy::ArgList&);
|
typedef PyVar (*_CppFunc)(VM*, const pkpy::ArgList&);
|
||||||
typedef std::shared_ptr<CodeObject> _Code;
|
typedef std::shared_ptr<CodeObject> _Code;
|
||||||
|
|
||||||
struct Pointer {
|
|
||||||
Frame* frame; // the frame that created this pointer
|
|
||||||
_Pointer ptr; // the internal pointer
|
|
||||||
Pointer(Frame* frame, _Pointer ptr) : frame(frame), ptr(ptr) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Function {
|
struct Function {
|
||||||
_Str name;
|
_Str name;
|
||||||
_Code code;
|
_Code code;
|
||||||
@ -80,7 +73,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<Function> _Func;
|
typedef std::shared_ptr<Function> _Func;
|
||||||
typedef std::variant<_Int,_Float,bool,_Str,PyVarList,_CppFunc,_Func,std::shared_ptr<_Iterator>,_BoundedMethod,_Range,_Slice,_Pointer,Pointer> _Value;
|
typedef std::variant<_Int,_Float,bool,_Str,PyVarList,_CppFunc,_Func,std::shared_ptr<_Iterator>,_BoundedMethod,_Range,_Slice,_Pointer> _Value;
|
||||||
|
|
||||||
const int _SIZEOF_VALUE = sizeof(_Value);
|
const int _SIZEOF_VALUE = sizeof(_Value);
|
||||||
|
|
||||||
|
@ -60,5 +60,6 @@ OPCODE(BUILD_STRING) // arg is the expr count, build a string from the to
|
|||||||
|
|
||||||
OPCODE(GOTO)
|
OPCODE(GOTO)
|
||||||
OPCODE(UNARY_REF) // for &
|
OPCODE(UNARY_REF) // for &
|
||||||
|
OPCODE(UNARY_DEREF) // for *
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -56,23 +56,6 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
return vm->PyStr(tvm->readStdin());
|
return vm->PyStr(tvm->readStdin());
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("pointer", "set", [](VM* vm, const pkpy::ArgList& args) {
|
|
||||||
vm->__checkArgSize(args, 2, true);
|
|
||||||
Pointer& p = std::get<Pointer>(args[0]->_native);
|
|
||||||
// this check is unsafe, but it's the best we can do
|
|
||||||
if(!vm->__isFrameValid(p.frame)) vm->nullPointerError();
|
|
||||||
p.ptr->set(vm, p.frame, args[1]);
|
|
||||||
return vm->None;
|
|
||||||
});
|
|
||||||
|
|
||||||
_vm->bindMethod("pointer", "get", [](VM* vm, const pkpy::ArgList& args) {
|
|
||||||
vm->__checkArgSize(args, 1, true);
|
|
||||||
Pointer& p = std::get<Pointer>(args[0]->_native);
|
|
||||||
// this check is unsafe, but it's the best we can do
|
|
||||||
if(!vm->__isFrameValid(p.frame)) vm->nullPointerError();
|
|
||||||
return p.ptr->get(vm, p.frame);
|
|
||||||
});
|
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("eval", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("eval", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->__checkArgSize(args, 1);
|
||||||
const _Str& expr = vm->PyStr_AS_C(args[0]);
|
const _Str& expr = vm->PyStr_AS_C(args[0]);
|
||||||
|
@ -55,6 +55,16 @@ struct CompoundPointer : BasePointer {
|
|||||||
CompoundPointer(std::vector<_Pointer> pointers) : pointers(pointers) {}
|
CompoundPointer(std::vector<_Pointer> pointers) : pointers(pointers) {}
|
||||||
CompoundPointer(std::vector<_Pointer>&& pointers) : pointers(pointers) {}
|
CompoundPointer(std::vector<_Pointer>&& pointers) : pointers(pointers) {}
|
||||||
|
|
||||||
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
|
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||||
|
void del(VM* vm, Frame* frame) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UserPointer : BasePointer {
|
||||||
|
const _Pointer p;
|
||||||
|
Frame* frame;
|
||||||
|
UserPointer(_Pointer p, Frame* frame) : p(p), frame(frame) {}
|
||||||
|
|
||||||
PyVar get(VM* vm, Frame* frame) const;
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||||
void del(VM* vm, Frame* frame) const;
|
void del(VM* vm, Frame* frame) const;
|
||||||
|
31
src/vm.h
31
src/vm.h
@ -209,8 +209,17 @@ private:
|
|||||||
} break;
|
} break;
|
||||||
case OP_UNARY_REF:
|
case OP_UNARY_REF:
|
||||||
{
|
{
|
||||||
_Pointer p = PyPointer_AS_C(frame->__pop());
|
// _pointer to pointer
|
||||||
frame->push(newObject(_tp_user_pointer, Pointer(frame, p)));
|
const _Pointer& p = PyPointer_AS_C(frame->__pop());
|
||||||
|
_Pointer up = std::make_shared<UserPointer>(p, frame);
|
||||||
|
frame->push(newObject(_tp_user_pointer, std::move(up)));
|
||||||
|
} break;
|
||||||
|
case OP_UNARY_DEREF:
|
||||||
|
{
|
||||||
|
// pointer to _pointer
|
||||||
|
PyVar obj = frame->popValue(this);
|
||||||
|
__checkType(obj, _tp_user_pointer);
|
||||||
|
frame->push(PyPointer(std::get<_Pointer>(obj->_native)));
|
||||||
} break;
|
} break;
|
||||||
case OP_POP_JUMP_IF_FALSE:
|
case OP_POP_JUMP_IF_FALSE:
|
||||||
if(!PyBool_AS_C(asBool(frame->popValue(this)))) frame->jump(byte.arg);
|
if(!PyBool_AS_C(asBool(frame->popValue(this)))) frame->jump(byte.arg);
|
||||||
@ -941,6 +950,24 @@ void CompoundPointer::del(VM* vm, Frame* frame) const{
|
|||||||
for (auto& ptr : pointers) ptr->del(vm, frame);
|
for (auto& ptr : pointers) ptr->del(vm, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyVar UserPointer::get(VM* vm, Frame* frame) const{
|
||||||
|
frame = this->frame;
|
||||||
|
// this check is unsafe, but it's the best we can do
|
||||||
|
if(!vm->__isFrameValid(frame)) vm->nullPointerError();
|
||||||
|
return p->get(vm, frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserPointer::set(VM* vm, Frame* frame, PyVar val) const{
|
||||||
|
frame = this->frame;
|
||||||
|
// this check is unsafe, but it's the best we can do
|
||||||
|
if(!vm->__isFrameValid(frame)) vm->nullPointerError();
|
||||||
|
p->set(vm, frame, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserPointer::del(VM* vm, Frame* frame) const{
|
||||||
|
vm->typeError("delete is unsupported");
|
||||||
|
}
|
||||||
|
|
||||||
/***** Frame's Impl *****/
|
/***** Frame's Impl *****/
|
||||||
inline PyVar Frame::__deref_pointer(VM* vm, PyVar v){
|
inline PyVar Frame::__deref_pointer(VM* vm, PyVar v){
|
||||||
if(v->isType(vm->_tp_pointer)) return vm->PyPointer_AS_C(v)->get(vm, this);
|
if(v->isType(vm->_tp_pointer)) return vm->PyPointer_AS_C(v)->get(vm, this);
|
||||||
|
19
tests/pointer.py
Normal file
19
tests/pointer.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
a = 1
|
||||||
|
assert a == 1
|
||||||
|
assert *&a == 1
|
||||||
|
b = &a
|
||||||
|
*b = 2
|
||||||
|
assert a == 2
|
||||||
|
|
||||||
|
def swap(a,b):
|
||||||
|
t = *a
|
||||||
|
*a = *b
|
||||||
|
*b = t
|
||||||
|
|
||||||
|
def f():
|
||||||
|
a,b = 5,6
|
||||||
|
swap(&a,&b)
|
||||||
|
assert a == 6
|
||||||
|
assert b == 5
|
||||||
|
|
||||||
|
f()
|
Loading…
x
Reference in New Issue
Block a user