merge module/json.cpp into builtins

This commit is contained in:
ValKmjolnir 2023-12-10 23:55:18 +08:00
parent 49ebdc8e19
commit c59743b2ed
12 changed files with 163 additions and 464 deletions

View File

@ -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)

View File

@ -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\

View File

@ -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);
}

View File

@ -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

View File

@ -1,6 +1,4 @@
#include "../src/nasal.h"
#include "../src/nasal_type.h"
#include "../src/nasal_gc.h"
#include "json_lib.h"
#include <iostream>
#include <cstring>
@ -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");
}
return ngc->newstr(json().stringify(object));
void json_destructor(void* ptr) {
delete static_cast<json*>(ptr);
}
var parse(var* args, usize size, gc* ngc) {
auto input = args[0];
if (!input.is_str()) {
return nas_err("json::parse", "must use string");
}
return json().parse(input.str(), ngc);
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 get_error(var* args, usize size, gc* ngc) {
return ngc->newstr(json::get_error());
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.");
}
auto json_ptr = static_cast<json*>(json_object.ghost().pointer);
return ngc->newstr(json_ptr->stringify(object));
}
module_func_info func_tbl[] = {
{"stringify", stringify},
{"parse", parse},
{"get_error", get_error},
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.");
}
if (!input_string.is_str()) {
return nas_err("json::parse", "require string as the input.");
}
auto json_ptr = static_cast<json*>(json_object.ghost().pointer);
return json_ptr->parse(input_string.str(), ngc);
}
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*>(json_object.ghost().pointer);
return ngc->newstr(json_ptr->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;
}
}

16
src/json_lib.h Normal file
View File

@ -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[];
}

View File

@ -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) {

View File

@ -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"

View File

@ -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 and !check()) {
if (char(text[ptr])=='\n') {
line += 1;
}
ptr += 1;
}
if (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(ptr<text_size and char(text[ptr])!=strbegin) {
s ~= char(text[ptr]);
ptr += 1;
if (char(text[ptr-1])=="\\" and ptr<text_size) {
s ~= char(text[ptr]);
ptr += 1;
}
}
token.content=s;
token.type=_j_str;
} elsif (isnum(c)) {
var s = c;
ptr += 1;
while(ptr<text_size and ((
isnum(char(text[ptr])) or
char(text[ptr])=='.' or
char(text[ptr])=='e' or
char(text[ptr])=='-' or
char(text[ptr])=='+'))
) {
s ~= char(text[ptr]);
ptr += 1;
}
ptr -= 1;
token.content = num(s);
token.type = _j_num;
} elsif (isid(c)) {
var s = c;
ptr += 1;
while(ptr<text_size and (isid(char(text[ptr])) or isnum(char(text[ptr])))) {
s ~= char(text[ptr]);
ptr += 1;
}
ptr -= 1;
token.content = s;
token.type = _j_id;
if (s=="true" or s=="false") {
token.type = _j_bool;
}
}
ptr += 1;
return;
}
var match = func(type) {
if (token.type!=type) {
println("json::parse: line ",line,": expect ",_j_content[type]," but get `",token.content,"`.");
_parse_error += 1;
}
next();
return;
}
var member = func(hash) {
var name = token.content;
if (token.type==_j_rbrace) {
return;
}
if (token.type==_j_str) {
match(_j_str);
} else {
match(_j_id);
}
match(_j_colon);
if (token.type==_j_lbrace) {
hash[name] = hash_gen();
} elsif (token.type==_j_lbrkt) {
hash[name] = vec_gen();
} elsif (token.type==_j_str or token.type==_j_num or token.type==_j_bool) {
hash[name] = token.content;
next();
}
return;
}
var hash_gen = func() {
var hash = {};
match(_j_lbrace);
member(hash);
while(token.type==_j_comma) {
match(_j_comma);
member(hash);
}
match(_j_rbrace);
return hash;
}
var vec_gen = func() {
var vec = [];
match(_j_lbrkt);
if (token.type==_j_lbrace) {
append(vec, hash_gen());
} elsif (token.type==_j_lbrkt) {
append(vec, vec_gen());
} elsif (token.type==_j_str or token.type==_j_num) {
append(vec, token.content);
next();
}
while(token.type==_j_comma) {
match(_j_comma);
if (token.type==_j_lbrace) {
append(vec, hash_gen());
} elsif (token.type==_j_lbrkt) {
append(vec, vec_gen());
} elsif (token.type==_j_str or token.type==_j_num) {
append(vec, token.content);
next();
}
}
match(_j_rbrkt);
return vec;
}
return func(source) {
_parse_error = 0;
if (typeof(source)!="str") {
println("json::parse: must use string but get", typeof(str));
_parse_error += 1;
return [];
}
get(source);
next();
if (token.type==_j_lbrkt) {
var res = vec_gen();
} else {
var res = hash_gen();
}
init();
return res;
}
var _json = func() {
return _json_new();
}();
var _stringify = func(json_object, object) {
return _json_stringify(json_object, object);
}
var _parse = func(json_object, input_string) {
return _json_parse(json_object, input_string);
}
var _get_error = func(json_object) {
return _json_get_error(json_object);
}
var stringify = func(object) {
_parse_error = 0;
var object_type = typeof(object);
if (object_type!="hash" and object_type!="vec" and object_type!="namespace") {
_parse_error += 1;
println("json::stringify: must use hashmap or vector, but get ", typeof(object));
return "[]";
return _stringify(_json, object);
}
var s = "";
var gen = func(elem) {
var t = typeof(elem);
if (t=="num") {
s ~= str(elem);
} elsif (t=="str") {
s ~= '"'~elem~'"';
} elsif (t=="vec") {
vgen(elem);
} elsif (t=="hash") {
hgen(elem);
} else {
s ~= '"undefined"';
}
}
var vgen = func(v) {
s ~= "[";
var vsize = size(v);
for(var i = 0; i<vsize; i += 1) {
gen(v[i]);
if (i!=vsize-1) {
s~=",";
}
}
s ~= "]";
}
var hgen = func(h) {
s ~= "{";
var k = keys(h);
var vsize = size(k);
for(var i = 0; i<vsize; i += 1) {
s ~= "\""~k[i]~"\":";
gen(h[k[i]]);
if (i!=vsize-1) {
s ~= ",";
}
}
s ~= "}";
}
if (typeof(object)=="vec") {
vgen(object);
} else {
hgen(object);
}
return s;
var parse = func(input_string) {
return _parse(_json, input_string);
}
var get_error = func() {
return _parse_error;
}
var check_error = func() {
if (_parse_error==0) {
return;
}
println("json: encounter ", _parse_error, " error(s), stop.");
exit(-1);
return _get_error(_json);
}

View File

@ -4,7 +4,7 @@
# 2023/11/06 ValKmjolnir
use module.libsock;
use module.libjson;
use std.json;
use std.os;
use std.unix;
@ -87,9 +87,9 @@ var new = func(hostname, port) {
var data = substr(total_source, begin_position, length);
# parse this json and return
var props = libjson.parse(data);
if (size(libjson.get_error())>0) {
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};
}

View File

@ -10,6 +10,7 @@
# available in C++; just use node.getNode(path).whatever() instead.
#
use std.math;
use std.string;
var _new = func {
return {

View File

@ -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");
for(var i = 0; i<10; i += 1) {
stamp.stamp();
test_json(json);
println("time usage: ", stamp.elapsedUSec()/1000, " ms");
}