mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 19:40:18 +00:00
up
This commit is contained in:
parent
2a84911862
commit
0871b627ed
@ -64,6 +64,7 @@ typedef struct pk_VM {
|
||||
PyVar last_retval;
|
||||
// registers
|
||||
PyVar reg[8];
|
||||
PyVar sysreg[8];
|
||||
|
||||
PyObject* __curr_class;
|
||||
PyObject* __cached_object_new;
|
||||
|
@ -48,27 +48,28 @@ int py_le(const py_Ref, const py_Ref);
|
||||
int py_hash(const py_Ref, int64_t* out);
|
||||
|
||||
/* py_var */
|
||||
void py_new_int(py_Ref, int64_t);
|
||||
void py_new_float(py_Ref, double);
|
||||
void py_new_bool(py_Ref, bool);
|
||||
void py_new_str(py_Ref, const char*);
|
||||
void py_new_strn(py_Ref, const char*, int);
|
||||
void py_new_fstr(py_Ref, const char*, ...);
|
||||
void py_new_bytes(py_Ref, const uint8_t*, int);
|
||||
void py_new_none(py_Ref);
|
||||
void py_new_null(py_Ref);
|
||||
void py_newint(py_Ref, int64_t);
|
||||
void py_newfloat(py_Ref, double);
|
||||
void py_newbool(py_Ref, bool);
|
||||
void py_newstr(py_Ref, const char*);
|
||||
void py_newstrn(py_Ref, const char*, int);
|
||||
// void py_newfstr(py_Ref, const char*, ...);
|
||||
void py_newbytes(py_Ref, const uint8_t*, int);
|
||||
void py_newnone(py_Ref);
|
||||
void py_newnull(py_Ref);
|
||||
|
||||
void py_new_tuple(PyVar, int);
|
||||
void py_newtuple(py_Ref, int);
|
||||
|
||||
// new style decl-based function
|
||||
void py_new_function(py_Ref, py_CFunction, const char* sig, BindType bt);
|
||||
void py_new_function2(py_Ref, py_CFunction, const char* sig, BindType bt, const char* docstring, const py_Ref userdata);
|
||||
void py_newfunction(py_Ref, py_CFunction, const char* sig, BindType bt);
|
||||
void py_newfunction2(py_Ref, py_CFunction, const char* sig, BindType bt, const char* docstring, const py_Ref userdata);
|
||||
// old style argc-based function
|
||||
void py_new_nativefunc(py_Ref, py_CFunction, int argc, BindType bt);
|
||||
void py_new_nativefunc2(py_Ref, py_CFunction, int argc, BindType bt, const char* docstring, const py_Ref userdata);
|
||||
void py_newnativefunc(py_Ref, py_CFunction, int argc, BindType bt);
|
||||
void py_newnativefunc2(py_Ref, py_CFunction, int argc, BindType bt, const char* docstring, const py_Ref userdata);
|
||||
|
||||
|
||||
py_Ref py_new_module(const char* name);
|
||||
py_Ref py_newmodule(const char* name, const char* package);
|
||||
py_Ref py_getmodule(const char* name);
|
||||
const py_Ref py_import(const char* name);
|
||||
|
||||
#define py_isnull(self) ((self)->type == 0)
|
||||
@ -84,19 +85,25 @@ void py_setslot(py_Ref self, int i, const py_Ref val);
|
||||
/// Returns a reference to the i-th slot of the object.
|
||||
py_Ref py_getslot(const py_Ref self, int i);
|
||||
|
||||
/// Sets the attribute of the object to the given value.
|
||||
/// This is equivalent to `self.name = val`.
|
||||
/// Equivalent to `self.name = val`.
|
||||
/// Returns 0 | err
|
||||
int py_setattr(py_Ref self, py_Name name, const py_Ref val);
|
||||
|
||||
/// Gets the attribute of the object.
|
||||
/// This is equivalent to `self.name`.
|
||||
/// Equivalent to `self.name`.
|
||||
/// Returns 0 | err
|
||||
int py_getattr(const py_Ref self, py_Name name, py_Ref out);
|
||||
|
||||
/// Returns a reference to the i-th object in the stack.
|
||||
/// For example, `py_stackref(-1)` refers to the top of the stack.
|
||||
py_Ref py_stackref(int i);
|
||||
/// Returns a reference to the i-th object from the top of the stack.
|
||||
/// i should be negative, e.g. (-1) means TOS.
|
||||
py_Ref py_stack(int i);
|
||||
/// Returns a reference to the i-th register.
|
||||
py_Ref py_reg(int i);
|
||||
/// Returns a reference to the i-th system register.
|
||||
py_Ref py_sysreg(int i);
|
||||
/// Prepares a push and returns an uninitialized reference.
|
||||
py_Ref py_push();
|
||||
|
||||
|
||||
/// Pushes the object to the stack.
|
||||
void py_pushref(const py_Ref src);
|
||||
/// Pops the object from the stack.
|
||||
@ -109,13 +116,39 @@ void py_copyref(const py_Ref src, py_Ref dst);
|
||||
py_Ref py_tuple__getitem(const py_Ref self, int i);
|
||||
void py_tuple__setitem(py_Ref self, int i, const py_Ref val);
|
||||
int py_tuple__len(const py_Ref self);
|
||||
bool py_tuple__contains(const py_Ref self, const py_Ref val);
|
||||
|
||||
// unchecked functions, if self is not a list, the behavior is undefined
|
||||
py_Ref py_list__getitem(const py_Ref self, int i);
|
||||
void py_list__setitem(py_Ref self, int i, const py_Ref val);
|
||||
void py_list__delitem(py_Ref self, int i);
|
||||
int py_list__len(const py_Ref self);
|
||||
bool py_list__contains(const py_Ref self, const py_Ref val);
|
||||
void py_list__append(py_Ref self, const py_Ref val);
|
||||
void py_list__extend(py_Ref self, const py_Ref begin, const py_Ref end);
|
||||
void py_list__clear(py_Ref self);
|
||||
void py_list__insert(py_Ref self, int i, const py_Ref val);
|
||||
|
||||
// unchecked functions, if self is not a dict, the behavior is undefined
|
||||
int py_dict__len(const py_Ref self);
|
||||
bool py_dict__contains(const py_Ref self, const py_Ref key);
|
||||
py_Ref py_dict__getitem(const py_Ref self, const py_Ref key);
|
||||
void py_dict__setitem(py_Ref self, const py_Ref key, const py_Ref val);
|
||||
void py_dict__delitem(py_Ref self, const py_Ref key);
|
||||
void py_dict__clear(py_Ref self);
|
||||
|
||||
int py_str(const py_Ref, py_Str* out);
|
||||
int py_repr(const py_Ref, py_Str* out);
|
||||
|
||||
int py_toint(py_Ref, int64_t* out);
|
||||
int py_tofloat(py_Ref, double* out);
|
||||
int py_tostr(py_Ref, py_Str** out);
|
||||
int py_tobool(py_Ref, bool* out);
|
||||
|
||||
bool py_istype(const py_Ref, Type);
|
||||
bool py_isinstance(const py_Ref obj, Type type);
|
||||
bool py_issubclass(Type derived, Type base);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -34,53 +34,50 @@ void pk_TypeInfo__dtor(pk_TypeInfo *self){
|
||||
c11_vector__dtor(&self->annotated_fields);
|
||||
}
|
||||
|
||||
static int _hello(const py_Ref args, int argc){
|
||||
return 0;
|
||||
}
|
||||
// static int _py_print(const py_Ref args, int argc){
|
||||
// int length = py_tuple__len(args+0);
|
||||
// py_Str* sep;
|
||||
// py_Str* end;
|
||||
|
||||
// print(*args, sep=' ', end='\n')
|
||||
static int _py_print(const py_Ref args, int argc){
|
||||
int length = py_tuple__len(args+0);
|
||||
py_Str* sep;
|
||||
py_Str* end;
|
||||
// int err;
|
||||
// err = py_tostr(args+1, &sep);
|
||||
// if(err) return err;
|
||||
// err = py_tostr(args+2, &end);
|
||||
// if(err) return err;
|
||||
|
||||
int err;
|
||||
err = py_tostr(args+1, &sep);
|
||||
if(err) return err;
|
||||
err = py_tostr(args+2, &end);
|
||||
if(err) return err;
|
||||
// pk_SStream ss;
|
||||
// pk_SStream__ctor(&ss);
|
||||
|
||||
pk_SStream ss;
|
||||
pk_SStream__ctor(&ss);
|
||||
|
||||
for(int i=0; i<length; i++){
|
||||
const py_Ref item = py_tuple__getitem(args+0, i);
|
||||
py_Str tmp;
|
||||
int err = py_str(item, &tmp);
|
||||
if(!err){
|
||||
pk_SStream__write_Str(&ss, &tmp);
|
||||
py_Str__dtor(&tmp);
|
||||
if(i != length-1){
|
||||
pk_SStream__write_Str(&ss, sep);
|
||||
}
|
||||
}else{
|
||||
py_Str__dtor(&tmp);
|
||||
pk_SStream__dtor(&ss);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
pk_SStream__write_Str(&ss, end);
|
||||
py_Str out = pk_SStream__submit(&ss);
|
||||
pk_current_vm->_stdout(py_Str__data(&out));
|
||||
py_Str__dtor(&out);
|
||||
return 0;
|
||||
}
|
||||
// for(int i=0; i<length; i++){
|
||||
// const py_Ref item = py_tuple__getitem(args+0, i);
|
||||
// py_Str tmp;
|
||||
// int err = py_str(item, &tmp);
|
||||
// if(!err){
|
||||
// pk_SStream__write_Str(&ss, &tmp);
|
||||
// py_Str__dtor(&tmp);
|
||||
// if(i != length-1){
|
||||
// pk_SStream__write_Str(&ss, sep);
|
||||
// }
|
||||
// }else{
|
||||
// py_Str__dtor(&tmp);
|
||||
// pk_SStream__dtor(&ss);
|
||||
// return err;
|
||||
// }
|
||||
// }
|
||||
// pk_SStream__write_Str(&ss, end);
|
||||
// py_Str out = pk_SStream__submit(&ss);
|
||||
// pk_current_vm->_stdout(py_Str__data(&out));
|
||||
// py_Str__dtor(&out);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
static void do_builtin_bindings(){
|
||||
pk_VM* vm = pk_current_vm;
|
||||
|
||||
py_new_nativefunc(&vm->reg[0], _hello, 2, BindType_FUNCTION);
|
||||
py_setdict(&vm->builtins, py_name("hello"), &vm->reg[0]);
|
||||
// py_Ref builtins = py_getmodule("builtins");
|
||||
// py_newfunction(py_reg(0), _py_print,
|
||||
// "print(*args, sep=' ', end='\\n')",
|
||||
// BindType_FUNCTION
|
||||
// );
|
||||
// py_setdict(builtins, py_name("hello"), py_reg(0));
|
||||
}
|
||||
|
||||
void pk_VM__ctor(pk_VM* self){
|
||||
@ -172,7 +169,7 @@ void pk_VM__ctor(pk_VM* self){
|
||||
#undef validate
|
||||
|
||||
self->StopIteration = c11__at(pk_TypeInfo, &self->types, tp_stop_iteration)->self;
|
||||
self->builtins = *py_new_module("builtins");
|
||||
self->builtins = *py_newmodule("builtins", NULL);
|
||||
|
||||
/* Setup Public Builtin Types */
|
||||
Type public_types[] = {
|
||||
@ -193,7 +190,7 @@ void pk_VM__ctor(pk_VM* self){
|
||||
|
||||
/* Do Buildin Bindings*/
|
||||
do_builtin_bindings();
|
||||
self->main = *py_new_module("__main__");
|
||||
self->main = *py_newmodule("__main__", NULL);
|
||||
}
|
||||
|
||||
void pk_VM__dtor(pk_VM* self){
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "pocketpy/pocketpy.h"
|
||||
#include "pocketpy/common/utils.h"
|
||||
#include "pocketpy/objects/object.h"
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
#include <assert.h>
|
||||
@ -32,6 +33,47 @@ int py_exec_simple(const char* source){
|
||||
assert(0); // unreachable
|
||||
}
|
||||
|
||||
py_Ref py_getmodule(const char *name){
|
||||
pk_VM* vm = pk_current_vm;
|
||||
return pk_NameDict__try_get(&vm->modules, py_name(name));
|
||||
}
|
||||
|
||||
py_Ref py_newmodule(const char *name, const char *package){
|
||||
pk_ManagedHeap* heap = &pk_current_vm->heap;
|
||||
PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_module, -1, 0);
|
||||
|
||||
py_Ref r0 = py_sysreg(0);
|
||||
py_Ref r1 = py_sysreg(1);
|
||||
|
||||
*r0 = PyVar__fromobj(obj);
|
||||
|
||||
py_newstr(r1, name);
|
||||
py_setdict(r0, __name__, r1);
|
||||
|
||||
package = package ? package : "";
|
||||
|
||||
py_newstr(r1, package);
|
||||
py_setdict(r0, __package__, r1);
|
||||
|
||||
// convert to fullname
|
||||
if(package[0] != '\0'){
|
||||
// package.name
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf), "%s.%s", package, name);
|
||||
name = buf;
|
||||
}
|
||||
|
||||
py_newstr(r1, name);
|
||||
py_setdict(r0, __path__, r1);
|
||||
|
||||
// we do not allow override in order to avoid memory leak
|
||||
// it is because Module objects are not garbage collected
|
||||
bool exists = pk_NameDict__contains(&pk_current_vm->modules, py_name(name));
|
||||
if(exists) abort();
|
||||
pk_NameDict__set(&pk_current_vm->modules, py_name(name), *r0);
|
||||
return py_getmodule(name);
|
||||
}
|
||||
|
||||
py_Error* py_getlasterror(){
|
||||
return pk_current_vm->last_error;
|
||||
}
|
||||
@ -40,6 +82,21 @@ void py_Error__print(py_Error* self){
|
||||
abort();
|
||||
}
|
||||
|
||||
py_Ref py_reg(int i){
|
||||
assert(i >= 0 && i < 8);
|
||||
return &pk_current_vm->reg[i];
|
||||
}
|
||||
|
||||
py_Ref py_sysreg(int i){
|
||||
assert(i >= 0 && i < 8);
|
||||
return &pk_current_vm->sysreg[i];
|
||||
}
|
||||
|
||||
py_Ref py_stack(int i){
|
||||
assert(i < 0);
|
||||
return &pk_current_vm->stack.sp[i];
|
||||
}
|
||||
|
||||
void py_finalize(){
|
||||
pk_VM__dtor(&pk_default_vm);
|
||||
pk_current_vm = NULL;
|
||||
@ -61,3 +118,22 @@ void py_newint(py_Ref self, int64_t val){
|
||||
self->_i64 = val;
|
||||
}
|
||||
|
||||
void py_newfloat(py_Ref self, double val){
|
||||
self->type = tp_float;
|
||||
self->is_ptr = false;
|
||||
self->_f64 = val;
|
||||
}
|
||||
|
||||
void py_newbool(py_Ref self, bool val){
|
||||
pk_VM* vm = pk_current_vm;
|
||||
*self = val ? vm->True : vm->False;
|
||||
}
|
||||
|
||||
void py_newstr(py_Ref self, const char* val){
|
||||
pk_VM* vm = pk_current_vm;
|
||||
PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_str, 0, sizeof(py_Str));
|
||||
py_Str__ctor((py_Str*)PyObject__value(obj), val);
|
||||
self->type = tp_str;
|
||||
self->is_ptr = true;
|
||||
self->_obj = obj;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user