blueloveTH 2 年 前
コミット
fd2996eb87
5 ファイル変更121 行追加103 行削除
  1. 96 93
      c_bindings/test.c
  2. 1 1
      docs/C-API/error.md
  3. 5 1
      docs/C-API/specials.md
  4. 2 1
      include/pocketpy/pocketpy_c.h
  5. 17 7
      src/pocketpy_c.cpp

+ 96 - 93
c_bindings/test.c

@@ -71,34 +71,30 @@ int test_return_none(pkpy_vm* vm) {
 }
 
 int test_error_propagate(pkpy_vm* vm) {
-    pkpy_error(vm, "NameError", "catch me");
+    pkpy_error(vm, "NameError", pkpy_string("catch me"));
     return 1;
 }
 
 int test_nested_error(pkpy_vm* vm) {
-    pkpy_get_global(vm, "error_from_python");
-    pkpy_call(vm, 0);
+    pkpy_getglobal(vm, pkpy_name("error_from_python"));
+    pkpy_push_null(vm);
+    pkpy_vectorcall(vm, 0);
     return 0;
 }
 
-
-pkpy_vm* vm;
-
 int main(int argc, char** argv) {
+    pkpy_vm* vm = pkpy_new_vm(true);
 
-    vm = pkpy_vm_create(true, true);
-
-    //test run
-    check(pkpy_vm_run(vm, "print('hello world!')"));
-
-    error(pkpy_get_global(vm, "nonexistatn"));
+    check(pkpy_exec(vm, "print('hello world!')"));
+    error(pkpy_getglobal(vm, pkpy_name("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"));
+    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);
@@ -109,11 +105,12 @@ int main(int argc, char** argv) {
     fail(pkpy_is_voidp(vm, -1));
 
     printf("\ntesting float methods\n");
-    double r_float;
+    float 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"));
+    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("%f\n", r_float);
@@ -126,9 +123,10 @@ int main(int argc, char** argv) {
     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"));
+    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);
@@ -139,19 +137,19 @@ int main(int argc, char** argv) {
     fail(pkpy_is_voidp(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));
+    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));
-    printf("%s\n", r_string);
-    free(r_string);
-    const char* r_stringn;
-    int r_size;
-    check(pkpy_to_stringn(vm, -1, &r_stringn, &r_size));
-    printf("%.*s\n", r_size, r_stringn);
+    
+    for(int i=0; i<r_string.size; i++) {
+        putchar(r_string.data[i]);
+    }
+    putchar('\n');
+
     fail(pkpy_is_int(vm, -1));
     fail(pkpy_is_float(vm, -1));
     fail(pkpy_is_bool(vm, -1));
@@ -160,9 +158,10 @@ int main(int argc, char** argv) {
 
     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"));
+    pkpy_CName m_none = pkpy_name("none");
+    check(pkpy_setglobal(vm, m_none));
+    check(pkpy_exec(vm, "print(none)"));
+    check(pkpy_getglobal(vm, m_none));
     check(pkpy_is_none(vm, -1));
     fail(pkpy_is_int(vm, -1));
     fail(pkpy_is_float(vm, -1));
@@ -173,9 +172,9 @@ int main(int argc, char** argv) {
     printf("\ntesting voidp methods\n");
     void* vp = (void*) 123;
     check(pkpy_push_voidp(vm, vp));
-    check(pkpy_set_global(vm, "vp"));
-    check(pkpy_vm_run(vm, "print(vp)"));
-    check(pkpy_get_global(vm, "vp"));
+    check(pkpy_setglobal(vm, pkpy_name("vp")));
+    check(pkpy_exec(vm, "print(vp)"));
+    check(pkpy_getglobal(vm, pkpy_name("vp")));
     check(pkpy_is_voidp(vm, -1));
     vp = NULL;
     check(pkpy_to_voidp(vm, -1, &vp));
@@ -190,9 +189,6 @@ int main(int argc, char** argv) {
     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, 26));
-    fail(pkpy_check_stack(vm, 27));
     check(pkpy_is_int(vm, 0));
     check(pkpy_is_float(vm, 1));
     check(pkpy_is_bool(vm, 2));
@@ -205,53 +201,56 @@ int main(int argc, char** argv) {
     check(pkpy_is_string(vm, -3));
     check(pkpy_is_none(vm, -2));
     check(pkpy_is_voidp(vm, -1));
-    check(pkpy_push(vm, -3));
-    check(pkpy_is_string(vm, -1));
     
     printf("\ntesting error catching\n");
-    error(pkpy_vm_run(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
 
     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_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_get_global(vm, "x"));
+    check(pkpy_getglobal(vm, pkpy_name("x")));
+    check(pkpy_push_null(vm));
     check(pkpy_push_int(vm, 2));
     check(pkpy_push_int(vm, 3));
-    check(pkpy_call(vm, 2));
+    check(pkpy_vectorcall(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_getglobal(vm, pkpy_name("vararg_x")));
+    check(pkpy_push_null(vm));
     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_vectorcall(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_getglobal(vm, pkpy_name("keyword_x")));
+    check(pkpy_push_null(vm));
     check(pkpy_push_int(vm, 3));
-    check(pkpy_call(vm, 1));
+    check(pkpy_vectorcall(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_getglobal(vm, pkpy_name("keyword_x")));
+    check(pkpy_push_null(vm));
+    check(pkpy_vectorcall(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_getglobal(vm, pkpy_name("retmany_x")));
+    check(pkpy_push_null(vm));
+    check(pkpy_vectorcall(vm, 0));
     check(pkpy_stack_size(vm) == 7);
     check(pkpy_to_int(vm, -3, &r_int));
     printf("retmany_x : %i\n", r_int);
@@ -260,69 +259,73 @@ int main(int argc, char** argv) {
     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_getglobal(vm, pkpy_name("x")));
+    check(pkpy_push_null(vm));
+    error(pkpy_vectorcall(vm, 0));
 
-    check(pkpy_vm_run(vm, "l = []"));
+    check(pkpy_exec(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)"));
+    check(pkpy_getglobal(vm, pkpy_name("l")));
+    check(pkpy_get_unbound_method(vm, pkpy_name("append")));
+    check(pkpy_push_string(vm, pkpy_string("hello")));
+    check(pkpy_vectorcall(vm, 1));
+    check(pkpy_exec(vm, "print(l)"));
 
 
     printf("\ntesting pushing functions\n");
 
-    check(pkpy_push_function(vm, test_binding, 0));
-    check(pkpy_set_global(vm, "test_binding"));
-    check(pkpy_vm_run(vm, "print(test_binding())"));
+    check(pkpy_push_function(vm, "test_binding()", test_binding));
+    check(pkpy_setglobal(vm, pkpy_name("test_binding")));
+    check(pkpy_exec(vm, "print(test_binding())"));
 
-    check(pkpy_push_function(vm, test_multiple_return, 0));
-    check(pkpy_set_global(vm, "test_multiple_return"));
+    check(pkpy_push_function(vm, "test_multiple_return()", test_multiple_return));
+    check(pkpy_setglobal(vm, pkpy_name("test_multiple_return")));
 
     //uncomment if _exec changes
-    //check(pkpy_vm_run(vm, "test_multiple_return()"));
+    //check(pkpy_exec(vm, "test_multiple_return()"));
     //check(pkpy_stack_size(vm) == 2);
 
 
-    check(pkpy_push_function(vm, test_error_propagate, 0));
-    check(pkpy_set_global(vm, "test_error_propagate"));
-    error(pkpy_vm_run(vm, "test_error_propagate()"));
+    check(pkpy_push_function(vm, "test_error_propagate()", test_error_propagate));
+    check(pkpy_setglobal(vm, pkpy_name("test_error_propagate")));
+    error(pkpy_exec(vm, "test_error_propagate()"));
 
-    check(pkpy_get_global(vm, "test_multiple_return"));
-    check(pkpy_call(vm, 0));
+    check(pkpy_getglobal(vm, pkpy_name("test_multiple_return")));
+    check(pkpy_push_null(vm));
+    check(pkpy_vectorcall(vm, 0));
     check(pkpy_stack_size(vm) == 2);
 
     
     check(pkpy_pop(vm, 2));
     check(pkpy_stack_size(vm) == 0);
 
-    check(pkpy_check_global(vm, "test_error_propagate"));
-    fail(pkpy_check_global(vm, "nonexistant"));
+    check(pkpy_getglobal(vm, pkpy_name("test_error_propagate")));
+    check(pkpy_pop_top(vm));
+    fail(pkpy_getglobal(vm, pkpy_name("nonexistant")));
 
-    error(pkpy_vm_run(vm, "raise NameError('testing error throwing from python')"));
+    error(pkpy_exec(vm, "raise NameError('testing error throwing from python')"));
 
-    pkpy_vm_run(vm, "test_error_propagate()");
+    pkpy_exec(vm, "test_error_propagate()");
     check(pkpy_check_error(vm));
     // testing code going to standard error, can ignore next error
     pkpy_clear_error(vm, NULL);
 
     //errors
     //this should be catchable
-    check(pkpy_vm_run(vm, "try : test_error_propagate(); except NameError : pass"));
+    check(pkpy_exec(vm, "try : test_error_propagate(); except NameError : pass"));
 
-    error(pkpy_error(vm, "_", "test direct error mechanism"));
+    error(pkpy_error(vm, "_", pkpy_string("test direct error mechanism")));
 
 
     //more complicated error handling
-    check(pkpy_vm_run(vm, "def error_from_python() : raise NotImplementedError()"));
-    check(pkpy_push_function(vm, test_nested_error, 0));
-    check(pkpy_set_global(vm, "test_nested_error"));
-    error(pkpy_vm_run(vm, "test_nested_error()"));
-
-    check(pkpy_vm_run(vm, "import math"));
-    check(pkpy_get_global(vm, "math"));
-    check(pkpy_getattr(vm, "pi"));
+    check(pkpy_exec(vm, "def error_from_python() : raise NotImplementedError()"));
+    check(pkpy_push_function(vm, "test_nested_error()", test_nested_error));
+    check(pkpy_setglobal(vm, pkpy_name("test_nested_error")));
+    error(pkpy_exec(vm, "test_nested_error()"));
+
+    check(pkpy_exec(vm, "import math"));
+    check(pkpy_getglobal(vm, pkpy_name("math")));
+    check(pkpy_getattr(vm, pkpy_name("pi")));
     check(pkpy_to_float(vm, -1, &r_float));
     printf("pi: %.2f\n", r_float);
 
@@ -335,8 +338,8 @@ int main(int argc, char** argv) {
     // math.pi = 2
     check(pkpy_push_int(vm, 2));
     check(pkpy_eval(vm, "math"));
-    check(pkpy_setattr(vm, "pi"));
-    check(pkpy_vm_run(vm, "print(math.pi)"));
+    check(pkpy_setattr(vm, pkpy_name("pi")));
+    check(pkpy_exec(vm, "print(math.pi)"));
 
 
     //should give a type error

+ 1 - 1
docs/C-API/error.md

@@ -15,6 +15,6 @@ order: 5
 
 Return true if the vm is currently in an error state.
 
-#### `bool pkpy_error(pkpy_vm*, const char* name, const char* message)`
+#### `bool pkpy_error(pkpy_vm*, const char* name, pkpy_CString message)`
 
 Set the error state of the vm. It is almost equivalent to `raise` in python.

+ 5 - 1
docs/C-API/specials.md

@@ -14,4 +14,8 @@ order: 6
 
 + `pkpy_CName pkpy_name(const char*)`
 
-    Construct a `pkpy_CName` from a null-terminated C string. You should cache the result of this function if you are going to use it multiple times.
+    Construct a `pkpy_CName` from a null-terminated C string. You should cache the result of this function if you are going to use it multiple times.
+
++ `pkpy_CString pkpy_name_to_string(pkpy_CName)`
+
+    Convert a `pkpy_CName` to a `pkpy_CString`.

+ 2 - 1
include/pocketpy/pocketpy_c.h

@@ -77,7 +77,7 @@ PK_EXPORT bool pkpy_unpack_sequence(pkpy_vm*, int size);
 PK_EXPORT bool pkpy_get_unbound_method(pkpy_vm*, pkpy_CName);
 
 /* Error Handling */
-PK_EXPORT bool pkpy_error(pkpy_vm*, const char* name, const char* message);
+PK_EXPORT bool pkpy_error(pkpy_vm*, const char* name, pkpy_CString);
 PK_EXPORT bool pkpy_check_error(pkpy_vm*);
 PK_EXPORT bool pkpy_clear_error(pkpy_vm*, char** message);
 
@@ -88,6 +88,7 @@ PK_EXPORT bool pkpy_vectorcall(pkpy_vm*, int argc);
 PK_EXPORT void pkpy_free(void* p);
 PK_EXPORT pkpy_CString pkpy_string(const char*);
 PK_EXPORT pkpy_CName pkpy_name(const char*);
+PK_EXPORT pkpy_CString pkpy_name_to_string(pkpy_CName);
 PK_EXPORT void pkpy_compile_to_string(pkpy_vm*, const char* source, const char* filename, int mode, bool* ok, char** out);
 
 /* REPL */

+ 17 - 7
src/pocketpy_c.cpp

@@ -1,4 +1,5 @@
 #include "pocketpy.h"
+#include "pocketpy/pocketpy_c.h"
 #include "pocketpy_c.h"
 
 using namespace pkpy;
@@ -9,7 +10,7 @@ typedef int (*LuaStyleFuncC)(VM*);
     int __ex_count = count_extra_elements(vm, n); \
     if(__ex_count < n){ \
         std::string msg = fmt("expected at least ", n, " elements, got ", __ex_count); \
-        pkpy_error(vm_handle, "StackError", msg.c_str()); \
+        pkpy_error(vm_handle, "StackError", pkpy_string(msg.c_str())); \
         return false; \
     }
 
@@ -373,14 +374,15 @@ bool pkpy_setattr(pkpy_vm* vm_handle, pkpy_CName name) {
 }
 
 //get global will also get bulitins
-bool pkpy_getglobal(pkpy_vm* vm_handle, const char* name) {
+bool pkpy_getglobal(pkpy_vm* vm_handle, pkpy_CName name_) {
     VM* vm = (VM*) vm_handle;
+    StrName name(name_);
     PK_ASSERT_NO_ERROR()
     PyObject* o = vm->_main->attr().try_get(name);
     if (o == nullptr) {
         o = vm->builtins->attr().try_get(name);
         if (o == nullptr){
-            pkpy_error(vm_handle, "NameError", name);
+            pkpy_error(vm_handle, "NameError", pkpy_name_to_string(name_));
             return false;
         }
     }
@@ -388,11 +390,11 @@ bool pkpy_getglobal(pkpy_vm* vm_handle, const char* name) {
     return true;
 }
 
-bool pkpy_setglobal(pkpy_vm* vm_handle, const char* name) {
+bool pkpy_setglobal(pkpy_vm* vm_handle, pkpy_CName name_) {
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_N_EXTRA_ELEMENTS(1)
-    vm->_main->attr().set(name, vm->s_data.popx());
+    vm->_main->attr().set(StrName(name_), vm->s_data.popx());
     return true;
 }
 
@@ -440,10 +442,10 @@ bool pkpy_get_unbound_method(pkpy_vm* vm_handle, pkpy_CName name){
 }
 
 /* Error Handling */
-bool pkpy_error(pkpy_vm* vm_handle, const char* name, const char* message) {
+bool pkpy_error(pkpy_vm* vm_handle, const char* name, pkpy_CString message) {
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
-    vm->_c.error = py_var(vm, Exception(name, message));
+    vm->_c.error = py_var(vm, Exception(name, Str(message.data, message.size)));
     return false;
 }
 
@@ -494,6 +496,14 @@ pkpy_CName pkpy_name(const char* name){
     return StrName(name).index;
 }
 
+pkpy_CString pkpy_name_to_string(pkpy_CName name){
+    std::string_view sv = StrName(name).sv();
+    pkpy_CString s;
+    s.data = sv.data();
+    s.size = sv.size();
+    return s;
+}
+
 void pkpy_compile_to_string(pkpy_vm* vm_handle, const char* source, const char* filename, int mode, bool* ok, char** out){
     VM* vm = (VM*) vm_handle;
     try{