json: decode() part 1

pull/4665/head
Alexander Medvednikov 2020-05-01 12:02:31 +02:00
parent a0e662bef9
commit c1ee14cc3e
3 changed files with 22 additions and 46 deletions

View File

@ -12,7 +12,7 @@ struct C.cJSON {
valuestring byteptr
}
pub fn decode() ?voidptr {
pub fn decode(typ voidptr, s string) ?voidptr {
// compiler implementation
return 0
}

View File

@ -607,12 +607,10 @@ pub fn (mut c Checker) call_method(call_expr mut ast.CallExpr) table.Type {
mut scope := c.file.scope.innermost(call_expr.pos.pos)
scope.update_var_type('it', array_info.elem_type)
}
mut arg_type := left_type
for arg in call_expr.args {
arg_type = c.expr(arg.expr)
}
call_expr.return_type = left_type
call_expr.receiver_type = left_type
if method_name == 'map' && call_expr.args.len == 1 {
@ -687,17 +685,13 @@ pub fn (mut c Checker) call_method(call_expr mut ast.CallExpr) table.Type {
return table.string_type
}
// call struct field fn type
// TODO: can we use SelectorExpr for all? this dosent really belong here
// TODO: can we use SelectorExpr for all?
if field := c.table.struct_find_field(left_type_sym, method_name) {
field_type_sym := c.table.get_type_symbol(field.typ)
if field_type_sym.kind == .function {
call_expr.is_method = false
info := field_type_sym.info as table.FnType
call_expr.return_type = info.func.return_type
// TODO: check args (do it once for all of the above)
for i, arg in call_expr.args {
arg_typ := c.expr(arg.expr)
}
return info.func.return_type
}
}
@ -722,6 +716,13 @@ pub fn (mut c Checker) call_fn(call_expr mut ast.CallExpr) table.Type {
// }
if fn_name == 'json.encode' {
}
if fn_name == 'json.decode' {
ident := call_expr.args[0].expr as ast.Ident
// sym := c.table.find_type(ident.name)
idx := c.table.find_type_idx(ident.name)
println('js.decode t=$ident.name')
return table.Type(idx)
}
// look for function in format `mod.fn` or `fn` (main/builtin)
mut f := table.Fn{}
mut found := false
@ -1720,6 +1721,10 @@ pub fn (mut c Checker) ident(ident mut ast.Ident) table.Type {
if ident.is_c {
return table.int_type
}
if c.table.known_type(ident.name) {
// e.g. `User` in `json.decode(User, '...')`
return table.void_type
}
if ident.name != '_' {
c.error('undefined: `$ident.name`', ident.pos)
}

View File

@ -26,53 +26,24 @@ fn (mut g Gen) gen_json_for_type(typ table.Type) {
return
}
// println('gen_json_for_type($typ.name)')
// Register decoder fn
/*
mut dec_fn := Fn{
mod: p.mod
typ: 'Option_$typ.name'
name: js_dec_name(t)
}
if p.table.known_fn(dec_fn.name) {
// Already registered? Skip.
return
}
// decode_TYPE funcs receive an actual cJSON* object to decode
// cJSON_Parse(str) call is added by the compiler
arg := Var{
typ: 'cJSON*'
}
dec_fn.args << arg
p.table.register_fn(dec_fn)
// Register encoder fn
mut enc_fn := Fn{
mod: p.mod
typ: 'cJSON*'
name: js_enc_name(t)
}
// encode_TYPE funcs receive an object to encode
enc_arg := Var{
typ: t
}
enc_fn.args << enc_arg
p.table.register_fn(enc_fn)
// Code gen decoder
dec += '
//$t $dec_fn.name (cJSON* root) {
Option ${dec_fn.name}(cJSON* root, $t* res) {
// $t res;
dec_fn_name := js_dec_name(sym.name)
dec.writeln('
Option ${dec_fn_name}(cJSON* root, $styp* res) {
// $styp res;
if (!root) {
const char *error_ptr = cJSON_GetErrorPtr();
if (error_ptr != NULL) {
fprintf(stderr, "Error in decode() for $t error_ptr=: %%s\\n", error_ptr);
fprintf(stderr, "Error in decode() for $styp error_ptr=: %%s\\n", error_ptr);
// printf("\\nbad js=%%s\\n", js.str);
return v_error(tos2(error_ptr));
}
}
'
*/
')
// Code gen encoder
// encode_TYPE funcs receive an object to encode
enc_fn_name := js_enc_name(sym.name)
enc.writeln('
cJSON* ${enc_fn_name}($styp val) {
@ -111,7 +82,7 @@ cJSON* ${enc_fn_name}($styp val) {
// p.cgen.fns << '$dec return opt_ok(res); \n}'
dec.writeln('return opt_ok(res, sizeof(*res)); \n}')
enc.writeln('\treturn o;\n}')
// g.definitions.writeln(dec.str())
g.definitions.writeln(dec.str())
g.gowrappers.writeln(enc.str())
}