mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
add py_smartexec
This commit is contained in:
parent
cc94a382a9
commit
b99c3ed220
@ -111,6 +111,21 @@ PK_EXPORT bool py_exec(const char* source,
|
||||
/// Evaluate a source string. Equivalent to `py_exec(source, "<string>", EVAL_MODE, module)`.
|
||||
PK_EXPORT bool py_eval(const char* source, py_Ref module) PY_RAISE PY_RETURN;
|
||||
|
||||
/// Run a source string with smart interpretation.
|
||||
/// Example:
|
||||
/// `py_newstr(py_r0(), "abc");`
|
||||
/// `py_newint(py_r1(), 123);`
|
||||
/// `py_smartexec("print(_1, _2)", NULL, py_r0(), py_r1());`
|
||||
/// `// "abc 123" will be printed`.
|
||||
PK_EXPORT bool py_smartexec(const char* source, py_Ref module, ...) PY_RAISE PY_RETURN;
|
||||
/// Evaluate a source string with smart interpretation.
|
||||
/// Example:
|
||||
/// `py_newstr(py_r0(), "abc");`
|
||||
/// `py_smarteval("len(_1)", NULL, py_r0());`
|
||||
/// `int res = py_toint(py_retval());`
|
||||
/// `// res will be 3`.
|
||||
PK_EXPORT bool py_smarteval(const char* source, py_Ref module, ...) PY_RAISE PY_RETURN;
|
||||
|
||||
/// Compile a source string into a code object.
|
||||
/// Use python's `exec()` or `eval()` to execute it.
|
||||
PK_EXPORT bool py_compile(const char* source,
|
||||
@ -286,6 +301,15 @@ PK_EXPORT py_GlobalRef py_getreg(int i);
|
||||
/// Set the i-th register.
|
||||
PK_EXPORT void py_setreg(int i, py_Ref val);
|
||||
|
||||
#define py_r0() py_getreg(0)
|
||||
#define py_r1() py_getreg(1)
|
||||
#define py_r2() py_getreg(2)
|
||||
#define py_r3() py_getreg(3)
|
||||
#define py_r4() py_getreg(4)
|
||||
#define py_r5() py_getreg(5)
|
||||
#define py_r6() py_getreg(6)
|
||||
#define py_r7() py_getreg(7)
|
||||
|
||||
/// Get variable in the `__main__` module.
|
||||
PK_EXPORT py_ItemRef py_getglobal(py_Name name);
|
||||
/// Set variable in the `__main__` module.
|
||||
|
@ -1,11 +1,13 @@
|
||||
#include "pocketpy/common/str.h"
|
||||
#include "pocketpy/objects/codeobject.h"
|
||||
#include "pocketpy/pocketpy.h"
|
||||
|
||||
#include "pocketpy/common/utils.h"
|
||||
#include "pocketpy/objects/object.h"
|
||||
#include "pocketpy/common/sstream.h"
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
#include "pocketpy/common/_generated.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
|
||||
py_Ref py_getmodule(const char* path) {
|
||||
@ -523,6 +525,67 @@ static bool builtins_eval(int argc, py_Ref argv) {
|
||||
return _builtins_execdyn("eval", argc, argv, EVAL_MODE);
|
||||
}
|
||||
|
||||
static bool
|
||||
pk_smartexec(const char* source, py_Ref module, enum py_CompileMode mode, va_list args) {
|
||||
if(module == NULL) module = &pk_current_vm->main;
|
||||
pk_mappingproxy__namedict(py_pushtmp(), module); // globals
|
||||
py_newdict(py_pushtmp()); // locals
|
||||
bool ok = py_compile(source, "<string>", mode, true);
|
||||
if(!ok) return false;
|
||||
py_push(py_retval());
|
||||
// [globals, locals, code]
|
||||
CodeObject* co = py_touserdata(py_peek(-1));
|
||||
py_StackRef locals = py_peek(-2);
|
||||
int max_index = 0;
|
||||
c11__foreach(Bytecode, &co->codes, bc) {
|
||||
if(bc->op == OP_LOAD_NAME) {
|
||||
c11_sv name = py_name2sv(bc->arg);
|
||||
if(name.data[0] != '_') continue;
|
||||
int index;
|
||||
if(name.size == 1) {
|
||||
index = 1;
|
||||
} else if(name.size == 2 && isdigit(name.data[1])) {
|
||||
index = name.data[1] - '0';
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
max_index = c11__max(max_index, index);
|
||||
}
|
||||
}
|
||||
|
||||
if(max_index == 0) { return ValueError("no placeholder found in the source"); }
|
||||
|
||||
for(int i = 1; i <= max_index; i++) {
|
||||
py_Ref val = va_arg(args, py_Ref);
|
||||
char buf[3];
|
||||
buf[0] = '_';
|
||||
buf[1] = '0' + i;
|
||||
buf[2] = '\0';
|
||||
py_dict_setitem_by_str(locals, buf, val);
|
||||
if(i == 1) {
|
||||
// _ => _1
|
||||
py_dict_setitem_by_str(locals, "_", val);
|
||||
}
|
||||
}
|
||||
return pk_exec(co, module);
|
||||
}
|
||||
|
||||
bool py_smartexec(const char* source, py_Ref module, ...) {
|
||||
va_list args;
|
||||
va_start(args, module);
|
||||
bool ok = pk_smartexec(source, module, EXEC_MODE, args);
|
||||
va_end(args);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool py_smarteval(const char* source, py_Ref module, ...) {
|
||||
va_list args;
|
||||
va_start(args, module);
|
||||
bool ok = pk_smartexec(source, module, EVAL_MODE, args);
|
||||
va_end(args);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool builtins_compile(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(3);
|
||||
for(int i = 0; i < 3; i++) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user