From c59743b2eda9c8f05fdc107331ad019e19eac4fa Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Sun, 10 Dec 2023 23:55:18 +0800 Subject: [PATCH] :zap: merge module/json.cpp into builtins --- CMakeLists.txt | 5 +- makefile | 9 + module/libjson.nas | 24 -- module/makefile | 17 +- module/json.cpp => src/json_lib.cpp | 189 ++++++++-------- src/json_lib.h | 16 ++ src/nasal_codegen.cpp | 1 + src/nasal_codegen.h | 1 + std/json.nas | 337 ++-------------------------- std/phi.nas | 8 +- std/props.nas | 1 + test/json.nas | 19 +- 12 files changed, 163 insertions(+), 464 deletions(-) delete mode 100644 module/libjson.nas rename module/json.cpp => src/json_lib.cpp (58%) create mode 100644 src/json_lib.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 88e34ca..b230a31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ set(NASAL_OBJECT_SOURCE_FILE ${CMAKE_SOURCE_DIR}/src/fg_props.cpp ${CMAKE_SOURCE_DIR}/src/bits_lib.cpp ${CMAKE_SOURCE_DIR}/src/io_lib.cpp + ${CMAKE_SOURCE_DIR}/src/json_lib.cpp ${CMAKE_SOURCE_DIR}/src/math_lib.cpp ${CMAKE_SOURCE_DIR}/src/dylib_lib.cpp ${CMAKE_SOURCE_DIR}/src/unix_lib.cpp @@ -85,7 +86,3 @@ target_link_libraries(mat module-used-object) add_library(nasock SHARED ${CMAKE_SOURCE_DIR}/module/nasocket.cpp) target_include_directories(nasock PRIVATE ${CMAKE_SOURCE_DIR}/src) target_link_libraries(nasock module-used-object) - -add_library(json SHARED ${CMAKE_SOURCE_DIR}/module/json.cpp) -target_include_directories(json PRIVATE ${CMAKE_SOURCE_DIR}/src) -target_link_libraries(json module-used-object) diff --git a/makefile b/makefile index e1d3c94..af03a18 100644 --- a/makefile +++ b/makefile @@ -32,6 +32,7 @@ NASAL_HEADER = \ src/io_lib.h\ src/math_lib.h\ src/dylib_lib.h\ + src/json_lib.h\ src/unix_lib.h\ src/coroutine.h\ src/repl.h @@ -57,6 +58,7 @@ NASAL_OBJECT = \ build/math_lib.o\ build/unix_lib.o\ build/dylib_lib.o\ + build/json_lib.o\ build/coroutine.o\ build/nasal_type.o\ build/nasal_vm.o\ @@ -161,6 +163,13 @@ build/dylib_lib.o: \ src/dylib_lib.h src/dylib_lib.cpp | build $(CXX) $(CXXFLAGS) src/dylib_lib.cpp -o build/dylib_lib.o +build/json_lib.o: \ + src/nasal.h\ + src/nasal_type.h\ + src/nasal_gc.h\ + src/json_lib.h src/json_lib.cpp | build + $(CXX) $(CXXFLAGS) src/json_lib.cpp -o build/json_lib.o + build/unix_lib.o: \ src/nasal.h\ src/nasal_type.h\ diff --git a/module/libjson.nas b/module/libjson.nas deleted file mode 100644 index e9209a3..0000000 --- a/module/libjson.nas +++ /dev/null @@ -1,24 +0,0 @@ -# module json -# 2023/11/27 ValKmjolnir - -use std.dylib; -use std.os; - -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) { - return _call(_stringify, 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/module/makefile b/module/makefile index dcfb025..17fe33b 100644 --- a/module/makefile +++ b/module/makefile @@ -1,7 +1,7 @@ .PHONY = clean all winall -dynamic_libs_so = libfib.so libkey.so libnasock.so libmat.so libjson.so -dynamic_libs_dll = libfib.dll libkey.dll libnasock.dll libmat.dll libjson.dll +dynamic_libs_so = libfib.so libkey.so libnasock.so libmat.so +dynamic_libs_dll = libfib.dll libkey.dll libnasock.dll libmat.dll used_header = ../src/nasal.h ../src/nasal_type.h ../src/nasal_gc.h used_object = ../build/nasal_misc.o ../build/nasal_type.o ../build/nasal_gc.o @@ -66,25 +66,12 @@ libmat.dll: matrix.cpp $(used_header) $(used_object) @ $(CXX) -shared -o libmat.dll matrix.o $(used_object) -static @ del matrix.o -libjson.so: json.cpp $(used_header) $(used_object) - @ echo "[Compiling] libjson.so" - @ $(CXX) $(CXXFLAGS) json.cpp -o json.o - @ $(CXX) -shared -o libjson.so json.o $(used_object) - @ rm json.o -libjson.dll: json.cpp $(used_header) $(used_object) - @ echo [Compiling] libjson.dll - @ $(CXX) -std=$(STD) -c -O3 json.cpp -fPIC -o json.o -static - @ $(CXX) -shared -o libjson.dll json.o $(used_object) -static - @ del json.o - clean: @ echo "[clean] libfib.so" && if [ -e libfib.so ]; then rm libfib.so; fi @ echo "[clean] libkey.so" && if [ -e libkey.so ]; then rm libkey.so; fi @ echo "[clean] libnasock.so" && if [ -e libnasock.so ]; then rm libnasock.so; fi @ echo "[clean] libmat.so" && if [ -e libmat.so ]; then rm libmat.so; fi - @ echo "[clean] libjson.so" && if [ -e libjson.so ]; then rm libjson.so; fi @ echo "[clean] libfib.dll" &&if [ -e libfib.dll ]; then rm libfib.dll; fi @ echo "[clean] libkey.dll" &&if [ -e libkey.dll ]; then rm libkey.dll; fi @ echo "[clean] libnasock.dll" &&if [ -e libnasock.dll ]; then rm libnasock.dll; fi @ echo "[clean] libmat.dll" &&if [ -e libmat.dll ]; then rm libmat.dll; fi - @ echo "[clean] libjson.dll" && if [ -e libjson.dll ]; then rm libjson.dll; fi diff --git a/module/json.cpp b/src/json_lib.cpp similarity index 58% rename from module/json.cpp rename to src/json_lib.cpp index e1d4268..3948c9a 100644 --- a/module/json.cpp +++ b/src/json_lib.cpp @@ -1,6 +1,4 @@ -#include "../src/nasal.h" -#include "../src/nasal_type.h" -#include "../src/nasal_gc.h" +#include "json_lib.h" #include #include @@ -9,7 +7,7 @@ namespace nasal { -enum class token_type { +enum class json_token_type { tok_eof, tok_lbrace, tok_rbrace, @@ -23,26 +21,26 @@ enum class token_type { tok_bool }; -std::string get_content(token_type type) { +std::string get_content(json_token_type type) { switch(type) { - case token_type::tok_eof: return "eof"; - case token_type::tok_lbrace: return "`{`"; - case token_type::tok_rbrace: return "`}`"; - case token_type::tok_lbrkt: return "`[`"; - case token_type::tok_rbrkt: return "`]`"; - case token_type::tok_comma: return "`,`"; - case token_type::tok_colon: return "`:`"; - case token_type::tok_str: return "string"; - case token_type::tok_num: return "number"; - case token_type::tok_id: return "identifier"; - case token_type::tok_bool: return "boolean"; + case json_token_type::tok_eof: return "eof"; + case json_token_type::tok_lbrace: return "`{`"; + case json_token_type::tok_rbrace: return "`}`"; + case json_token_type::tok_lbrkt: return "`[`"; + case json_token_type::tok_rbrkt: return "`]`"; + case json_token_type::tok_comma: return "`,`"; + case json_token_type::tok_colon: return "`:`"; + case json_token_type::tok_str: return "string"; + case json_token_type::tok_num: return "number"; + case json_token_type::tok_id: return "identifier"; + case json_token_type::tok_bool: return "boolean"; } // unreachable return ""; } struct token { - token_type type; + json_token_type type; std::string content; }; @@ -53,6 +51,7 @@ private: usize ptr = 0; token this_token; var temp_stack = nil; + std::string info = ""; private: std::string var_generate(var&); @@ -72,21 +71,20 @@ private: c=='-' || c=='+' || is_num(c) || is_id(c); } void next(); - void match(token_type); + void match(json_token_type); void vector_member(nas_vec&, gc*); 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 = ""; + std::string& error_info() { return info; } public: std::string stringify(var&); var parse(const std::string&, gc*); - static const std::string& get_error() { return error_info(); } + const std::string& get_error() { return error_info(); } }; std::string json::var_generate(var& value) { @@ -164,17 +162,17 @@ void json::next() { ++ptr; } if (ptr>=text.length()) { - this_token = {token_type::tok_eof, "eof"}; + this_token = {json_token_type::tok_eof, "eof"}; return; } auto c = text[ptr]; switch(c) { - case '{': this_token = {token_type::tok_lbrace, "{"}; ++ptr; return; - case '}': this_token = {token_type::tok_rbrace, "}"}; ++ptr; return; - case '[': this_token = {token_type::tok_lbrkt, "["}; ++ptr; return; - case ']': this_token = {token_type::tok_rbrkt, "]"}; ++ptr; return; - case ',': this_token = {token_type::tok_comma, ","}; ++ptr; return; - case ':': this_token = {token_type::tok_colon, ":"}; ++ptr; return; + case '{': this_token = {json_token_type::tok_lbrace, "{"}; ++ptr; return; + case '}': this_token = {json_token_type::tok_rbrace, "}"}; ++ptr; return; + case '[': this_token = {json_token_type::tok_lbrkt, "["}; ++ptr; return; + case ']': this_token = {json_token_type::tok_rbrkt, "]"}; ++ptr; return; + case ',': this_token = {json_token_type::tok_comma, ","}; ++ptr; return; + case ':': this_token = {json_token_type::tok_colon, ":"}; ++ptr; return; default: break; } if (is_num(c) || c=='-' || c=='+') { @@ -190,7 +188,7 @@ void json::next() { ++ptr; } --ptr; - this_token = {token_type::tok_num, temp}; + this_token = {json_token_type::tok_num, temp}; } else if (is_id(c)) { auto temp = std::string(1, c); ++ptr; @@ -200,9 +198,9 @@ void json::next() { } --ptr; if (temp=="true" || temp=="false") { - this_token = {token_type::tok_bool, temp}; + this_token = {json_token_type::tok_bool, temp}; } else { - this_token = {token_type::tok_id, temp}; + this_token = {json_token_type::tok_id, temp}; } } else if (c=='"' || c=='\'') { auto begin = c; @@ -216,13 +214,13 @@ void json::next() { ++ptr; } } - this_token = {token_type::tok_str, temp}; + this_token = {json_token_type::tok_str, temp}; } ++ptr; return; } -void json::match(token_type type) { +void json::match(json_token_type type) { if (this_token.type!=type) { error_info() += "json::parse: line " + std::to_string(line); error_info() += ": expect " + get_content(type) + " but get `"; @@ -233,14 +231,14 @@ void json::match(token_type type) { } void json::vector_member(nas_vec& vec, gc* ngc) { - if (this_token.type==token_type::tok_lbrace) { + if (this_token.type==json_token_type::tok_lbrace) { vec.elems.push_back(hash_object_generate(ngc)); - } else if (this_token.type==token_type::tok_lbrkt) { + } else if (this_token.type==json_token_type::tok_lbrkt) { vec.elems.push_back(vector_object_generate(ngc)); - } else if (this_token.type==token_type::tok_str) { + } else if (this_token.type==json_token_type::tok_str) { vec.elems.push_back(ngc->newstr(this_token.content)); next(); - } else if (this_token.type==token_type::tok_num) { + } else if (this_token.type==json_token_type::tok_num) { vec.elems.push_back(var::num(str_to_num(this_token.content.c_str()))); next(); } @@ -249,37 +247,37 @@ void json::vector_member(nas_vec& vec, gc* ngc) { var json::vector_object_generate(gc* ngc) { auto vect_object = ngc->alloc(vm_type::vm_vec); temp_stack.vec().elems.push_back(vect_object); - match(token_type::tok_lbrkt); + match(json_token_type::tok_lbrkt); vector_member(vect_object.vec(), ngc); - while(this_token.type==token_type::tok_comma) { - match(token_type::tok_comma); + while(this_token.type==json_token_type::tok_comma) { + match(json_token_type::tok_comma); vector_member(vect_object.vec(), ngc); } - match(token_type::tok_rbrkt); + match(json_token_type::tok_rbrkt); temp_stack.vec().elems.pop_back(); return vect_object; } void json::hash_member(nas_hash& hash, gc* ngc) { const auto name = this_token.content; - if (this_token.type==token_type::tok_rbrace) { + if (this_token.type==json_token_type::tok_rbrace) { return; } - if (this_token.type==token_type::tok_str) { - match(token_type::tok_str); + if (this_token.type==json_token_type::tok_str) { + match(json_token_type::tok_str); } else { - match(token_type::tok_id); + match(json_token_type::tok_id); } - match(token_type::tok_colon); - if (this_token.type==token_type::tok_lbrace) { + match(json_token_type::tok_colon); + if (this_token.type==json_token_type::tok_lbrace) { hash.elems.insert({name, hash_object_generate(ngc)}); - } else if (this_token.type==token_type::tok_lbrkt) { + } else if (this_token.type==json_token_type::tok_lbrkt) { hash.elems.insert({name, vector_object_generate(ngc)}); - } else if (this_token.type==token_type::tok_str || - this_token.type==token_type::tok_bool) { + } else if (this_token.type==json_token_type::tok_str || + this_token.type==json_token_type::tok_bool) { hash.elems.insert({name, ngc->newstr(this_token.content)}); next(); - } else if (this_token.type==token_type::tok_num) { + } else if (this_token.type==json_token_type::tok_num) { hash.elems.insert({name, var::num(str_to_num(this_token.content.c_str()))}); next(); } @@ -288,91 +286,106 @@ void json::hash_member(nas_hash& hash, gc* ngc) { var json::hash_object_generate(gc* ngc) { auto hash_object = ngc->alloc(vm_type::vm_hash); temp_stack.vec().elems.push_back(hash_object); - match(token_type::tok_lbrace); + match(json_token_type::tok_lbrace); hash_member(hash_object.hash(), ngc); - while(this_token.type==token_type::tok_comma) { - match(token_type::tok_comma); + while(this_token.type==json_token_type::tok_comma) { + match(json_token_type::tok_comma); hash_member(hash_object.hash(), ngc); } - match(token_type::tok_rbrace); + match(json_token_type::tok_rbrace); temp_stack.vec().elems.pop_back(); return hash_object; } void json::check_eof() { next(); - if (this_token.type==token_type::tok_eof) { + if (this_token.type==json_token_type::tok_eof) { return; } - while (this_token.type!=token_type::tok_eof) { + while (this_token.type!=json_token_type::tok_eof) { error_info() += "json::parse: line " + std::to_string(line); - error_info() += ": expect " + get_content(token_type::tok_eof); + error_info() += ": expect " + get_content(json_token_type::tok_eof); error_info() += " but get `" + this_token.content + "`.\n"; next(); } } var json::parse(const std::string& input, gc* ngc) { - usize parse_error = 0; - usize line = 1; - usize ptr = 0; - this_token = {token_type::tok_eof, ""}; + line = 1; + ptr = 0; + this_token = {json_token_type::tok_eof, ""}; error_info() = ""; if (input.empty()) { error_info() += "json::parse: empty string.\n"; - ++parse_error; return nil; } text = input; next(); - if (this_token.type==token_type::tok_lbrkt) { + if (this_token.type==json_token_type::tok_lbrkt) { ngc->temp = temp_stack = ngc->alloc(vm_type::vm_vec); auto result = vector_object_generate(ngc); check_eof(); - ngc->temp = nil; - temp_stack = nil; + ngc->temp = 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; + ngc->temp = temp_stack = nil; return result; } return nil; } -var stringify(var* args, usize size, gc* ngc) { - auto object = args[0]; - if (!object.is_vec() && !object.is_hash()) { - return nas_err("json::stringify", "must use hashmap or vector"); +void json_destructor(void* ptr) { + delete static_cast(ptr); +} + +var builtin_json_new(context* ctx, gc* ngc) { + var res = ngc->alloc(vm_type::vm_ghost); + res.ghost().set("nasal::json", json_destructor, nullptr, new json); + return res; +} + +var builtin_json_stringify(context* ctx, gc* ngc) { + auto json_object = ctx->localr[1]; + auto object = ctx->localr[2]; + if (!json_object.object_check("nasal::json")) { + return nas_err("json::stringify", "expect a json object."); } - return ngc->newstr(json().stringify(object)); + auto json_ptr = static_cast(json_object.ghost().pointer); + return ngc->newstr(json_ptr->stringify(object)); } -var parse(var* args, usize size, gc* ngc) { - auto input = args[0]; - if (!input.is_str()) { - return nas_err("json::parse", "must use string"); +var builtin_json_parse(context* ctx, gc* ngc) { + auto json_object = ctx->localr[1]; + auto input_string = ctx->localr[2]; + if (!json_object.object_check("nasal::json")) { + return nas_err("json::parse", "expect a json object."); } - return json().parse(input.str(), ngc); + if (!input_string.is_str()) { + return nas_err("json::parse", "require string as the input."); + } + auto json_ptr = static_cast(json_object.ghost().pointer); + return json_ptr->parse(input_string.str(), ngc); } -var get_error(var* args, usize size, gc* ngc) { - return ngc->newstr(json::get_error()); +var builtin_json_get_error(context* ctx, gc* ngc) { + auto json_object = ctx->localr[1]; + if (!json_object.object_check("nasal::json")) { + return nas_err("json::get_error", "expect a json object."); + } + auto json_ptr = static_cast(json_object.ghost().pointer); + return ngc->newstr(json_ptr->get_error()); } -module_func_info func_tbl[] = { - {"stringify", stringify}, - {"parse", parse}, - {"get_error", get_error}, +nasal_builtin_table json_lib_native[] = { + {"_json_new", builtin_json_new}, + {"_json_stringify", builtin_json_stringify}, + {"_json_parse", builtin_json_parse}, + {"_json_get_error", builtin_json_get_error}, {nullptr, nullptr} }; -NASAL_EXTERN module_func_info* get() { - return func_tbl; -} - } \ No newline at end of file diff --git a/src/json_lib.h b/src/json_lib.h new file mode 100644 index 0000000..ddec72a --- /dev/null +++ b/src/json_lib.h @@ -0,0 +1,16 @@ +#pragma once + +#include "nasal.h" +#include "nasal_gc.h" +#include "nasal_builtin.h" + +namespace nasal { + +var builtin_json_new(context*, gc*); +var builtin_json_stringify(context*, gc*); +var builtin_json_parse(context*, gc*); +var builtin_json_get_error(context*, gc*); + +extern nasal_builtin_table json_lib_native[]; + +} \ No newline at end of file diff --git a/src/nasal_codegen.cpp b/src/nasal_codegen.cpp index 7c5a72c..95a135e 100644 --- a/src/nasal_codegen.cpp +++ b/src/nasal_codegen.cpp @@ -30,6 +30,7 @@ void codegen::init_native_function() { load_native_function_table(flight_gear_native); load_native_function_table(dylib_lib_native); load_native_function_table(unix_lib_native); + load_native_function_table(json_lib_native); } void codegen::check_id_exist(identifier* node) { diff --git a/src/nasal_codegen.h b/src/nasal_codegen.h index af1635c..221a0d3 100644 --- a/src/nasal_codegen.h +++ b/src/nasal_codegen.h @@ -14,6 +14,7 @@ #include "math_lib.h" #include "fg_props.h" #include "io_lib.h" +#include "json_lib.h" #include "dylib_lib.h" #include "unix_lib.h" diff --git a/std/json.nas b/std/json.nas index 8aab185..27a443f 100644 --- a/std/json.nas +++ b/std/json.nas @@ -1,329 +1,30 @@ # lib json.nas # 2021 ValKmjolnir -var ( - _j_eof, - _j_lbrace, - _j_rbrace, - _j_lbrkt, - _j_rbrkt, - _j_comma, - _j_colon, - _j_str, - _j_num, - _j_id, - _j_bool -) = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); - -var _j_content = [ - "eof", - "`{`", - "`}`", - "`[`", - "`]`", - "`,`", - "`:`", - "string", - "number", - "identifier", - "boolean" -]; - -var _parse_error = 0; - -var parse = func() { - var text = ""; - var line = 1; - var text_size = 0; - var ptr = 0; - var token = { - content: "", - type: "" - }; - - var init = func() { - text = ""; - line = 1; - text_size = 0; - ptr = 0; - token = { - content: "", - type: "" - }; - } - - var isnum = func(c) { - return '0'<=c and c<='9'; - } - - var isid = func(c) { - var tmp = c[0]; - return ('a'[0]<=tmp and tmp<='z'[0]) or - ('A'[0]<=tmp and tmp<='Z'[0]) or - c=='_'; - } - - var check = func() { - var c = char(text[ptr]); - return ( - c=='{' or c=='}' or - c=='[' or c==']' or - c==',' or c==':' or - c=='\"' or c=='\'' or - isnum(c) or isid(c) - ); - } - - var get = func(str) { - init(); - if (!size(str)) { - println("json::parse: empty string"); - _parse_error += 1; - str = "[]"; - } - text = str; - text_size = size(text); - return; - } - - var next = func() { - while(ptr=text_size) { - token.content = "eof"; - token.type = _j_eof; - return; - } - - var c = char(text[ptr]); - if (c=='{') { - token.content = '{'; - token.type = _j_lbrace; - } elsif (c=='}') { - token.content = '}'; - token.type = _j_rbrace; - } elsif (c=='[') { - token.content = '['; - token.type = _j_lbrkt; - } elsif (c==']') { - token.content = ']'; - token.type = _j_rbrkt; - } elsif (c==',') { - token.content = ','; - token.type = _j_comma; - } elsif (c==':') { - token.content = ':'; - token.type = _j_colon; - } elsif (c=='\"' or c=='\'') { - var strbegin = c; - var s = ""; - ptr += 1; - while(ptr0) { - println("encounter error when parsing \"", path, "\":\n", libjson.get_error()); + var props = json.parse(data); + if (size(json.get_error())>0) { + println("encounter error when parsing \"", path, "\":\n", json.get_error()); logprint(LOG_DEBUG, _raw_str(data)); return {path: path}; } diff --git a/std/props.nas b/std/props.nas index 1a31dba..202aa15 100644 --- a/std/props.nas +++ b/std/props.nas @@ -10,6 +10,7 @@ # available in C++; just use node.getNode(path).whatever() instead. # use std.math; +use std.string; var _new = func { return { diff --git a/test/json.nas b/test/json.nas index f0a23d6..0e24d05 100644 --- a/test/json.nas +++ b/test/json.nas @@ -1,5 +1,4 @@ use std.json; -use module.libjson; use std.process_bar; var ss = json.stringify({ @@ -19,7 +18,6 @@ var ss = json.stringify({ println(ss, "\n"); println(json.parse(ss), "\n"); -println(libjson.parse(ss), "\n"); var ss = json.stringify([{ vec:[0,1,2,3], @@ -37,11 +35,10 @@ var ss = json.stringify([{ 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(); + var result = json.parse(input_string); + var errno = json.get_error(); if (!size(errno)) { println("\e[92;1msuccess\e[0m:"); println(" ", result); @@ -60,7 +57,7 @@ test_func("{\"1\":1}"); test_func("[[[}]]]"); test_func("=-==_+_+_+"); test_func("123"); -test_func(libjson.stringify({ +test_func(json.stringify({ a: 0, b: nil, c: "this is a string", @@ -100,8 +97,8 @@ var test_json = func(json) { }; var stamp = maketimestamp(); -test_json(libjson); -println("time usage: ", stamp.elapsedUSec()/1000, " ms"); -stamp.stamp(); -test_json(json); -println("time usage: ", stamp.elapsedUSec()/1000, " ms"); +for(var i = 0; i<10; i += 1) { + stamp.stamp(); + test_json(json); + println("time usage: ", stamp.elapsedUSec()/1000, " ms"); +}