#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!\n"); 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"); 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_return_none(pkpy_vm* vm) { return 0; } int test_error_propagate(pkpy_vm* vm) { pkpy_get_global(vm, "does not exist"); return 1; } pkpy_vm* vm; void cleanup(void) { pkpy_vm_destroy(vm); } int main(int argc, char** argv) { vm = pkpy_vm_create(true, true); atexit(cleanup); //test run check(pkpy_vm_run(vm, "print('hello world!')")); error(pkpy_get_global(vm, "nonexistatn")); printf("\ntesting int methods\n"); int r_int; check(pkpy_push_int(vm, 11)); check(pkpy_set_global(vm, "eleven")); check(pkpy_vm_run(vm, "print(eleven)")); check(pkpy_get_global(vm, "eleven")); check(pkpy_is_int(vm, -1)); check(pkpy_to_int(vm, -1, &r_int)); printf("%i\n", r_int); fail(pkpy_is_float(vm, -1)); fail(pkpy_is_bool(vm, -1)); fail(pkpy_is_string(vm, -1)); fail(pkpy_is_none(vm, -1)); printf("\ntesting float methods\n"); double r_float; check(pkpy_push_float(vm, 11.11)); check(pkpy_set_global(vm, "elevenf")); check(pkpy_vm_run(vm, "print(elevenf)")); check(pkpy_get_global(vm, "elevenf")); check(pkpy_is_float(vm, -1)); check(pkpy_to_float(vm, -1, &r_float)); printf("%f\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)); printf("\ntesting bool methods\n"); bool r_bool; check(pkpy_push_bool(vm, false)); check(pkpy_set_global(vm, "false_test")); check(pkpy_vm_run(vm, "print(false_test)")); check(pkpy_get_global(vm, "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)); printf("\ntesting string methods\n"); char* r_string; check(pkpy_push_string(vm, "hello!")); check(pkpy_set_global(vm, "hello1")); check(pkpy_vm_run(vm, "print(hello1)")); check(pkpy_push_stringn(vm, "hello!", 5)); check(pkpy_is_string(vm, -1)); check(pkpy_to_string(vm, -1, &r_string)); printf("%s\n", r_string); fail(pkpy_is_int(vm, -1)); fail(pkpy_is_float(vm, -1)); fail(pkpy_is_bool(vm, -1)); fail(pkpy_is_none(vm, -1)); free(r_string); printf("\ntesting None methods\n"); check(pkpy_push_none(vm)); check(pkpy_set_global(vm, "none")); check(pkpy_vm_run(vm, "print(none)")); check(pkpy_get_global(vm, "none")); check(pkpy_is_none(vm, -1)); fail(pkpy_is_int(vm, -1)); fail(pkpy_is_float(vm, -1)); fail(pkpy_is_bool(vm, -1)); fail(pkpy_is_string(vm, -1)); printf("\ntesting sizing and indexing\n"); int stack_size = pkpy_stack_size(vm); printf("stack size %i\n", stack_size); check(pkpy_check_stack(vm, 10)); check(pkpy_check_stack(vm, 27)); fail(pkpy_check_stack(vm, 28)); check(pkpy_is_int(vm, 0)); check(pkpy_is_float(vm, 1)); check(pkpy_is_bool(vm, 2)); check(pkpy_is_string(vm, 3)); check(pkpy_is_none(vm, 4)); check(pkpy_is_int(vm, -5)); check(pkpy_is_float(vm, -4)); check(pkpy_is_bool(vm, -3)); check(pkpy_is_string(vm, -2)); check(pkpy_is_none(vm, -1)); printf("\ntesting error catching\n"); error(pkpy_vm_run(vm, "let's make sure syntax errors get caught")); check(pkpy_stack_size(vm) == 0); //stack should be cleared after error is resolved printf("\ntesting calls\n"); check(pkpy_vm_run(vm, "def x(x, y) : return x - y")); check(pkpy_vm_run(vm, "def vararg_x(*x) : return sum(x)")); check(pkpy_vm_run(vm, "def keyword_x(x=1, y=1) : return x+y")); check(pkpy_vm_run(vm, "def retmany_x() : return 1, 2, 3")); check(pkpy_get_global(vm, "x")); check(pkpy_push_int(vm, 2)); check(pkpy_push_int(vm, 3)); check(pkpy_call(vm, 2)); check(pkpy_to_int(vm, -1, &r_int)); printf("x : %i\n", r_int); check(pkpy_get_global(vm, "vararg_x")); check(pkpy_push_int(vm, 1)); check(pkpy_push_int(vm, 2)); check(pkpy_push_int(vm, 3)); check(pkpy_push_int(vm, 4)); check(pkpy_push_int(vm, 5)); check(pkpy_push_int(vm, 6)); check(pkpy_call(vm, 6)); check(pkpy_to_int(vm, -1, &r_int)); printf("vararg_x : %i\n", r_int); check(pkpy_get_global(vm, "keyword_x")); check(pkpy_push_int(vm, 3)); check(pkpy_call(vm, 1)); check(pkpy_to_int(vm, -1, &r_int)); printf("keyword_x : %i\n", r_int); check(pkpy_get_global(vm, "keyword_x")); check(pkpy_call(vm, 0)); check(pkpy_to_int(vm, -1, &r_int)); printf("keyword_x : %i\n", r_int); check(pkpy_stack_size(vm) == 4); check(pkpy_get_global(vm, "retmany_x")); check(pkpy_call(vm, 0)); check(pkpy_stack_size(vm) == 7); check(pkpy_to_int(vm, -3, &r_int)); printf("retmany_x : %i\n", r_int); check(pkpy_to_int(vm, -2, &r_int)); printf("retmany_x : %i\n", r_int); check(pkpy_to_int(vm, -1, &r_int)); printf("retmany_x : %i\n", r_int); check(pkpy_get_global(vm, "x")); error(pkpy_call(vm, 0)); check(pkpy_vm_run(vm, "l = []")); check(pkpy_get_global(vm, "l")); check(pkpy_push_string(vm, "hello")); check(pkpy_call_method(vm, "append", 1)); check(pkpy_vm_run(vm, "print(l)")); printf("\ntesting pushing functions\n"); check(pkpy_push_function(vm, test_binding)); check(pkpy_set_global(vm, "test_binding")); check(pkpy_vm_run(vm, "print(test_binding())")); check(pkpy_push_function(vm, test_multiple_return)); check(pkpy_set_global(vm, "test_multiple_return")); //uncomment if _exec changes //check(pkpy_vm_run(vm, "test_multiple_return()")); //check(pkpy_stack_size(vm) == 2); check(pkpy_push_function(vm, test_error_propagate)); check(pkpy_set_global(vm, "test_error_propagate")); error(pkpy_vm_run(vm, "test_error_propagate()")); check(pkpy_get_global(vm, "test_multiple_return")); check(pkpy_call(vm, 0)); check(pkpy_stack_size(vm) == 2); check(pkpy_pop(vm, 2)); check(pkpy_stack_size(vm) == 0); return 0; }