blueloveTH 2 лет назад
Родитель
Сommit
1d9c565b64
5 измененных файлов с 63 добавлено и 12 удалено
  1. 32 1
      c_bindings/pocketpy_c.cpp
  2. 3 0
      c_bindings/pocketpy_c.h
  3. 16 0
      c_bindings/test.c
  4. 3 0
      c_bindings/test_answers.txt
  5. 9 11
      run_c_binding_test.sh

+ 32 - 1
c_bindings/pocketpy_c.cpp

@@ -133,7 +133,7 @@ bool pkpy_vm_run(pkpy_vm* vm_handle, const char* source) {
     ERRHANDLER_OPEN
 
     CodeObject_ code = vm->compile(source, "<c-bound>", EXEC_MODE);
-    // PyObject* result = vm->_exec(code, vm->_main);
+    vm->_exec(code, vm->_main);
 
     //unpack_return(w, result);
     //NOTE: it seems like vm->_exec should return whatever the last command it
@@ -584,3 +584,34 @@ bool pkpy_error(pkpy_vm* vm_handle, const char* message) {
     ERRHANDLER_CLOSE
 }
 
+bool pkpy_getattr(pkpy_vm* vm_handle, const char* name) {
+    CVM* vm = (CVM*) vm_handle;
+    ERRHANDLER_OPEN
+    PyObject* o = vm->c_data->top();
+    PyObject* ret = vm->getattr(o, name, false);
+    if(ret == nullptr) return false;
+    vm->c_data->top() = ret;
+    ERRHANDLER_CLOSE
+    return true;
+}
+
+bool pkpy_setattr(pkpy_vm* vm_handle, const char* name) {
+    CVM* vm = (CVM*) vm_handle;
+    ERRHANDLER_OPEN
+    PyObject* a = vm->c_data->top();
+    PyObject* val = vm->c_data->second();
+    vm->setattr(a, name, val);
+    vm->c_data->shrink(2);
+    ERRHANDLER_CLOSE
+    return true;
+}
+
+bool pkpy_eval(pkpy_vm* vm_handle, const char* code) {
+    CVM* vm = (CVM*) vm_handle;
+    ERRHANDLER_OPEN
+    CodeObject_ co = vm->compile(code, "<eval>", EVAL_MODE);
+    PyObject* ret = vm->_exec(co, vm->_main);
+    vm->c_data->push(ret);
+    ERRHANDLER_CLOSE
+    return true;
+}

+ 3 - 0
c_bindings/pocketpy_c.h

@@ -110,6 +110,9 @@ PK_EXPORT int pkpy_stack_size(pkpy_vm*);
 typedef void (*OutputHandler)(pkpy_vm*, const char*);
 PK_EXPORT void pkpy_set_output_handlers(pkpy_vm*, OutputHandler stdout_handler, OutputHandler stderr_handler);
 
+PK_EXPORT bool pkpy_getattr(pkpy_vm*, const char* name);
+PK_EXPORT bool pkpy_setattr(pkpy_vm*, const char* name);
+PK_EXPORT bool pkpy_eval(pkpy_vm*, const char* source);
 
 #ifdef __cplusplus
 }

+ 16 - 0
c_bindings/test.c

@@ -339,6 +339,22 @@ int main(int argc, char** argv) {
     //check(pkpy_set_global(vm, "test_nested_error"));
     //fail(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_to_float(vm, -1, &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
+    check(pkpy_push_int(vm, 2));
+    check(pkpy_eval(vm, "math"));
+    check(pkpy_setattr(vm, "pi"));
+    check(pkpy_vm_run(vm, "print(math.pi)"));
     return 0;
 }

+ 3 - 0
c_bindings/test_answers.txt

@@ -64,3 +64,6 @@ NameError: could not find requested global
 successfully errored with this message: 
 Traceback (most recent call last):
 CBindingError: test direct error mechanism
+pi: 3.14
+pi: 3.14
+2

+ 9 - 11
run_c_binding_test.sh

@@ -1,22 +1,20 @@
 python3 preprocess.py
 
-if [ ! -f "pocketpy_c.o" ] 
-then
-    echo "compiling c++ lib"
-    clang++ -c -o pocketpy_c.o c_bindings/pocketpy_c.cpp -Wfatal-errors --std=c++17 -O2 -Wall -Wno-sign-compare -Wno-unused-variable -fno-rtti -stdlib=libc++ -I src/ -fsanitize=address -g
-else
-    echo "DETECTED PREVIOUS COMPILATION USING IT"
-fi
+echo "compiling c++ lib"
+clang++ -c -o pocketpy_c.o c_bindings/pocketpy_c.cpp -Wfatal-errors --std=c++17 -O2 -Wall -Wno-sign-compare -Wno-unused-variable -fno-rtti -stdlib=libc++ -I src/ -g
 
 echo "compiling c executable" 
-clang -c -o test.o c_bindings/test.c -Wfatal-errors -O2 -Wall -Wno-sign-compare -Wno-unused-variable -I src/ -fsanitize=address -g
+clang -c -o test.o c_bindings/test.c -Wfatal-errors -O2 -Wall -Wno-sign-compare -Wno-unused-variable -I src/ -g
 echo "linking"
-clang++ -o c_binding_test test.o pocketpy_c.o -stdlib=libc++ -fsanitize=address -g
-echo "running, leaksanitizer is finding a false postive leak in the CVM constructor"
-echo "ignore that but pay attention to anything else"
+clang++ -o c_binding_test test.o pocketpy_c.o -stdlib=libc++ -g
 ./c_binding_test > binding_test_scratch
 echo "checking results (they should be identical)"
 diff -q -s  binding_test_scratch c_bindings/test_answers.txt
+if [ $? -eq 1 ]
+then
+    echo "ERROR: c binding test failed"
+    exit 1
+fi
 
 echo "cleaning up"
 rm pocketpy_c.o