blueloveTH 2 лет назад
Родитель
Сommit
3c6e4b4e76
3 измененных файлов с 44 добавлено и 30 удалено
  1. 40 28
      3rd/cjson/src/cJSONw.cpp
  2. 3 1
      cmake_build.py
  3. 1 1
      tests/80_json.py

+ 40 - 28
3rd/cjson/src/cJSONw.cpp

@@ -32,50 +32,58 @@ static cJSON* covert_dict_to_cjson(const Dict& dict, VM* vm){
 }
 
 static cJSON* convert_python_object_to_cjson(PyObject* obj, VM* vm){
-    if (is_type(obj, vm->tp_int)){
-        return cJSON_CreateNumber(CAST(i64, obj));
+    Type obj_t = vm->_tp(obj);
+    if (obj_t == vm->tp_int){
+        return cJSON_CreateNumber(_CAST(i64, obj));
     }
-    else if (is_type(obj, vm->tp_float)){
-        return cJSON_CreateNumber(CAST(f64, obj));
+    else if (obj_t == vm->tp_float){
+        return cJSON_CreateNumber(_CAST(f64, obj));
     }
-    else if (is_type(obj, vm->tp_bool)){
+    else if (obj_t == vm->tp_bool){
         return cJSON_CreateBool(obj == vm->True);
     }
-    else if (is_type(obj, vm->tp_str)){
-        return cJSON_CreateString(CAST(Str&, obj).c_str());
+    else if (obj_t == vm->tp_str){
+        return cJSON_CreateString(_CAST(Str&, obj).c_str());
     }
-    else if (is_type(obj, vm->tp_dict)){
-        return covert_dict_to_cjson(CAST(Dict&, obj), vm);
-       
+    else if (obj_t == vm->tp_dict){
+        return covert_dict_to_cjson(_CAST(Dict&, obj), vm);
     }
-    else if (is_type(obj, vm->tp_list)){
-        return convert_list_to_cjson(CAST(List&, obj), vm);
+    else if (obj_t == vm->tp_list){
+        return convert_list_to_cjson(_CAST(List&, obj), vm);
     }
-    else if(is_type(obj, vm->tp_tuple)){
-        return convert_tuple_to_cjson(CAST(Tuple&, obj), vm);
+    else if(obj_t == vm->tp_tuple){
+        return convert_tuple_to_cjson(_CAST(Tuple&, obj), vm);
+    }else if(obj == vm->None){
+        return cJSON_CreateNull();
+    }else{
+        vm->TypeError(fmt("cjson: unrecognized type ", obj_type_name(vm, obj_t)));
     }
-    return cJSON_CreateNull();
+    UNREACHABLE();
 }
+
+
 static PyObject* convert_cjson_to_list(const cJSON * const item, VM* vm){
-    List list;
+    List output;
     cJSON *element = item->child;
     while(element != NULL){
-        list.push_back(convert_cjson_to_python_object(element, vm));
+        output.push_back(convert_cjson_to_python_object(element, vm));
         element = element->next;
     }
-    return VAR(list);
+    return VAR(std::move(output));
 }
 
 static PyObject* convert_cjson_to_dict(const cJSON* const item, VM* vm){
     Dict output(vm);
     cJSON *child = item->child;
     while(child != NULL){
-        const cJSON *child_value = cJSON_GetObjectItemCaseSensitive(item, child->string);
-        output.set(VAR(Str(child->string)), convert_cjson_to_python_object(child_value, vm));
+        const char* key = child->string;
+        const cJSON *child_value = cJSON_GetObjectItemCaseSensitive(item, key);
+        output.set(VAR(key), convert_cjson_to_python_object(child_value, vm));
         child = child->next;
     }
-    return VAR(output);
+    return VAR(std::move(output));
 }
+
 static PyObject* convert_cjson_to_python_object(const cJSON * const item, VM* vm)
 {
     if (cJSON_IsString(item))
@@ -83,6 +91,9 @@ static PyObject* convert_cjson_to_python_object(const cJSON * const item, VM* vm
         return VAR(Str(item->valuestring));
     }
     else if (cJSON_IsNumber(item)){
+        if(item->valuedouble != item->valueint){
+            return VAR(item->valuedouble);
+        }
         return VAR(item->valueint);
     }
     else if (cJSON_IsBool(item)){
@@ -102,19 +113,20 @@ static PyObject* convert_cjson_to_python_object(const cJSON * const item, VM* vm
 
 void add_module_cjson(VM* vm){
     PyObject* mod = vm->new_module("cjson");
-    vm->bind_func<1>(mod, "loads", [](VM* vm, ArgsView args) {
-
-        const Str& expr = CAST(Str&, args[0]);
-
-        cJSON *json = cJSON_ParseWithLength(expr.data, expr.size);
-
+    vm->bind_func<1>(mod, "loads", [](VM* vm, ArgsView args){
+        const Str& string = CAST(Str&, args[0]);
+        cJSON *json = cJSON_ParseWithLength(string.data, string.size);
+        if(json == NULL){
+            const char* err = cJSON_GetErrorPtr();
+            vm->TypeError(fmt("cjson: ", err));
+            UNREACHABLE();
+        }
         PyObject* output = convert_cjson_to_python_object(json, vm);
         cJSON_Delete(json);
         return output;
     });
 
     vm->bind_func<1>(mod, "dumps", [](VM* vm, ArgsView args) {
-        
         cJSON* cjson = convert_python_object_to_cjson(args[0], vm);
         char* str = cJSON_Print(cjson);
         cJSON_Delete(cjson);

+ 3 - 1
cmake_build.py

@@ -7,11 +7,13 @@ if not os.path.exists("build"):
 
 os.chdir("build")
 
-os.system(r"""
+code = os.system(r"""
 cmake .. -DPK_USE_CJSON=ON -DPK_USE_BOX2D=ON
 cmake --build . --config Release
 """)
 
+assert code == 0
+
 if sys.platform == "win32":
     shutil.copy("Release/main.exe", "../main.exe")
     shutil.copy("Release/pocketpy.dll", "../pocketpy.dll")

+ 1 - 1
tests/80_json.py

@@ -5,7 +5,7 @@ a = {
     'd': [1, 2, 3],
     'e': {
         'a': 1,
-        'b': 2,
+        'b': 2.5,
         'c': None,
         'd': [1, 2, 3],
     },