diff --git a/module/json.cpp b/module/json.cpp index 04d2feb..51adecc 100644 --- a/module/json.cpp +++ b/module/json.cpp @@ -37,6 +37,8 @@ std::string get_content(token_type type) { case token_type::tok_id: return "identifier"; case token_type::tok_bool: return "boolean"; } + // unreachable + return ""; } struct token { @@ -46,7 +48,6 @@ struct token { class json { private: - usize parse_error = 0; std::string text = ""; usize line = 1; usize ptr = 0; @@ -77,11 +78,16 @@ private: var vector_object_generate(gc*); void hash_member(nas_hash&, gc*); var hash_object_generate(gc*); + void check_eof(); + static std::string& error_info() { + static std::string info = ""; + return info; + } public: std::string stringify(var&); var parse(const std::string&, gc*); - bool has_error() const { return parse_error; } + static const std::string& get_error() { return error_info(); } }; std::string json::var_generate(var& value) { @@ -152,6 +158,11 @@ void json::next() { while(ptrtemp = temp_stack = ngc->alloc(vm_type::vm_vec); auto result = vector_object_generate(ngc); + check_eof(); ngc->temp = nil; temp_stack = nil; return result; } else { ngc->temp = temp_stack = ngc->alloc(vm_type::vm_vec); auto result = hash_object_generate(ngc); + check_eof(); ngc->temp = nil; temp_stack = nil; return result; @@ -334,17 +360,17 @@ var parse(var* args, usize size, gc* ngc) { if (!input.is_str()) { return nas_err("json::parse", "must use string"); } - json instance; - auto result = instance.parse(input.str(), ngc); - if (instance.has_error()) { - return nas_err("json::parse", "parse error"); - } - return result; + return json().parse(input.str(), ngc); +} + +var get_error(var* args, usize size, gc* ngc) { + return ngc->newstr(json::get_error()); } module_func_info func_tbl[] = { {"stringify", stringify}, {"parse", parse}, + {"get_error", get_error}, {nullptr, nullptr} }; diff --git a/module/libjson.nas b/module/libjson.nas index 4eb91ba..eefa7fa 100644 --- a/module/libjson.nas +++ b/module/libjson.nas @@ -6,6 +6,8 @@ use std.dylib; var _dynamic_lib = dylib.dlopen("libjson."~(os.platform()=="windows"?"dll":"so")); var _stringify = _dynamic_lib.stringify; var _parse = _dynamic_lib.parse; +var _get_error = _dynamic_lib.get_error; +var _no_param_call = dylib.limitcall(0); var _call = dylib.limitcall(1); var stringify = func(object) { @@ -14,4 +16,8 @@ var stringify = func(object) { var parse = func(input_string) { return _call(_parse, input_string); +} + +var get_error = func() { + return _no_param_call(_get_error); } \ No newline at end of file diff --git a/test/json.nas b/test/json.nas index 263c4be..f0a23d6 100644 --- a/test/json.nas +++ b/test/json.nas @@ -39,6 +39,36 @@ println(ss, "\n"); println(json.parse(ss), "\n"); println(libjson.parse(ss), "\n"); +var test_func = func(input_string) { + var result = libjson.parse(input_string); + var errno = libjson.get_error(); + if (!size(errno)) { + println("\e[92;1msuccess\e[0m:"); + println(" ", result); + } else { + println("\e[91;1merror\e[0m:"); + foreach(var err; split("\n", errno)) { + println(" |-> ", err); + } + println(" +-> generated with error:"); + println(" +-> ", result); + } +} + +test_func("[[]]"); +test_func("{\"1\":1}"); +test_func("[[[}]]]"); +test_func("=-==_+_+_+"); +test_func("123"); +test_func(libjson.stringify({ + a: 0, + b: nil, + c: "this is a string", + d: [{}, [[1, 2, 4, 8, 16]]] +})); +test_func(""); +println(); + var test_json = func(json) { var bar = process_bar.high_resolution_bar(30); var tmp = [