From f23948010ace5f3769288ef73d6c1edce4153015 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sun, 26 Apr 2020 17:28:43 +0200 Subject: [PATCH] parser: new array init syntax --- vlib/builtin/array_test.v | 5 +-- vlib/v/ast/ast.v | 4 +++ vlib/v/gen/cgen.v | 70 +++++++++++++++++++++++--------------- vlib/v/parser/containers.v | 26 ++++++++++++-- 4 files changed, 73 insertions(+), 32 deletions(-) diff --git a/vlib/builtin/array_test.v b/vlib/builtin/array_test.v index 7c5eeb7831..c5ee360db7 100644 --- a/vlib/builtin/array_test.v +++ b/vlib/builtin/array_test.v @@ -724,6 +724,7 @@ fn test_left_shift_precendence() { } fn test_array_with_cap() { - a := []int{cap:10, len:1 } - //assert a.len == 1 + a4 := []int{cap:10, len:1 } + assert a4.len == 1 + assert a4.cap == 10 } diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 2e55e3fbc3..3b9aaca323 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -635,6 +635,10 @@ pub: is_fixed bool has_val bool mod string + len_expr Expr + has_len bool + has_cap bool + cap_expr Expr mut: elem_type table.Type typ table.Type diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index dab75dcc9b..bb834a709a 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -963,33 +963,7 @@ fn (mut g Gen) expr(node ast.Expr) { // println('cgen expr() line_nr=$node.pos.line_nr') match node { ast.ArrayInit { - type_sym := g.table.get_type_symbol(it.typ) - if type_sym.kind != .array_fixed { - // elem_sym := g.table.get_type_symbol(it.elem_type) - elem_type_str := g.typ(it.elem_type) - if it.exprs.len == 0 { - // use __new_array to fix conflicts when the name of the variable is new_array - g.write('__new_array($it.exprs.len, $it.exprs.len, sizeof($elem_type_str))') - } else { - len := it.exprs.len - g.write('new_array_from_c_array($len, $len, sizeof($elem_type_str), ') - g.write('($elem_type_str[$len]){\n\t\t') - for expr in it.exprs { - g.expr(expr) - g.write(', ') - } - g.write('\n})') - } - } else { - g.write('{') - for i, expr in it.exprs { - g.expr(expr) - if i != it.exprs.len - 1 { - g.write(', ') - } - } - g.write('}') - } + g.array_init(it) } ast.AsCast { g.as_cast(it) @@ -3346,3 +3320,45 @@ ${interface_name} I_${cctype}_to_${interface_name}(${cctype} x) { } return sb.str() } + +fn (mut g Gen) array_init(it ast.ArrayInit) { + type_sym := g.table.get_type_symbol(it.typ) + if type_sym.kind != .array_fixed { + // elem_sym := g.table.get_type_symbol(it.elem_type) + elem_type_str := g.typ(it.elem_type) + if it.exprs.len == 0 { + g.write('__new_array(') + if it.has_len { + g.expr(it.len_expr) + g.write(', ') + } else { + g.write('0, ') + } + if it.has_cap { + g.expr(it.cap_expr) + g.write(', ') + } else { + g.write('0, ') + } + g.write('sizeof($elem_type_str))') + } else { + len := it.exprs.len + g.write('new_array_from_c_array($len, $len, sizeof($elem_type_str), ') + g.write('($elem_type_str[$len]){\n\t\t') + for expr in it.exprs { + g.expr(expr) + g.write(', ') + } + g.write('\n})') + } + } else { + g.write('{') + for i, expr in it.exprs { + g.expr(expr) + if i != it.exprs.len - 1 { + g.write(', ') + } + } + g.write('}') + } +} diff --git a/vlib/v/parser/containers.v b/vlib/v/parser/containers.v index ded9e69719..16dde699e4 100644 --- a/vlib/v/parser/containers.v +++ b/vlib/v/parser/containers.v @@ -70,16 +70,32 @@ fn (mut p Parser) array_init() ast.ArrayInit { if exprs.len == 0 && p.tok.kind != .lcbr && has_type { p.warn_with_pos('use `x := []Type{}` instead of `x := []Type`', last_pos) } + mut has_len := false + mut has_cap := false + mut len_expr := ast.Expr{} + mut cap_expr := ast.Expr{} if p.tok.kind == .lcbr && exprs.len == 0 { // `[]int{ len: 10, cap: 100}` syntax p.next() for p.tok.kind != .rcbr { key := p.check_name() p.check(.colon) - if key !in ['len', 'cap', 'init'] { - p.error('wrong field `$key`, expecting `len`, `cap`, or `init`') + match key { + 'len' { + has_len = true + len_expr = p.expr(0) + } + 'cap' { + has_cap = true + cap_expr = p.expr(0) + } + 'default' { + p.expr(0) + } + else { + p.error('wrong field `$key`, expecting `len`, `cap`, or `default`') + } } - p.expr(0) if p.tok.kind != .rcbr { p.check(.comma) } @@ -99,6 +115,10 @@ fn (mut p Parser) array_init() ast.ArrayInit { typ: array_type exprs: exprs pos: pos + has_len: has_len + len_expr: len_expr + has_cap: has_cap + cap_expr: cap_expr } }