json: decode_array fix

pull/4732/head
Alexander Medvednikov 2020-05-05 14:19:31 +02:00
parent ef6c418eb6
commit ee92060d4d
5 changed files with 14 additions and 8 deletions

View File

@ -735,7 +735,8 @@ pub fn (mut c Checker) call_fn(call_expr mut ast.CallExpr) table.Type {
} else if fn_name == 'json.decode' { } else if fn_name == 'json.decode' {
expr := call_expr.args[0].expr expr := call_expr.args[0].expr
if !(expr is ast.Type) { if !(expr is ast.Type) {
c.error('json.decode: first argument needs to be a type', call_expr.pos) typ := typeof(expr)
c.error('json.decode: first argument needs to be a type, got `$typ`', call_expr.pos)
return table.void_type return table.void_type
} }
typ := expr as ast.Type typ := expr as ast.Type

View File

@ -124,7 +124,7 @@ fn (mut g Gen) decode_array(value_type table.Type) string {
if is_js_prim(styp) { if is_js_prim(styp) {
s = '$styp val = ${fn_name}(jsval); ' s = '$styp val = ${fn_name}(jsval); '
} else { } else {
s = '\t$styp val; ${fn_name}(jsval, &val); ' s = '\t$styp val = *($styp*) ${fn_name}(jsval).data; '
} }
return ' return '
res = __new_array(0, 0, sizeof($styp)); res = __new_array(0, 0, sizeof($styp));

View File

@ -22,7 +22,7 @@ pub fn (mut p Parser) call_expr(is_c, is_js bool, mod string) ast.CallExpr {
} }
if fn_name == 'json.decode' { if fn_name == 'json.decode' {
// Makes name_expr() parse the type (`User` in `json.decode(User, txt)`)` // Makes name_expr() parse the type (`User` in `json.decode(User, txt)`)`
p.inside_is = true p.expecting_type = true
p.expr_mod = '' p.expr_mod = ''
} }
p.check(.lpar) p.check(.lpar)

View File

@ -42,7 +42,7 @@ mut:
inside_match bool // to separate `match A { }` from `Struct{}` inside_match bool // to separate `match A { }` from `Struct{}`
inside_match_case bool // to separate `match_expr { }` from `Struct{}` inside_match_case bool // to separate `match_expr { }` from `Struct{}`
is_stmt_ident bool // true while the beginning of a statement is an ident/selector is_stmt_ident bool // true while the beginning of a statement is an ident/selector
inside_is bool // `is Type`, expecting type expecting_type bool // `is Type`, expecting type
} }
// for tests // for tests
@ -584,8 +584,8 @@ pub fn (mut p Parser) parse_ident(is_c, is_js bool) ast.Ident {
pub fn (mut p Parser) name_expr() ast.Expr { pub fn (mut p Parser) name_expr() ast.Expr {
mut node := ast.Expr{} mut node := ast.Expr{}
if p.inside_is { if p.expecting_type {
p.inside_is = false p.expecting_type = false
// get type position before moving to next // get type position before moving to next
type_pos := p.tok.position() type_pos := p.tok.position()
typ := p.parse_type() typ := p.parse_type()

View File

@ -62,8 +62,13 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
node = p.if_expr() node = p.if_expr()
} }
.lsbr { .lsbr {
if p.expecting_type {
// parse json.decode type (`json.decode([]User, s)`)
node = p.name_expr()
} else {
node = p.array_init() node = p.array_init()
} }
}
.key_none { .key_none {
p.next() p.next()
node = ast.None{} node = ast.None{}
@ -190,7 +195,7 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr {
p.next() p.next()
mut right := ast.Expr{} mut right := ast.Expr{}
if op == .key_is { if op == .key_is {
p.inside_is = true p.expecting_type = true
} }
right = p.expr(precedence) right = p.expr(precedence)
return ast.InfixExpr{ return ast.InfixExpr{