mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
some up
This commit is contained in:
parent
8c41065258
commit
1696bb6d66
@ -50,10 +50,9 @@ typedef struct pk_VM {
|
|||||||
void (*_stdout)(const char*, ...);
|
void (*_stdout)(const char*, ...);
|
||||||
void (*_stderr)(const char*, ...);
|
void (*_stderr)(const char*, ...);
|
||||||
|
|
||||||
// singleton objects
|
|
||||||
py_TValue True, False, None, NotImplemented, Ellipsis;
|
|
||||||
|
|
||||||
py_TValue last_retval;
|
py_TValue last_retval;
|
||||||
|
bool has_error;
|
||||||
|
|
||||||
py_TValue reg[8]; // users' registers
|
py_TValue reg[8]; // users' registers
|
||||||
|
|
||||||
py_TValue __curr_class;
|
py_TValue __curr_class;
|
||||||
|
@ -40,10 +40,10 @@ void py_initialize();
|
|||||||
void py_finalize();
|
void py_finalize();
|
||||||
|
|
||||||
/// Run a simple source string. Do not change the stack.
|
/// Run a simple source string. Do not change the stack.
|
||||||
bool py_exec(const char*);
|
bool py_exec(const char* source);
|
||||||
/// Eval a simple expression.
|
/// Eval a simple expression.
|
||||||
/// The result will be set to `py_retval()`.
|
/// The result will be set to `py_retval()`.
|
||||||
bool py_eval(const char*);
|
bool py_eval(const char* source);
|
||||||
|
|
||||||
/************* Values Creation *************/
|
/************* Values Creation *************/
|
||||||
void py_newint(py_Ref, py_i64);
|
void py_newint(py_Ref, py_i64);
|
||||||
|
@ -20,11 +20,6 @@ void py_Name__initialize() {
|
|||||||
#define MAGIC_METHOD(x) assert(x == py_name(#x));
|
#define MAGIC_METHOD(x) assert(x == py_name(#x));
|
||||||
#include "pocketpy/xmacros/magics.h"
|
#include "pocketpy/xmacros/magics.h"
|
||||||
#undef MAGIC_METHOD
|
#undef MAGIC_METHOD
|
||||||
|
|
||||||
// print all names
|
|
||||||
for(int i = 0; i < _interned.count; i++) {
|
|
||||||
printf("%d: %s\n", i + 1, c11__getitem(char*, &_r_interned, i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void py_Name__finalize() {
|
void py_Name__finalize() {
|
||||||
|
@ -13,7 +13,6 @@ int NameError(py_Name name) { return -1; }
|
|||||||
|
|
||||||
static bool stack_binaryop(pk_VM* self, py_Name op, py_Name rop);
|
static bool stack_binaryop(pk_VM* self, py_Name op, py_Name rop);
|
||||||
|
|
||||||
|
|
||||||
#define DISPATCH() \
|
#define DISPATCH() \
|
||||||
do { \
|
do { \
|
||||||
frame->ip++; \
|
frame->ip++; \
|
||||||
@ -123,13 +122,13 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
DISPATCH();
|
DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
case OP_LOAD_CONST: PUSH(c11__at(py_TValue, &frame->co->consts, byte.arg)); DISPATCH();
|
case OP_LOAD_CONST: PUSH(c11__at(py_TValue, &frame->co->consts, byte.arg)); DISPATCH();
|
||||||
case OP_LOAD_NONE: PUSH(&self->None); DISPATCH();
|
case OP_LOAD_NONE: py_newnone(SP()++); DISPATCH();
|
||||||
case OP_LOAD_TRUE: PUSH(&self->True); DISPATCH();
|
case OP_LOAD_TRUE: py_newbool(SP()++, true); DISPATCH();
|
||||||
case OP_LOAD_FALSE: PUSH(&self->False); DISPATCH();
|
case OP_LOAD_FALSE: py_newbool(SP()++, false); DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
case OP_LOAD_SMALL_INT: py_newint(SP()++, (int64_t)(int16_t)byte.arg); DISPATCH();
|
case OP_LOAD_SMALL_INT: py_newint(SP()++, (int64_t)(int16_t)byte.arg); DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
case OP_LOAD_ELLIPSIS: PUSH(&self->Ellipsis); DISPATCH();
|
case OP_LOAD_ELLIPSIS: py_newellipsis(SP()++); DISPATCH();
|
||||||
case OP_LOAD_FUNCTION: {
|
case OP_LOAD_FUNCTION: {
|
||||||
// FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
|
// FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
|
||||||
// py_TValue obj;
|
// py_TValue obj;
|
||||||
@ -512,7 +511,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
bool res = py_isidentical(SECOND(), TOP());
|
bool res = py_isidentical(SECOND(), TOP());
|
||||||
POP();
|
POP();
|
||||||
if(byte.arg) res = !res;
|
if(byte.arg) res = !res;
|
||||||
*TOP() = res ? self->True : self->False;
|
py_newbool(TOP(), res);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
case OP_CONTAINS_OP: {
|
case OP_CONTAINS_OP: {
|
||||||
@ -575,9 +574,9 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
case OP_SHORTCUT_IF_FALSE_OR_POP: {
|
case OP_SHORTCUT_IF_FALSE_OR_POP: {
|
||||||
int res = py_bool(TOP());
|
int res = py_bool(TOP());
|
||||||
if(res < 0) goto __ERROR;
|
if(res < 0) goto __ERROR;
|
||||||
if(!res) { // [b, False]
|
if(!res) { // [b, False]
|
||||||
STACK_SHRINK(2); // []
|
STACK_SHRINK(2); // []
|
||||||
PUSH(&self->False); // [False]
|
py_newbool(SP()++, false); // [False]
|
||||||
DISPATCH_JUMP((int16_t)byte.arg);
|
DISPATCH_JUMP((int16_t)byte.arg);
|
||||||
} else {
|
} else {
|
||||||
POP(); // [b]
|
POP(); // [b]
|
||||||
@ -606,7 +605,11 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
// }
|
// }
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
case OP_RETURN_VALUE: {
|
case OP_RETURN_VALUE: {
|
||||||
self->last_retval = byte.arg == BC_NOARG ? POPX() : self->None;
|
if(byte.arg == BC_NOARG){
|
||||||
|
self->last_retval = POPX();
|
||||||
|
}else{
|
||||||
|
py_newnone(&self->last_retval);
|
||||||
|
}
|
||||||
pk_VM__pop_frame(self);
|
pk_VM__pop_frame(self);
|
||||||
if(frame == base_frame) { // [ frameBase<- ]
|
if(frame == base_frame) { // [ frameBase<- ]
|
||||||
return RES_RETURN;
|
return RES_RETURN;
|
||||||
|
@ -68,7 +68,8 @@ void pk_VM__ctor(pk_VM* self) {
|
|||||||
self->_stderr = pk_default_stderr;
|
self->_stderr = pk_default_stderr;
|
||||||
|
|
||||||
self->last_retval = PY_NULL;
|
self->last_retval = PY_NULL;
|
||||||
|
self->has_error = false;
|
||||||
|
|
||||||
self->__curr_class = PY_NULL;
|
self->__curr_class = PY_NULL;
|
||||||
self->__cached_object_new = PY_NULL;
|
self->__cached_object_new = PY_NULL;
|
||||||
self->__dynamic_func_decl = NULL;
|
self->__dynamic_func_decl = NULL;
|
||||||
@ -148,7 +149,10 @@ void pk_VM__ctor(pk_VM* self) {
|
|||||||
pk_TypeInfo* ti = c11__at(pk_TypeInfo, &self->types, t);
|
pk_TypeInfo* ti = c11__at(pk_TypeInfo, &self->types, t);
|
||||||
py_setdict(&self->builtins, ti->name, py_tpobject(t));
|
py_setdict(&self->builtins, ti->name, py_tpobject(t));
|
||||||
}
|
}
|
||||||
py_setdict(&self->builtins, py_name("NotImplemented"), &self->NotImplemented);
|
|
||||||
|
py_TValue tmp;
|
||||||
|
py_newnotimplemented(&tmp);
|
||||||
|
py_setdict(&self->builtins, py_name("NotImplemented"), &tmp);
|
||||||
|
|
||||||
/* Do Buildin Bindings*/
|
/* Do Buildin Bindings*/
|
||||||
pk_VM__init_builtins(self);
|
pk_VM__init_builtins(self);
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
#include "pocketpy/pocketpy.h"
|
||||||
|
#include "pocketpy/interpreter/vm.h"
|
||||||
|
|
||||||
|
void py_printexc(){
|
||||||
|
pk_VM* vm = pk_current_vm;
|
||||||
|
if(vm->has_error){
|
||||||
|
assert(vm->last_retval.type == tp_exception);
|
||||||
|
}else{
|
||||||
|
vm->_stdout("NoneType: None\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void py_formatexc(char *out){
|
||||||
|
|
||||||
|
}
|
132
src/public/vm.c
132
src/public/vm.c
@ -2,6 +2,7 @@
|
|||||||
#include "pocketpy/pocketpy.h"
|
#include "pocketpy/pocketpy.h"
|
||||||
|
|
||||||
#include "pocketpy/common/utils.h"
|
#include "pocketpy/common/utils.h"
|
||||||
|
#include "pocketpy/common/sstream.h"
|
||||||
#include "pocketpy/objects/object.h"
|
#include "pocketpy/objects/object.h"
|
||||||
#include "pocketpy/interpreter/vm.h"
|
#include "pocketpy/interpreter/vm.h"
|
||||||
#include "pocketpy/compiler/compiler.h"
|
#include "pocketpy/compiler/compiler.h"
|
||||||
@ -23,17 +24,136 @@ void py_finalize() {
|
|||||||
pk_MemoryPools__finalize();
|
pk_MemoryPools__finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool py_exec(const char* source) { PK_UNREACHABLE(); }
|
static void disassemble(CodeObject* co) {
|
||||||
|
const static char* OP_NAMES[] = {
|
||||||
|
#define OPCODE(name) #name,
|
||||||
|
#include "pocketpy/xmacros/opcodes.h"
|
||||||
|
#undef OPCODE
|
||||||
|
};
|
||||||
|
|
||||||
bool py_eval(const char* source) {
|
c11_vector /*T=int*/ jumpTargets;
|
||||||
|
c11_vector__ctor(&jumpTargets, sizeof(int));
|
||||||
|
for(int i = 0; i < co->codes.count; i++) {
|
||||||
|
Bytecode* bc = c11__at(Bytecode, &co->codes, i);
|
||||||
|
if(Bytecode__is_forward_jump(bc)) {
|
||||||
|
int target = (int16_t)bc->arg + i;
|
||||||
|
c11_vector__push(int, &jumpTargets, target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c11_sbuf ss;
|
||||||
|
c11_sbuf__ctor(&ss);
|
||||||
|
|
||||||
|
int prev_line = -1;
|
||||||
|
for(int i = 0; i < co->codes.count; i++) {
|
||||||
|
Bytecode byte = c11__getitem(Bytecode, &co->codes, i);
|
||||||
|
BytecodeEx ex = c11__getitem(BytecodeEx, &co->codes_ex, i);
|
||||||
|
|
||||||
|
char line[8];
|
||||||
|
if(ex.lineno == prev_line) {
|
||||||
|
line[0] = '\0';
|
||||||
|
} else {
|
||||||
|
snprintf(line, sizeof(line), "%d", ex.lineno);
|
||||||
|
if(prev_line != -1) c11_sbuf__write_char(&ss, '\n');
|
||||||
|
prev_line = ex.lineno;
|
||||||
|
}
|
||||||
|
|
||||||
|
char pointer[4] = "";
|
||||||
|
c11__foreach(int, &jumpTargets, it) {
|
||||||
|
if(*it == i) {
|
||||||
|
snprintf(pointer, sizeof(pointer), "->");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[64];
|
||||||
|
snprintf(buf, sizeof(buf), "%-8s%-3s%-3d", line, pointer, i);
|
||||||
|
c11_sbuf__write_cstr(&ss, buf);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), " %-24s", OP_NAMES[byte.op]);
|
||||||
|
c11_sbuf__write_cstr(&ss, buf);
|
||||||
|
c11_sbuf__write_char(&ss, ex.is_virtual ? '*' : ' ');
|
||||||
|
|
||||||
|
// _opcode_argstr(this, i, byte, co);
|
||||||
|
do {
|
||||||
|
if(Bytecode__is_forward_jump(&byte)) {
|
||||||
|
c11_sbuf__write_int(&ss, (int16_t)byte.arg);
|
||||||
|
c11_sbuf__write_cstr(&ss, " (to ");
|
||||||
|
c11_sbuf__write_int(&ss, (int16_t)byte.arg + i);
|
||||||
|
c11_sbuf__write_char(&ss, ')');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c11_sbuf__write_int(&ss, byte.arg);
|
||||||
|
switch(byte.op) {
|
||||||
|
case OP_LOAD_CONST:
|
||||||
|
case OP_FORMAT_STRING:
|
||||||
|
case OP_IMPORT_PATH: {
|
||||||
|
c11_string* ud = py_touserdata(c11__at(py_TValue, &co->consts, byte.arg));
|
||||||
|
c11_sbuf__write_cstr(&ss, " (");
|
||||||
|
c11_sbuf__write_cstr(&ss, ud->data);
|
||||||
|
c11_sbuf__write_char(&ss, ')');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_LOAD_NAME:
|
||||||
|
case OP_LOAD_GLOBAL:
|
||||||
|
case OP_LOAD_NONLOCAL:
|
||||||
|
case OP_STORE_GLOBAL:
|
||||||
|
case OP_LOAD_ATTR:
|
||||||
|
case OP_LOAD_METHOD:
|
||||||
|
case OP_STORE_ATTR:
|
||||||
|
case OP_DELETE_ATTR:
|
||||||
|
case OP_BEGIN_CLASS:
|
||||||
|
case OP_GOTO:
|
||||||
|
case OP_DELETE_GLOBAL:
|
||||||
|
case OP_STORE_CLASS_ATTR:
|
||||||
|
case OP_FOR_ITER_STORE_GLOBAL: {
|
||||||
|
c11_sbuf__write_cstr(&ss, " (");
|
||||||
|
c11_sbuf__write_cstr(&ss, py_name2str(byte.arg));
|
||||||
|
c11_sbuf__write_char(&ss, ')');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_LOAD_FAST:
|
||||||
|
case OP_STORE_FAST:
|
||||||
|
case OP_DELETE_FAST:
|
||||||
|
case OP_FOR_ITER_STORE_FAST: {
|
||||||
|
py_Name name = c11__getitem(py_Name, &co->varnames, byte.arg);
|
||||||
|
c11_sbuf__write_cstr(&ss, " (");
|
||||||
|
c11_sbuf__write_cstr(&ss, py_name2str(name));
|
||||||
|
c11_sbuf__write_char(&ss, ')');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_LOAD_FUNCTION: {
|
||||||
|
const FuncDecl* decl = c11__getitem(FuncDecl*, &co->func_decls, byte.arg);
|
||||||
|
c11_sbuf__write_cstr(&ss, " (");
|
||||||
|
c11_sbuf__write_cstr(&ss, decl->code.name->data);
|
||||||
|
c11_sbuf__write_char(&ss, ')');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
if(i != co->codes.count - 1) c11_sbuf__write_char(&ss, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
c11_string* output = c11_sbuf__submit(&ss);
|
||||||
|
pk_current_vm->_stdout("%s\n", output->data);
|
||||||
|
c11_string__delete(output);
|
||||||
|
c11_vector__dtor(&jumpTargets);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
pk_VM__exec(pk_VM* vm, const char* source, const char* filename, enum CompileMode mode) {
|
||||||
CodeObject co;
|
CodeObject co;
|
||||||
pk_SourceData_ src = pk_SourceData__rcnew(source, "main.py", EVAL_MODE, false);
|
pk_SourceData_ src = pk_SourceData__rcnew(source, filename, mode, false);
|
||||||
Error* err = pk_compile(src, &co);
|
Error* err = pk_compile(src, &co);
|
||||||
if(err) {
|
if(err) {
|
||||||
PK_DECREF(src);
|
PK_DECREF(src);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pk_VM* vm = pk_current_vm;
|
|
||||||
|
disassemble(&co);
|
||||||
|
|
||||||
Frame* frame = Frame__new(&co, &vm->main, NULL, vm->stack.sp, vm->stack.sp, &co);
|
Frame* frame = Frame__new(&co, &vm->main, NULL, vm->stack.sp, vm->stack.sp, &co);
|
||||||
pk_VM__push_frame(vm, frame);
|
pk_VM__push_frame(vm, frame);
|
||||||
pk_FrameResult res = pk_VM__run_top_frame(vm);
|
pk_FrameResult res = pk_VM__run_top_frame(vm);
|
||||||
@ -44,6 +164,10 @@ bool py_eval(const char* source) {
|
|||||||
PK_UNREACHABLE();
|
PK_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool py_exec(const char* source) { return pk_VM__exec(pk_current_vm, source, "<exec>", EXEC_MODE); }
|
||||||
|
|
||||||
|
bool py_eval(const char* source) { return pk_VM__exec(pk_current_vm, source, "<eval>", EVAL_MODE); }
|
||||||
|
|
||||||
bool py_call(py_Ref f, int argc, py_Ref argv) { return -1; }
|
bool py_call(py_Ref f, int argc, py_Ref argv) { return -1; }
|
||||||
|
|
||||||
bool py_callmethod(py_Ref self, py_Name name, int argc, py_Ref argv) { return -1; }
|
bool py_callmethod(py_Ref self, py_Name name, int argc, py_Ref argv) { return -1; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user