This commit is contained in:
blueloveTH 2023-07-01 00:33:34 +08:00
parent fb83748e02
commit b13581037d
11 changed files with 123 additions and 60 deletions

View File

@ -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

View File

@ -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: ...

View File

@ -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]);

View File

@ -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;

View File

@ -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());

View File

@ -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;

View File

@ -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;
}

View File

@ -123,7 +123,6 @@ OPCODE(RAISE)
OPCODE(RE_RAISE)
OPCODE(POP_EXCEPTION)
/**************************/
OPCODE(SETUP_DOCSTRING)
OPCODE(FORMAT_STRING)
/**************************/
OPCODE(INC_FAST)

View File

@ -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]));

View File

@ -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); });

View File

@ -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;
}