This commit is contained in:
blueloveTH 2023-07-15 13:35:03 +08:00
parent fd2996eb87
commit f2435b81df
4 changed files with 131 additions and 87 deletions

View File

@ -66,6 +66,14 @@ int test_multiple_return(pkpy_vm* vm) {
return 2; return 2;
} }
int test_default_argument(pkpy_vm* vm){
int x;
pkpy_to_int(vm, -1, &x);
bool ok = x == 5;
pkpy_push_bool(vm, ok);
return 1;
}
int test_return_none(pkpy_vm* vm) { int test_return_none(pkpy_vm* vm) {
return 0; return 0;
} }
@ -82,13 +90,17 @@ int test_nested_error(pkpy_vm* vm) {
return 0; return 0;
} }
#define PRINT_TITLE(x) printf("\n====== %s ======\n", x)
int main(int argc, char** argv) { int main(int argc, char** argv) {
pkpy_vm* vm = pkpy_new_vm(true); pkpy_vm* vm = pkpy_new_vm(true);
PRINT_TITLE("test basic exec");
check(pkpy_exec(vm, "print('hello world!')")); check(pkpy_exec(vm, "print('hello world!')"));
error(pkpy_getglobal(vm, pkpy_name("nonexistatn"))); error(pkpy_getglobal(vm, pkpy_name("nonexistatn")));
printf("\ntesting int methods\n"); // test int methods
PRINT_TITLE("test int methods");
int r_int; int r_int;
check(pkpy_push_int(vm, 11)); check(pkpy_push_int(vm, 11));
pkpy_CName m_eleven = pkpy_name("eleven"); pkpy_CName m_eleven = pkpy_name("eleven");
@ -97,30 +109,32 @@ int main(int argc, char** argv) {
check(pkpy_getglobal(vm, m_eleven)); check(pkpy_getglobal(vm, m_eleven));
check(pkpy_is_int(vm, -1)); check(pkpy_is_int(vm, -1));
check(pkpy_to_int(vm, -1, &r_int)); check(pkpy_to_int(vm, -1, &r_int));
printf("%i\n", r_int); printf("%i\n", r_int); // 11
printf("%i\n", pkpy_stack_size(vm)); // 1
fail(pkpy_is_float(vm, -1)); fail(pkpy_is_float(vm, -1));
fail(pkpy_is_bool(vm, -1)); fail(pkpy_is_bool(vm, -1));
fail(pkpy_is_string(vm, -1)); fail(pkpy_is_string(vm, -1));
fail(pkpy_is_none(vm, -1)); fail(pkpy_is_none(vm, -1));
fail(pkpy_is_voidp(vm, -1)); fail(pkpy_is_voidp(vm, -1));
printf("\ntesting float methods\n"); PRINT_TITLE("test float methods");
float r_float; float r_float;
check(pkpy_push_float(vm, 11.11)); check(pkpy_push_float(vm, 11.125));
pkpy_CName m_elevenf = pkpy_name("elevenf"); pkpy_CName m_elevenf = pkpy_name("elevenf");
check(pkpy_setglobal(vm, m_elevenf)); check(pkpy_setglobal(vm, m_elevenf));
check(pkpy_exec(vm, "print(elevenf)")); check(pkpy_exec(vm, "print(elevenf)"));
check(pkpy_getglobal(vm, m_elevenf)); check(pkpy_getglobal(vm, m_elevenf));
check(pkpy_is_float(vm, -1)); check(pkpy_is_float(vm, -1));
check(pkpy_to_float(vm, -1, &r_float)); check(pkpy_to_float(vm, -1, &r_float));
printf("%f\n", r_float); printf("%.3f\n", r_float);
fail(pkpy_is_int(vm, -1)); fail(pkpy_is_int(vm, -1));
fail(pkpy_is_bool(vm, -1)); fail(pkpy_is_bool(vm, -1));
fail(pkpy_is_string(vm, -1)); fail(pkpy_is_string(vm, -1));
fail(pkpy_is_none(vm, -1)); fail(pkpy_is_none(vm, -1));
fail(pkpy_is_voidp(vm, -1)); fail(pkpy_is_voidp(vm, -1));
printf("\ntesting bool methods\n"); PRINT_TITLE("test bool methods");
bool r_bool; bool r_bool;
check(pkpy_push_bool(vm, false)); check(pkpy_push_bool(vm, false));
pkpy_CName m_false_test = pkpy_name("false_test"); pkpy_CName m_false_test = pkpy_name("false_test");
@ -136,7 +150,7 @@ int main(int argc, char** argv) {
fail(pkpy_is_none(vm, -1)); fail(pkpy_is_none(vm, -1));
fail(pkpy_is_voidp(vm, -1)); fail(pkpy_is_voidp(vm, -1));
printf("\ntesting string methods\n"); PRINT_TITLE("test string methods");
pkpy_CString r_string; pkpy_CString r_string;
check(pkpy_push_string(vm, pkpy_string("hello!"))); check(pkpy_push_string(vm, pkpy_string("hello!")));
check(pkpy_setglobal(vm, pkpy_name("hello1"))); check(pkpy_setglobal(vm, pkpy_name("hello1")));
@ -156,7 +170,7 @@ int main(int argc, char** argv) {
fail(pkpy_is_none(vm, -1)); fail(pkpy_is_none(vm, -1));
fail(pkpy_is_voidp(vm, -1)); fail(pkpy_is_voidp(vm, -1));
printf("\ntesting None methods\n"); PRINT_TITLE("test none methods");
check(pkpy_push_none(vm)); check(pkpy_push_none(vm));
pkpy_CName m_none = pkpy_name("none"); pkpy_CName m_none = pkpy_name("none");
check(pkpy_setglobal(vm, m_none)); check(pkpy_setglobal(vm, m_none));
@ -169,7 +183,7 @@ int main(int argc, char** argv) {
fail(pkpy_is_string(vm, -1)); fail(pkpy_is_string(vm, -1));
fail(pkpy_is_voidp(vm, -1)); fail(pkpy_is_voidp(vm, -1));
printf("\ntesting voidp methods\n"); PRINT_TITLE("test voidp methods");
void* vp = (void*) 123; void* vp = (void*) 123;
check(pkpy_push_voidp(vm, vp)); check(pkpy_push_voidp(vm, vp));
check(pkpy_setglobal(vm, pkpy_name("vp"))); check(pkpy_setglobal(vm, pkpy_name("vp")));
@ -185,8 +199,7 @@ int main(int argc, char** argv) {
fail(pkpy_is_string(vm, -1)); fail(pkpy_is_string(vm, -1));
fail(pkpy_is_none(vm, -1)); fail(pkpy_is_none(vm, -1));
PRINT_TITLE("test sizing and indexing");
printf("\ntesting sizing and indexing\n");
int stack_size = pkpy_stack_size(vm); int stack_size = pkpy_stack_size(vm);
printf("stack size %i\n", stack_size); printf("stack size %i\n", stack_size);
check(pkpy_is_int(vm, 0)); check(pkpy_is_int(vm, 0));
@ -201,18 +214,14 @@ int main(int argc, char** argv) {
check(pkpy_is_string(vm, -3)); check(pkpy_is_string(vm, -3));
check(pkpy_is_none(vm, -2)); check(pkpy_is_none(vm, -2));
check(pkpy_is_voidp(vm, -1)); check(pkpy_is_voidp(vm, -1));
printf("\ntesting error catching\n"); PRINT_TITLE("test error catching");
error(pkpy_exec(vm, "let's make sure syntax errors get caught")); error(pkpy_exec(vm, "let's make sure syntax errors get caught"));
check(pkpy_stack_size(vm) == 0); //stack should be cleared after error is resolved //stack should be cleared after error is resolved
check(pkpy_stack_size(vm) == 0);
printf("\ntesting calls\n");
PRINT_TITLE("test simple call");
check(pkpy_exec(vm, "def x(x, y) : return x - y")); check(pkpy_exec(vm, "def x(x, y) : return x - y"));
check(pkpy_exec(vm, "def vararg_x(*x) : return sum(x)"));
check(pkpy_exec(vm, "def keyword_x(x=1, y=1) : return x+y"));
check(pkpy_exec(vm, "def retmany_x() : return 1, 2, 3"));
check(pkpy_getglobal(vm, pkpy_name("x"))); check(pkpy_getglobal(vm, pkpy_name("x")));
check(pkpy_push_null(vm)); check(pkpy_push_null(vm));
check(pkpy_push_int(vm, 2)); check(pkpy_push_int(vm, 2));
@ -221,6 +230,8 @@ int main(int argc, char** argv) {
check(pkpy_to_int(vm, -1, &r_int)); check(pkpy_to_int(vm, -1, &r_int));
printf("x : %i\n", r_int); printf("x : %i\n", r_int);
PRINT_TITLE("test vararg call");
check(pkpy_exec(vm, "def vararg_x(*x) : return sum(x)"));
check(pkpy_getglobal(vm, pkpy_name("vararg_x"))); check(pkpy_getglobal(vm, pkpy_name("vararg_x")));
check(pkpy_push_null(vm)); check(pkpy_push_null(vm));
check(pkpy_push_int(vm, 1)); check(pkpy_push_int(vm, 1));
@ -233,25 +244,33 @@ int main(int argc, char** argv) {
check(pkpy_to_int(vm, -1, &r_int)); check(pkpy_to_int(vm, -1, &r_int));
printf("vararg_x : %i\n", r_int); printf("vararg_x : %i\n", r_int);
PRINT_TITLE("test keyword call");
check(pkpy_exec(vm, "def keyword_x(x=1, y=1) : return x+y"));
check(pkpy_getglobal(vm, pkpy_name("keyword_x"))); check(pkpy_getglobal(vm, pkpy_name("keyword_x")));
check(pkpy_push_null(vm)); check(pkpy_push_null(vm));
check(pkpy_push_int(vm, 3)); check(pkpy_push_int(vm, 3));
check(pkpy_vectorcall(vm, 1)); check(pkpy_vectorcall(vm, 1));
check(pkpy_to_int(vm, -1, &r_int)); check(pkpy_to_int(vm, -1, &r_int));
printf("keyword_x : %i\n", r_int); printf("keyword_x : %i\n", r_int); // 3+1
check(pkpy_getglobal(vm, pkpy_name("keyword_x"))); check(pkpy_getglobal(vm, pkpy_name("keyword_x")));
check(pkpy_push_null(vm)); check(pkpy_push_null(vm));
check(pkpy_vectorcall(vm, 0)); check(pkpy_vectorcall(vm, 0));
check(pkpy_to_int(vm, -1, &r_int)); check(pkpy_to_int(vm, -1, &r_int));
printf("keyword_x : %i\n", r_int); printf("keyword_x : %i\n", r_int); // 1+1
check(pkpy_stack_size(vm) == 4); check(pkpy_stack_size(vm) == 4);
check(pkpy_pop(vm, 4)); // clear stack
PRINT_TITLE("test return many");
check(pkpy_exec(vm, "def retmany_x() : return 1, 2, 3"));
check(pkpy_getglobal(vm, pkpy_name("retmany_x"))); check(pkpy_getglobal(vm, pkpy_name("retmany_x")));
check(pkpy_push_null(vm)); check(pkpy_push_null(vm));
check(pkpy_vectorcall(vm, 0)); check(pkpy_vectorcall(vm, 0));
check(pkpy_stack_size(vm) == 7);
check(pkpy_stack_size(vm) == 1);
check(pkpy_unpack_sequence(vm, 3));
check(pkpy_stack_size(vm) == 3);
check(pkpy_to_int(vm, -3, &r_int)); check(pkpy_to_int(vm, -3, &r_int));
printf("retmany_x : %i\n", r_int); printf("retmany_x : %i\n", r_int);
check(pkpy_to_int(vm, -2, &r_int)); check(pkpy_to_int(vm, -2, &r_int));
@ -259,33 +278,40 @@ int main(int argc, char** argv) {
check(pkpy_to_int(vm, -1, &r_int)); check(pkpy_to_int(vm, -1, &r_int));
printf("retmany_x : %i\n", r_int); printf("retmany_x : %i\n", r_int);
// test argument error
check(pkpy_getglobal(vm, pkpy_name("x"))); check(pkpy_getglobal(vm, pkpy_name("x")));
check(pkpy_push_null(vm)); check(pkpy_push_null(vm));
error(pkpy_vectorcall(vm, 0)); error(pkpy_vectorcall(vm, 0));
check(pkpy_exec(vm, "l = []")); check(pkpy_exec(vm, "l = []"));
check(pkpy_getglobal(vm, pkpy_name("l"))); check(pkpy_getglobal(vm, pkpy_name("l")));
check(pkpy_get_unbound_method(vm, pkpy_name("append"))); check(pkpy_get_unbound_method(vm, pkpy_name("append")));
check(pkpy_push_string(vm, pkpy_string("hello"))); check(pkpy_push_string(vm, pkpy_string("hello")));
check(pkpy_vectorcall(vm, 1)); check(pkpy_vectorcall(vm, 1));
check(pkpy_pop_top(vm)); // pop None returned by append()
check(pkpy_exec(vm, "print(l)")); check(pkpy_exec(vm, "print(l)"));
PRINT_TITLE("test bindings");
printf("\ntesting pushing functions\n");
check(pkpy_push_function(vm, "test_binding()", test_binding)); check(pkpy_push_function(vm, "test_binding()", test_binding));
check(pkpy_setglobal(vm, pkpy_name("test_binding"))); check(pkpy_setglobal(vm, pkpy_name("test_binding")));
check(pkpy_exec(vm, "print(test_binding())")); check(pkpy_exec(vm, "print(test_binding())"));
check(pkpy_stack_size(vm) == 0);
check(pkpy_push_function(vm, "test_multiple_return()", test_multiple_return)); check(pkpy_push_function(vm, "test_multiple_return()", test_multiple_return));
check(pkpy_setglobal(vm, pkpy_name("test_multiple_return"))); check(pkpy_setglobal(vm, pkpy_name("test_multiple_return")));
check(pkpy_stack_size(vm) == 0);
//uncomment if _exec changes check(pkpy_push_function(vm, "test_default_argument(x=5)", test_default_argument));
//check(pkpy_exec(vm, "test_multiple_return()")); check(pkpy_push_null(vm));
//check(pkpy_stack_size(vm) == 2); check(pkpy_vectorcall(vm, 0));
check(pkpy_stack_size(vm) == 1);
check(pkpy_is_bool(vm, -1) == true);
check(pkpy_to_bool(vm, -1, &r_bool));
check(r_bool == true);
check(pkpy_pop_top(vm));
check(pkpy_stack_size(vm) == 0);
PRINT_TITLE("test error propagate");
check(pkpy_push_function(vm, "test_error_propagate()", test_error_propagate)); check(pkpy_push_function(vm, "test_error_propagate()", test_error_propagate));
check(pkpy_setglobal(vm, pkpy_name("test_error_propagate"))); check(pkpy_setglobal(vm, pkpy_name("test_error_propagate")));
error(pkpy_exec(vm, "test_error_propagate()")); error(pkpy_exec(vm, "test_error_propagate()"));
@ -293,58 +319,54 @@ int main(int argc, char** argv) {
check(pkpy_getglobal(vm, pkpy_name("test_multiple_return"))); check(pkpy_getglobal(vm, pkpy_name("test_multiple_return")));
check(pkpy_push_null(vm)); check(pkpy_push_null(vm));
check(pkpy_vectorcall(vm, 0)); check(pkpy_vectorcall(vm, 0));
check(pkpy_stack_size(vm) == 1);
check(pkpy_unpack_sequence(vm, 2));
check(pkpy_stack_size(vm) == 2); check(pkpy_stack_size(vm) == 2);
check(pkpy_pop(vm, 2)); check(pkpy_pop(vm, 2));
check(pkpy_stack_size(vm) == 0); check(pkpy_stack_size(vm) == 0);
PRINT_TITLE("test other errors");
check(pkpy_getglobal(vm, pkpy_name("test_error_propagate"))); check(pkpy_getglobal(vm, pkpy_name("test_error_propagate")));
check(pkpy_pop_top(vm)); check(pkpy_pop_top(vm));
fail(pkpy_getglobal(vm, pkpy_name("nonexistant"))); error(pkpy_getglobal(vm, pkpy_name("nonexistant")));
error(pkpy_exec(vm, "raise NameError('testing error throwing from python')")); error(pkpy_exec(vm, "raise NameError('testing error throwing from python')"));
PRINT_TITLE("test TypeError");
check(pkpy_push_float(vm, 2.0));
error(pkpy_to_int(vm, -1, &r_int));
PRINT_TITLE("test complicated errors");
pkpy_exec(vm, "test_error_propagate()"); pkpy_exec(vm, "test_error_propagate()");
check(pkpy_check_error(vm)); check(pkpy_check_error(vm));
// testing code going to standard error, can ignore next error
pkpy_clear_error(vm, NULL); pkpy_clear_error(vm, NULL);
//errors
//this should be catchable //this should be catchable
check(pkpy_exec(vm, "try : test_error_propagate(); except NameError : pass")); check(pkpy_exec(vm, "try : test_error_propagate(); except NameError : pass"));
error(pkpy_error(vm, "_", pkpy_string("test direct error mechanism"))); error(pkpy_error(vm, "_", pkpy_string("test direct error mechanism")));
//more complicated error handling //more complicated error handling
check(pkpy_exec(vm, "def error_from_python() : raise NotImplementedError()")); check(pkpy_exec(vm, "def error_from_python() : raise NotImplementedError()"));
check(pkpy_push_function(vm, "test_nested_error()", test_nested_error)); check(pkpy_push_function(vm, "test_nested_error()", test_nested_error));
check(pkpy_setglobal(vm, pkpy_name("test_nested_error"))); check(pkpy_setglobal(vm, pkpy_name("test_nested_error")));
error(pkpy_exec(vm, "test_nested_error()")); error(pkpy_exec(vm, "test_nested_error()"));
PRINT_TITLE("test getattr/setattr");
check(pkpy_exec(vm, "import math")); check(pkpy_exec(vm, "import math"));
check(pkpy_getglobal(vm, pkpy_name("math"))); check(pkpy_getglobal(vm, pkpy_name("math")));
check(pkpy_getattr(vm, pkpy_name("pi"))); check(pkpy_getattr(vm, pkpy_name("pi")));
check(pkpy_to_float(vm, -1, &r_float)); check(pkpy_to_float(vm, -1, &r_float));
printf("pi: %.2f\n", r_float); printf("pi: %.2f\n", r_float);
check(pkpy_eval(vm, "math.pi"));
check(pkpy_to_float(vm, -1, &r_float));
printf("pi: %.2f\n", r_float);
check(pkpy_pop(vm, 1));
// math.pi = 2 // math.pi = 2
check(pkpy_push_int(vm, 2)); check(pkpy_push_int(vm, 2));
check(pkpy_eval(vm, "math")); check(pkpy_eval(vm, "math"));
check(pkpy_setattr(vm, pkpy_name("pi"))); check(pkpy_setattr(vm, pkpy_name("pi")));
check(pkpy_exec(vm, "print(math.pi)")); check(pkpy_exec(vm, "print(math.pi)"));
PRINT_TITLE("test eval");
//should give a type error check(pkpy_eval(vm, "math.pi"));
check(pkpy_push_float(vm, 2.0)); check(pkpy_to_float(vm, -1, &r_float));
error(pkpy_to_int(vm, -1, &r_int)); printf("pi: %.2f\n", r_float);
check(pkpy_pop(vm, 1));
return 0; return 0;
} }

View File

@ -1,46 +1,54 @@
====== test basic exec ======
hello world! hello world!
successfully errored with this message: successfully errored with this message:
Traceback (most recent call last): Traceback (most recent call last):
NameError: nonexistatn NameError: nonexistatn
testing int methods ====== test int methods ======
11 11
11 11
1
testing float methods ====== test float methods ======
11.11 11.125
11.110000 11.125
testing bool methods ====== test bool methods ======
False False
0 0
testing string methods ====== test string methods ======
hello!
hello! hello!
hello
hello
testing None methods ====== test none methods ======
None None
testing voidp methods ====== test voidp methods ======
<void* at 0x7b> <void* at 0x7b>
123 123
testing sizing and indexing ====== test sizing and indexing ======
stack size 6 stack size 6
testing error catching ====== test error catching ======
successfully errored with this message: successfully errored with this message:
File "<c-bound>", line 1 File "main.py", line 1
let's make sure syntax errors get caught let's make sure syntax errors get caught
SyntaxError: EOL while scanning string literal SyntaxError: EOL while scanning string literal
testing calls ====== test simple call ======
x : -1 x : -1
====== test vararg call ======
vararg_x : 21 vararg_x : 21
====== test keyword call ======
keyword_x : 4 keyword_x : 4
keyword_x : 2 keyword_x : 2
====== test return many ======
retmany_x : 1 retmany_x : 1
retmany_x : 2 retmany_x : 2
retmany_x : 3 retmany_x : 3
@ -48,30 +56,45 @@ successfully errored with this message:
TypeError: expected 2 positional arguments, got 0 (x) TypeError: expected 2 positional arguments, got 0 (x)
['hello'] ['hello']
testing pushing functions ====== test bindings ======
12 12
====== test error propagate ======
successfully errored with this message: successfully errored with this message:
Traceback (most recent call last): Traceback (most recent call last):
File "<c-bound>", line 1 File "main.py", line 1
test_error_propagate() test_error_propagate()
NameError: catch me NameError: catch me
====== test other errors ======
successfully errored with this message: successfully errored with this message:
Traceback (most recent call last): Traceback (most recent call last):
File "<c-bound>", line 1 NameError: nonexistant
successfully errored with this message:
Traceback (most recent call last):
File "main.py", line 1
raise NameError('testing error throwing from python') raise NameError('testing error throwing from python')
NameError: testing error throwing from python NameError: testing error throwing from python
====== test TypeError ======
successfully errored with this message:
TypeError: expected 'int', got 'float'
====== test complicated errors ======
successfully errored with this message: successfully errored with this message:
Traceback (most recent call last): Traceback (most recent call last):
_: test direct error mechanism _: test direct error mechanism
successfully errored with this message: successfully errored with this message:
Traceback (most recent call last): Traceback (most recent call last):
File "<c-bound>", line 1 File "main.py", line 1
test_nested_error() test_nested_error()
File "<c-bound>", line 1 File "main.py", line 1
def error_from_python() : raise NotImplementedError() def error_from_python() : raise NotImplementedError()
NotImplementedError NotImplementedError
pi: 3.14
====== test getattr/setattr ======
pi: 3.14 pi: 3.14
2 2
successfully errored with this message:
TypeError: expected 'int', got 'float' ====== test eval ======
pi: 2.00

View File

@ -8,8 +8,11 @@ order: 5
+ If a method returns false, call the `pkpy_clear_error` method to check the error and clear it + If a method returns false, call the `pkpy_clear_error` method to check the error and clear it
+ If `pkpy_clear_error` returns false, it means that no error was set, and it takes no action + If `pkpy_clear_error` returns false, it means that no error was set, and it takes no action
+ If `pkpy_clear_error` returns true, it means there was an error and it was cleared. It will provide a string summary of the error in the message parameter (if it is not NULL) If null is passed in as message, and it will just print the message to stderr. + If `pkpy_clear_error` returns true, it means there was an error and it was cleared. It will provide a string summary of the error in the message parameter if it is not `NULL`.
+ You are responsible for freeing `message`.
!!!
You are responsible for freeing `message`.
!!!
#### `bool pkpy_check_error(pkpy_vm*)` #### `bool pkpy_check_error(pkpy_vm*)`

View File

@ -374,15 +374,14 @@ bool pkpy_setattr(pkpy_vm* vm_handle, pkpy_CName name) {
} }
//get global will also get bulitins //get global will also get bulitins
bool pkpy_getglobal(pkpy_vm* vm_handle, pkpy_CName name_) { bool pkpy_getglobal(pkpy_vm* vm_handle, pkpy_CName name) {
VM* vm = (VM*) vm_handle; VM* vm = (VM*) vm_handle;
StrName name(name_);
PK_ASSERT_NO_ERROR() PK_ASSERT_NO_ERROR()
PyObject* o = vm->_main->attr().try_get(name); PyObject* o = vm->_main->attr().try_get(StrName(name));
if (o == nullptr) { if (o == nullptr) {
o = vm->builtins->attr().try_get(name); o = vm->builtins->attr().try_get(StrName(name));
if (o == nullptr){ if (o == nullptr){
pkpy_error(vm_handle, "NameError", pkpy_name_to_string(name_)); pkpy_error(vm_handle, "NameError", pkpy_name_to_string(name));
return false; return false;
} }
} }
@ -390,11 +389,11 @@ bool pkpy_getglobal(pkpy_vm* vm_handle, pkpy_CName name_) {
return true; return true;
} }
bool pkpy_setglobal(pkpy_vm* vm_handle, pkpy_CName name_) { bool pkpy_setglobal(pkpy_vm* vm_handle, pkpy_CName name) {
VM* vm = (VM*) vm_handle; VM* vm = (VM*) vm_handle;
PK_ASSERT_NO_ERROR() PK_ASSERT_NO_ERROR()
PK_ASSERT_N_EXTRA_ELEMENTS(1) PK_ASSERT_N_EXTRA_ELEMENTS(1)
vm->_main->attr().set(StrName(name_), vm->s_data.popx()); vm->_main->attr().set(StrName(name), vm->s_data.popx());
return true; return true;
} }
@ -435,7 +434,7 @@ bool pkpy_get_unbound_method(pkpy_vm* vm_handle, pkpy_CName name){
PK_PROTECTED( PK_PROTECTED(
o = vm->get_unbound_method(o, StrName(name), &self); o = vm->get_unbound_method(o, StrName(name), &self);
) )
vm->s_data.shrink(2); vm->s_data.pop();
vm->s_data.push(o); vm->s_data.push(o);
vm->s_data.push(self); vm->s_data.push(self);
return true; return true;
@ -459,10 +458,7 @@ bool pkpy_clear_error(pkpy_vm* vm_handle, char** message) {
// no error // no error
if (vm->_c.error == nullptr) return false; if (vm->_c.error == nullptr) return false;
Exception& e = _py_cast<Exception&>(vm, vm->_c.error); Exception& e = _py_cast<Exception&>(vm, vm->_c.error);
if (message != nullptr) if (message != nullptr) *message = e.summary().c_str_dup();
*message = e.summary().c_str_dup();
else
std::cerr << "ERROR: " << e.summary() << "\n";
vm->_c.error = nullptr; vm->_c.error = nullptr;
// clear the whole stack?? // clear the whole stack??
vm->callstack.clear(); vm->callstack.clear();