#include "pocketpy_c.h" #include #include //tests the c bindings for pocketpy void check_impl(pkpy_vm* vm, bool result, int lineno) { if (!result) { printf("ERROR: failed where it should have succeed at line %i\n", lineno); char* message; if (!pkpy_clear_error(vm, &message)) { printf("clear error reported everything was fine\n"); exit(1); } printf("%s\n", message); free(message); exit(1); } } void fail_impl(pkpy_vm* vm, bool result, int lineno) { if (result) { printf("ERROR: succeeded where it should have failed line %i\n", lineno); exit(1); } else { char* message; if (pkpy_clear_error(vm, &message)) { printf("actually errored! line %i\n", lineno); free(message); exit(1); } } } void error_impl(pkpy_vm* vm, bool result, int lineno) { if (result) { printf("ERROR: succeeded where it should have failed line %i\n", lineno); exit(1); } else { char* message; if (!pkpy_clear_error(vm, &message)){ printf("clear error reported everything was fine\n"); exit(1); } else { printf("successfully errored with this message: \n"); printf("%s\n", message); free(message); } } } #define check(r) check_impl(vm, (r), __LINE__) #define fail(r) fail_impl(vm, (r), __LINE__) #define error(r) error_impl(vm, (r), __LINE__) int test_binding(pkpy_vm* vm) { pkpy_push_int(vm, 12); return 1; } int test_multiple_return(pkpy_vm* vm) { pkpy_push_int(vm, 12); pkpy_push_int(vm, 13); 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) { return 0; } int test_error_propagate(pkpy_vm* vm) { pkpy_error(vm, "NameError", pkpy_string("catch me")); return 1; } int test_nested_error(pkpy_vm* vm) { pkpy_getglobal(vm, pkpy_name("error_from_python")); pkpy_push_null(vm); pkpy_vectorcall(vm, 0); return 0; } #define PRINT_TITLE(x) printf("\n====== %s ======\n", x) int main(int argc, char** argv) { pkpy_vm* vm = pkpy_new_vm(true); PRINT_TITLE("test basic exec"); check(pkpy_exec(vm, "print('hello world!')")); error(pkpy_getglobal(vm, pkpy_name("nonexistatn"))); // test int methods PRINT_TITLE("test int methods"); int r_int; check(pkpy_push_int(vm, 11)); pkpy_CName m_eleven = pkpy_name("eleven"); check(pkpy_setglobal(vm, m_eleven)); check(pkpy_exec(vm, "print(eleven)")); check(pkpy_getglobal(vm, m_eleven)); check(pkpy_is_int(vm, -1)); check(pkpy_to_int(vm, -1, &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_bool(vm, -1)); fail(pkpy_is_string(vm, -1)); fail(pkpy_is_none(vm, -1)); fail(pkpy_is_voidp(vm, -1)); PRINT_TITLE("test float methods"); float r_float; check(pkpy_push_float(vm, 11.125)); pkpy_CName m_elevenf = pkpy_name("elevenf"); check(pkpy_setglobal(vm, m_elevenf)); check(pkpy_exec(vm, "print(elevenf)")); check(pkpy_getglobal(vm, m_elevenf)); check(pkpy_is_float(vm, -1)); check(pkpy_to_float(vm, -1, &r_float)); printf("%.3f\n", r_float); fail(pkpy_is_int(vm, -1)); fail(pkpy_is_bool(vm, -1)); fail(pkpy_is_string(vm, -1)); fail(pkpy_is_none(vm, -1)); fail(pkpy_is_voidp(vm, -1)); PRINT_TITLE("test bool methods"); bool r_bool; check(pkpy_push_bool(vm, false)); pkpy_CName m_false_test = pkpy_name("false_test"); check(pkpy_setglobal(vm, m_false_test)); check(pkpy_exec(vm, "print(false_test)")); check(pkpy_getglobal(vm, m_false_test)); check(pkpy_is_bool(vm, -1)); check(pkpy_to_bool(vm, -1, &r_bool)); printf("%i\n", r_bool); fail(pkpy_is_int(vm, -1)); fail(pkpy_is_float(vm, -1)); fail(pkpy_is_string(vm, -1)); fail(pkpy_is_none(vm, -1)); fail(pkpy_is_voidp(vm, -1)); PRINT_TITLE("test string methods"); pkpy_CString r_string; check(pkpy_push_string(vm, pkpy_string("hello!"))); check(pkpy_setglobal(vm, pkpy_name("hello1"))); check(pkpy_exec(vm, "print(hello1)")); check(pkpy_push_string(vm, pkpy_string("hello!"))); check(pkpy_is_string(vm, -1)); check(pkpy_to_string(vm, -1, &r_string)); for(int i=0; i