mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
99 lines
3.0 KiB
C
99 lines
3.0 KiB
C
#include "pocketpy/objects/codeobject.h"
|
|
#include "pocketpy/objects/sourcedata.h"
|
|
#include "pocketpy/pocketpy.h"
|
|
|
|
#include "pocketpy/common/utils.h"
|
|
#include "pocketpy/common/sstream.h"
|
|
#include "pocketpy/objects/object.h"
|
|
#include "pocketpy/interpreter/vm.h"
|
|
#include "pocketpy/compiler/compiler.h"
|
|
#include <assert.h>
|
|
|
|
py_Type pk_code__register() {
|
|
py_Type type = pk_newtype("code", tp_object, NULL, (py_Dtor)CodeObject__dtor, false, true);
|
|
pk__tp_set_marker(type, (void (*)(void *))CodeObject__gc_mark);
|
|
return type;
|
|
}
|
|
|
|
bool _py_compile(CodeObject* out,
|
|
const char* source,
|
|
const char* filename,
|
|
enum py_CompileMode mode,
|
|
bool is_dynamic) {
|
|
VM* vm = pk_current_vm;
|
|
SourceData_ src = SourceData__rcnew(source, filename, mode, is_dynamic);
|
|
Error* err = pk_compile(src, out);
|
|
if(err) {
|
|
py_exception(tp_SyntaxError, err->msg);
|
|
py_BaseException__stpush(&vm->curr_exception, err->src, err->lineno, NULL);
|
|
PK_DECREF(src);
|
|
|
|
PK_DECREF(err->src);
|
|
PK_FREE(err);
|
|
return false;
|
|
}
|
|
PK_DECREF(src);
|
|
return true;
|
|
}
|
|
|
|
bool py_compile(const char* source,
|
|
const char* filename,
|
|
enum py_CompileMode mode,
|
|
bool is_dynamic) {
|
|
CodeObject co;
|
|
bool ok = _py_compile(&co, source, filename, mode, is_dynamic);
|
|
if(ok) {
|
|
// compile success
|
|
CodeObject* ud = py_newobject(py_retval(), tp_code, 0, sizeof(CodeObject));
|
|
*ud = co;
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool pk_exec(CodeObject* co, py_Ref module) {
|
|
VM* vm = pk_current_vm;
|
|
if(!module) module = &vm->main;
|
|
assert(module->type == tp_module);
|
|
|
|
py_StackRef sp = vm->stack.sp;
|
|
Frame* frame = Frame__new(co, sp, module, module, sp, false, false);
|
|
VM__push_frame(vm, frame);
|
|
FrameResult res = VM__run_top_frame(vm);
|
|
if(res == RES_ERROR) return false;
|
|
assert(res == RES_RETURN);
|
|
return true;
|
|
}
|
|
|
|
bool pk_execdyn(CodeObject* co, py_Ref module, py_Ref globals, py_Ref locals) {
|
|
VM* vm = pk_current_vm;
|
|
if(!module) module = &vm->main;
|
|
assert(module->type == tp_module);
|
|
|
|
py_StackRef sp = vm->stack.sp;
|
|
assert(globals != NULL && locals != NULL);
|
|
|
|
if(globals->type == tp_namedict) {
|
|
globals = py_getslot(globals, 0);
|
|
assert(globals->type == tp_module);
|
|
} else {
|
|
assert(globals->type == tp_dict);
|
|
}
|
|
Frame* frame = Frame__new(co, sp, module, globals, locals, false, true);
|
|
VM__push_frame(vm, frame);
|
|
FrameResult res = VM__run_top_frame(vm);
|
|
if(res == RES_ERROR) return false;
|
|
assert(res == RES_RETURN);
|
|
return true;
|
|
}
|
|
|
|
bool py_exec(const char* source, const char* filename, enum py_CompileMode mode, py_Ref module) {
|
|
CodeObject co;
|
|
if(!_py_compile(&co, source, filename, mode, false)) return false;
|
|
bool ok = pk_exec(&co, module);
|
|
CodeObject__dtor(&co);
|
|
return ok;
|
|
}
|
|
|
|
bool py_eval(const char* source, py_Ref module) {
|
|
return py_exec(source, "<string>", EVAL_MODE, module);
|
|
} |