mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
...
This commit is contained in:
parent
fb83748e02
commit
b13581037d
@ -270,11 +270,8 @@ type.__repr__ = lambda self: "<class '" + self.__name__ + "'>"
|
||||
def help(obj):
|
||||
if hasattr(obj, '__func__'):
|
||||
obj = obj.__func__
|
||||
if hasattr(obj, '__doc__'):
|
||||
print(obj.__doc__)
|
||||
else:
|
||||
print("No docstring found")
|
||||
|
||||
print(obj.__signature__)
|
||||
print(obj.__doc__)
|
||||
|
||||
del __f
|
||||
|
||||
|
12
src/c.pyi
12
src/c.pyi
@ -65,12 +65,24 @@ class void_p:
|
||||
def set_base_offset(self, offset: str) -> None: ...
|
||||
|
||||
class struct:
|
||||
@overload
|
||||
def __init__(self, size: int): ...
|
||||
@overload
|
||||
def __init__(self, p: 'void_p', size: int): ...
|
||||
@overload
|
||||
def __init__(self, s: str): ...
|
||||
@overload
|
||||
def __init__(self, b: bytes): ...
|
||||
|
||||
def addr(self) -> 'void_p': ...
|
||||
def copy(self) -> 'struct': ...
|
||||
def size(self) -> int: ...
|
||||
def __eq__(self, other: 'struct') -> bool: ...
|
||||
def __ne__(self, other: 'struct') -> bool: ...
|
||||
|
||||
def to_string(self) -> str: ...
|
||||
def to_bytes(self) -> bytes: ...
|
||||
|
||||
def read_char(self, offset=0) -> int: ...
|
||||
def read_uchar(self, offset=0) -> int: ...
|
||||
def read_short(self, offset=0) -> int: ...
|
||||
|
@ -11,7 +11,6 @@ inline PyObject* VM::_run_top_frame(){
|
||||
DEF_SNAME(set);
|
||||
DEF_SNAME(__enter__);
|
||||
DEF_SNAME(__exit__);
|
||||
DEF_SNAME(__doc__);
|
||||
|
||||
FrameId frame = top_frame();
|
||||
const int base_id = frame.index;
|
||||
@ -674,9 +673,6 @@ __NEXT_STEP:;
|
||||
TARGET(RE_RAISE) _raise(); DISPATCH();
|
||||
TARGET(POP_EXCEPTION) _last_exception = POPX(); DISPATCH();
|
||||
/*****************************************/
|
||||
TARGET(SETUP_DOCSTRING)
|
||||
TOP()->attr().set(__doc__, co_consts[byte.arg]);
|
||||
DISPATCH();
|
||||
TARGET(FORMAT_STRING) {
|
||||
_0 = POPX();
|
||||
const Str& spec = CAST(Str&, co_consts[byte.arg]);
|
||||
|
57
src/cffi.h
57
src/cffi.h
@ -191,7 +191,7 @@ struct C99Struct{
|
||||
char* p;
|
||||
int size;
|
||||
|
||||
void _init(int new_size){
|
||||
C99Struct(int new_size){
|
||||
this->size = new_size;
|
||||
if(size <= INLINE_SIZE){
|
||||
p = _inlined;
|
||||
@ -201,27 +201,46 @@ struct C99Struct{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
C99Struct(const T& data){
|
||||
C99Struct(const T& data): C99Struct(sizeof(T)){
|
||||
static_assert(std::is_pod_v<T>);
|
||||
static_assert(!std::is_pointer_v<T>);
|
||||
_init(sizeof(T));
|
||||
memcpy(p, &data, this->size);
|
||||
}
|
||||
|
||||
C99Struct() { p = _inlined; }
|
||||
C99Struct(void* p, int size){
|
||||
_init(size);
|
||||
if(p!=nullptr) memcpy(this->p, p, size);
|
||||
C99Struct(void* p, int size): C99Struct(size){
|
||||
if(p != nullptr) memcpy(this->p, p, size);
|
||||
}
|
||||
|
||||
C99Struct(const C99Struct& other): C99Struct(other.p, other.size){}
|
||||
|
||||
~C99Struct(){ if(p!=_inlined) free(p); }
|
||||
|
||||
C99Struct(const C99Struct& other){
|
||||
_init(other.size);
|
||||
memcpy(p, other.p, size);
|
||||
}
|
||||
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type){
|
||||
vm->bind_default_constructor<C99Struct>(type);
|
||||
vm->bind_constructor<-1>(type, [](VM* vm, ArgsView args){
|
||||
if(args.size() == 1+1){
|
||||
if(is_int(args[1])){
|
||||
int size = _CAST(int, args[1]);
|
||||
return VAR_T(C99Struct, size);
|
||||
}
|
||||
if(is_non_tagged_type(args[1], vm->tp_str)){
|
||||
const Str& s = _CAST(Str&, args[1]);
|
||||
return VAR_T(C99Struct, (void*)s.data, s.size);
|
||||
}
|
||||
if(is_non_tagged_type(args[1], vm->tp_bytes)){
|
||||
const Bytes& b = _CAST(Bytes&, args[1]);
|
||||
return VAR_T(C99Struct, (void*)b.data(), b.size());
|
||||
}
|
||||
vm->TypeError("expected int, str or bytes");
|
||||
return vm->None;
|
||||
}
|
||||
if(args.size() == 1+2){
|
||||
void* p = CAST(void*, args[1]);
|
||||
int size = CAST(int, args[2]);
|
||||
return VAR_T(C99Struct, p, size);
|
||||
}
|
||||
vm->TypeError("expected 1 or 2 arguments");
|
||||
return vm->None;
|
||||
});
|
||||
|
||||
vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){
|
||||
C99Struct& self = _CAST(C99Struct&, args[0]);
|
||||
@ -238,6 +257,18 @@ struct C99Struct{
|
||||
return VAR_T(C99Struct, self);
|
||||
});
|
||||
|
||||
vm->bind_method<0>(type, "to_string", [](VM* vm, ArgsView args){
|
||||
C99Struct& self = _CAST(C99Struct&, args[0]);
|
||||
return VAR(Str(self.p, self.size));
|
||||
});
|
||||
|
||||
vm->bind_method<0>(type, "to_bytes", [](VM* vm, ArgsView args){
|
||||
C99Struct& self = _CAST(C99Struct&, args[0]);
|
||||
std::vector<char> buffer(self.size);
|
||||
memcpy(buffer.data(), self.p, self.size);
|
||||
return VAR(Bytes(std::move(buffer)));
|
||||
});
|
||||
|
||||
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
|
||||
C99Struct& self = _CAST(C99Struct&, lhs);
|
||||
if(!is_non_tagged_type(rhs, C99Struct::_type(vm))) return vm->NotImplemented;
|
||||
|
@ -972,9 +972,9 @@ __SUBSCR_END:
|
||||
}
|
||||
|
||||
void compile_function(const std::vector<Expr_>& decorators={}){
|
||||
Str decl_name;
|
||||
const char* _start = curr().start;
|
||||
consume(TK("@id"));
|
||||
decl_name = prev().str();
|
||||
Str decl_name = prev().str();
|
||||
FuncDecl_ decl = push_f_context(decl_name);
|
||||
consume(TK("("));
|
||||
if (!match(TK(")"))) {
|
||||
@ -982,6 +982,8 @@ __SUBSCR_END:
|
||||
consume(TK(")"));
|
||||
}
|
||||
if(match(TK("->"))) consume_type_hints();
|
||||
const char* _end = curr().start;
|
||||
decl->signature = Str(_start, _end-_start);
|
||||
compile_block_body();
|
||||
pop_context();
|
||||
|
||||
@ -994,10 +996,11 @@ __SUBSCR_END:
|
||||
docstring = c;
|
||||
}
|
||||
}
|
||||
ctx()->emit(OP_LOAD_FUNCTION, ctx()->add_func_decl(decl), prev().line);
|
||||
if(docstring != nullptr){
|
||||
ctx()->emit(OP_SETUP_DOCSTRING, ctx()->add_const(docstring), prev().line);
|
||||
decl->docstring = PK_OBJ_GET(Str, docstring);
|
||||
}
|
||||
ctx()->emit(OP_LOAD_FUNCTION, ctx()->add_func_decl(decl), prev().line);
|
||||
|
||||
// add decorators
|
||||
for(auto it=decorators.rbegin(); it!=decorators.rend(); ++it){
|
||||
(*it)->emit(ctx());
|
||||
|
18
src/main.cpp
18
src/main.cpp
@ -7,11 +7,25 @@
|
||||
|
||||
int main(int argc, char** argv){
|
||||
pkpy::VM* vm = pkpy_new_vm();
|
||||
pkpy::PyObject* input_f = vm->bind_builtin_func<0>("input", [](pkpy::VM* vm, pkpy::ArgsView args){
|
||||
vm->bind_builtin_func<0>("input", [](pkpy::VM* vm, pkpy::ArgsView args){
|
||||
// pkpy::getline() has bugs for PIPE input on Windows
|
||||
return VAR(pkpy::getline());
|
||||
});
|
||||
vm->_modules["sys"]->attr("stdin")->attr().set("readline", input_f);
|
||||
|
||||
// vm->bind(vm->builtins, "test_sum(a: int, b: int, *args, x=5)",
|
||||
// "Test function for summing up numbers.",
|
||||
// [](pkpy::VM* vm, pkpy::ArgsView args){
|
||||
// PK_ASSERT(args.size() == 4);
|
||||
// int sum = 0;
|
||||
// sum += pkpy::CAST(int, args[0]);
|
||||
// sum += pkpy::CAST(int, args[1]);
|
||||
// pkpy::Tuple& t = pkpy::CAST(pkpy::Tuple&, args[2]);
|
||||
// for(pkpy::PyObject* ob: t){
|
||||
// sum += pkpy::CAST(int, ob);
|
||||
// }
|
||||
// sum *= pkpy::CAST(int, args[3]);
|
||||
// return VAR(sum);
|
||||
// });
|
||||
if(argc == 1){
|
||||
pkpy::REPL* repl = pkpy_new_repl(vm);
|
||||
bool need_more_lines = false;
|
||||
|
@ -30,6 +30,9 @@ struct FuncDecl {
|
||||
int starred_arg = -1; // index in co->varnames, -1 if no *arg
|
||||
int starred_kwarg = -1; // index in co->varnames, -1 if no **kwarg
|
||||
bool nested = false; // whether this function is nested
|
||||
|
||||
Str signature; // signature of this function
|
||||
Str docstring; // docstring of this function
|
||||
void _gc_mark() const;
|
||||
};
|
||||
|
||||
@ -43,7 +46,6 @@ struct NativeFunc {
|
||||
|
||||
// new style decl-based call
|
||||
FuncDecl_ decl;
|
||||
const char* docstring;
|
||||
|
||||
using UserData = char[32];
|
||||
UserData _userdata;
|
||||
@ -75,11 +77,10 @@ struct NativeFunc {
|
||||
_has_userdata = false;
|
||||
}
|
||||
|
||||
NativeFunc(NativeFuncC f, FuncDecl_ decl, const char* docstring){
|
||||
NativeFunc(NativeFuncC f, FuncDecl_ decl){
|
||||
this->f = f;
|
||||
this->argc = -1;
|
||||
this->decl = decl;
|
||||
this->docstring = docstring;
|
||||
_has_userdata = false;
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,6 @@ OPCODE(RAISE)
|
||||
OPCODE(RE_RAISE)
|
||||
OPCODE(POP_EXCEPTION)
|
||||
/**************************/
|
||||
OPCODE(SETUP_DOCSTRING)
|
||||
OPCODE(FORMAT_STRING)
|
||||
/**************************/
|
||||
OPCODE(INC_FAST)
|
||||
|
@ -559,16 +559,6 @@ inline void init_builtins(VM* _vm) {
|
||||
return VAR(ss.str());
|
||||
});
|
||||
|
||||
_vm->bind_method<0>("str", "to_c_str", [](VM* vm, ArgsView args){
|
||||
const Str& self = _CAST(Str&, args[0]);
|
||||
return VAR(self.c_str_dup());
|
||||
});
|
||||
|
||||
_vm->bind_func<1>("str", "from_c_str", [](VM* vm, ArgsView args){
|
||||
char* p = CAST(char*, args[0]);
|
||||
return VAR(Str(p));
|
||||
});
|
||||
|
||||
_vm->bind_method<0>("str", "lower", [](VM* vm, ArgsView args) {
|
||||
const Str& self = _CAST(Str&, args[0]);
|
||||
return VAR(self.lower());
|
||||
@ -907,21 +897,6 @@ inline void init_builtins(VM* _vm) {
|
||||
return VAR(Str(self.str()));
|
||||
});
|
||||
|
||||
_vm->bind_method<0>("bytes", "to_char_array", [](VM* vm, ArgsView args) {
|
||||
const Bytes& self = _CAST(Bytes&, args[0]);
|
||||
void* buffer = malloc(self.size());
|
||||
memcpy(buffer, self.data(), self.size());
|
||||
return VAR_T(VoidP, buffer);
|
||||
});
|
||||
|
||||
_vm->bind_func<2>("bytes", "from_char_array", [](VM* vm, ArgsView args) {
|
||||
const VoidP& data = _CAST(VoidP&, args[0]);
|
||||
int size = CAST(int, args[1]);
|
||||
std::vector<char> buffer(size);
|
||||
memcpy(buffer.data(), data.ptr, size);
|
||||
return VAR(Bytes(std::move(buffer)));
|
||||
});
|
||||
|
||||
_vm->bind__eq__(_vm->tp_bytes, [](VM* vm, PyObject* lhs, PyObject* rhs) {
|
||||
if(!is_non_tagged_type(rhs, vm->tp_bytes)) return vm->NotImplemented;
|
||||
return VAR(_CAST(Bytes&, lhs) == _CAST(Bytes&, rhs));
|
||||
@ -1175,6 +1150,28 @@ inline void init_builtins(VM* _vm) {
|
||||
vm->TypeError("property() takes at most 2 arguments");
|
||||
return vm->None;
|
||||
});
|
||||
|
||||
_vm->_t(_vm->tp_function)->attr().set("__doc__", _vm->property([](VM* vm, ArgsView args) {
|
||||
Function& func = _CAST(Function&, args[0]);
|
||||
return VAR(func.decl->docstring);
|
||||
}));
|
||||
|
||||
_vm->_t(_vm->tp_native_func)->attr().set("__doc__", _vm->property([](VM* vm, ArgsView args) {
|
||||
NativeFunc& func = _CAST(NativeFunc&, args[0]);
|
||||
if(func.decl != nullptr) return VAR(func.decl->docstring);
|
||||
return VAR("");
|
||||
}));
|
||||
|
||||
_vm->_t(_vm->tp_function)->attr().set("__signature__", _vm->property([](VM* vm, ArgsView args) {
|
||||
Function& func = _CAST(Function&, args[0]);
|
||||
return VAR(func.decl->signature);
|
||||
}));
|
||||
|
||||
_vm->_t(_vm->tp_native_func)->attr().set("__signature__", _vm->property([](VM* vm, ArgsView args) {
|
||||
NativeFunc& func = _CAST(NativeFunc&, args[0]);
|
||||
if(func.decl != nullptr) return VAR(func.decl->signature);
|
||||
return VAR("unknown(*args, **kwargs)");
|
||||
}));
|
||||
|
||||
RangeIter::register_class(_vm, _vm->builtins);
|
||||
ArrayIter::register_class(_vm, _vm->builtins);
|
||||
@ -1288,10 +1285,8 @@ inline void add_module_sys(VM* vm){
|
||||
|
||||
PyObject* stdout_ = vm->heap.gcnew<DummyInstance>(vm->tp_object, {});
|
||||
PyObject* stderr_ = vm->heap.gcnew<DummyInstance>(vm->tp_object, {});
|
||||
PyObject* stdin_ = vm->heap.gcnew<DummyInstance>(vm->tp_object, {});
|
||||
vm->setattr(mod, "stdout", stdout_);
|
||||
vm->setattr(mod, "stderr", stderr_);
|
||||
vm->setattr(mod, "stdin", stdin_);
|
||||
|
||||
vm->bind_func<1>(stdout_, "write", [](VM* vm, ArgsView args) {
|
||||
vm->_stdout(vm, CAST(Str&, args[0]));
|
||||
|
11
src/str.h
11
src/str.h
@ -228,6 +228,17 @@ struct Str{
|
||||
return Str(copy);
|
||||
}
|
||||
|
||||
Str strip() const {
|
||||
std::string copy(data, size);
|
||||
copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](char c) {
|
||||
return c != ' ' && c != '\t' && c != '\r' && c != '\n';
|
||||
}));
|
||||
copy.erase(std::find_if(copy.rbegin(), copy.rend(), [](char c) {
|
||||
return c != ' ' && c != '\t' && c != '\r' && c != '\n';
|
||||
}).base(), copy.end());
|
||||
return Str(copy);
|
||||
}
|
||||
|
||||
Str lower() const{
|
||||
std::string copy(data, size);
|
||||
std::transform(copy.begin(), copy.end(), copy.begin(), [](unsigned char c){ return std::tolower(c); });
|
||||
|
6
src/vm.h
6
src/vm.h
@ -1561,7 +1561,11 @@ inline PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring,
|
||||
throw std::runtime_error("expected 1 function declaration");
|
||||
}
|
||||
FuncDecl_ decl = co->func_decls[0];
|
||||
PyObject* f_obj = VAR(NativeFunc(fn, decl, docstring));
|
||||
decl->signature = Str(sig);
|
||||
if(docstring != nullptr){
|
||||
decl->docstring = Str(docstring).strip();
|
||||
}
|
||||
PyObject* f_obj = VAR(NativeFunc(fn, decl));
|
||||
obj->attr().set(decl->code->name, f_obj);
|
||||
return f_obj;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user