all: index accessor in array init expression (#12181)
parent
6d62574e7f
commit
4d1307f29b
|
@ -692,6 +692,14 @@ arrays there is a second initialization syntax:
|
||||||
```v
|
```v
|
||||||
mut a := []int{len: 10000, cap: 30000, init: 3}
|
mut a := []int{len: 10000, cap: 30000, init: 3}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can initialize the array by accessing the it variable as shown here:
|
||||||
|
|
||||||
|
```v
|
||||||
|
mut square := []int{len: 6, init: it * it}
|
||||||
|
// square == [0, 1, 4, 9, 16, 25]
|
||||||
|
```
|
||||||
|
|
||||||
This creates an array of 10000 `int` elements that are all initialized with `3`. Memory
|
This creates an array of 10000 `int` elements that are all initialized with `3`. Memory
|
||||||
space is reserved for 30000 elements. The parameters `len`, `cap` and `init` are optional;
|
space is reserved for 30000 elements. The parameters `len`, `cap` and `init` are optional;
|
||||||
`len` defaults to `0` and `init` to the default initialization of the element type (`0`
|
`len` defaults to `0` and `init` to the default initialization of the element type (`0`
|
||||||
|
|
|
@ -1136,6 +1136,7 @@ pub:
|
||||||
has_len bool
|
has_len bool
|
||||||
has_cap bool
|
has_cap bool
|
||||||
has_default bool
|
has_default bool
|
||||||
|
has_it bool // true if temp variable it is used
|
||||||
pub mut:
|
pub mut:
|
||||||
expr_types []Type // [Dog, Cat] // also used for interface_types
|
expr_types []Type // [Dog, Cat] // also used for interface_types
|
||||||
elem_type Type // element type
|
elem_type Type // element type
|
||||||
|
|
|
@ -51,6 +51,80 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
|
||||||
noscan := g.check_noscan(elem_type.typ)
|
noscan := g.check_noscan(elem_type.typ)
|
||||||
if node.exprs.len == 0 {
|
if node.exprs.len == 0 {
|
||||||
is_default_array := elem_type.unaliased_sym.kind == .array && node.has_default
|
is_default_array := elem_type.unaliased_sym.kind == .array && node.has_default
|
||||||
|
if node.has_it { // []int{len: 6, init: it * it} when variable it is used in init expression
|
||||||
|
g.inside_lambda = true
|
||||||
|
tmp := g.new_tmp_var()
|
||||||
|
mut s := g.go_before_stmt(0)
|
||||||
|
s_ends_with_ln := s.ends_with('\n')
|
||||||
|
s = s.trim_space()
|
||||||
|
ret_typ := g.typ(node.typ)
|
||||||
|
elem_typ := g.typ(node.elem_type)
|
||||||
|
g.empty_line = true
|
||||||
|
g.write('$ret_typ $tmp =')
|
||||||
|
if is_default_array {
|
||||||
|
g.write('__new_array_with_array_default${noscan}(')
|
||||||
|
} else {
|
||||||
|
g.write('__new_array_with_default${noscan}(')
|
||||||
|
}
|
||||||
|
if node.has_len {
|
||||||
|
g.expr(node.len_expr)
|
||||||
|
g.write(', ')
|
||||||
|
} else {
|
||||||
|
g.write('0, ')
|
||||||
|
}
|
||||||
|
if node.has_cap {
|
||||||
|
g.expr(node.cap_expr)
|
||||||
|
g.write(', ')
|
||||||
|
} else {
|
||||||
|
g.write('0, ')
|
||||||
|
}
|
||||||
|
if elem_type.unaliased_sym.kind == .function {
|
||||||
|
g.write('sizeof(voidptr), ')
|
||||||
|
} else {
|
||||||
|
g.write('sizeof($elem_styp), ')
|
||||||
|
}
|
||||||
|
if is_default_array {
|
||||||
|
g.write('($elem_styp[]){')
|
||||||
|
g.expr(node.default_expr)
|
||||||
|
g.write('}[0])')
|
||||||
|
} else if node.has_len && node.elem_type == ast.string_type {
|
||||||
|
g.write('&($elem_styp[]){')
|
||||||
|
g.write('_SLIT("")')
|
||||||
|
g.write('})')
|
||||||
|
} else if node.has_len && elem_type.unaliased_sym.kind in [.array, .map] {
|
||||||
|
g.write('(voidptr)&($elem_styp[]){')
|
||||||
|
g.write(g.type_default(node.elem_type))
|
||||||
|
g.write('}[0])')
|
||||||
|
} else {
|
||||||
|
g.write('0)')
|
||||||
|
}
|
||||||
|
if g.is_shared {
|
||||||
|
g.write('}, sizeof($shared_styp))')
|
||||||
|
} else if is_amp {
|
||||||
|
g.write(')')
|
||||||
|
}
|
||||||
|
g.writeln(';')
|
||||||
|
g.writeln('{')
|
||||||
|
g.indent++
|
||||||
|
g.writeln('$elem_typ* pelem = ($elem_typ*)${tmp}.data;')
|
||||||
|
g.writeln('for(int it=0; it<${tmp}.len; it++, pelem++) {')
|
||||||
|
g.indent++
|
||||||
|
g.write('*pelem = ')
|
||||||
|
g.expr(node.default_expr)
|
||||||
|
g.writeln(';')
|
||||||
|
g.indent--
|
||||||
|
g.writeln('}')
|
||||||
|
g.indent--
|
||||||
|
g.writeln('}')
|
||||||
|
if s_ends_with_ln {
|
||||||
|
g.writeln(s)
|
||||||
|
} else {
|
||||||
|
g.write(s)
|
||||||
|
}
|
||||||
|
g.write(tmp)
|
||||||
|
g.inside_lambda = false
|
||||||
|
return
|
||||||
|
}
|
||||||
if is_default_array {
|
if is_default_array {
|
||||||
g.write('__new_array_with_array_default${noscan}(')
|
g.write('__new_array_with_array_default${noscan}(')
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1812,13 +1812,11 @@ fn (mut g JsGen) gen_array_init_expr(it ast.ArrayInit) {
|
||||||
|
|
||||||
if it.has_len {
|
if it.has_len {
|
||||||
t1 := g.new_tmp_var()
|
t1 := g.new_tmp_var()
|
||||||
t2 := g.new_tmp_var()
|
|
||||||
g.writeln('(function(length) {')
|
g.writeln('(function(length) {')
|
||||||
g.inc_indent()
|
g.inc_indent()
|
||||||
g.writeln('const $t1 = [];')
|
g.writeln('const $t1 = [];')
|
||||||
g.write('for (let $t2 = 0; $t2 < length')
|
g.write('for (let it = 0; it < length')
|
||||||
|
g.writeln('; it++) {')
|
||||||
g.writeln('; $t2++) {')
|
|
||||||
g.inc_indent()
|
g.inc_indent()
|
||||||
g.write('${t1}.push(')
|
g.write('${t1}.push(')
|
||||||
if it.has_default {
|
if it.has_default {
|
||||||
|
|
|
@ -20,6 +20,7 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
||||||
mut has_val := false
|
mut has_val := false
|
||||||
mut has_type := false
|
mut has_type := false
|
||||||
mut has_default := false
|
mut has_default := false
|
||||||
|
mut has_it := false
|
||||||
mut default_expr := ast.empty_expr()
|
mut default_expr := ast.empty_expr()
|
||||||
if p.tok.kind == .rsbr {
|
if p.tok.kind == .rsbr {
|
||||||
last_pos = p.tok.position()
|
last_pos = p.tok.position()
|
||||||
|
@ -79,8 +80,19 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
||||||
return ast.ArrayInit{}
|
return ast.ArrayInit{}
|
||||||
}
|
}
|
||||||
p.check(.colon)
|
p.check(.colon)
|
||||||
|
p.open_scope()
|
||||||
has_default = true
|
has_default = true
|
||||||
|
p.scope_register_it_as_index()
|
||||||
default_expr = p.expr(0)
|
default_expr = p.expr(0)
|
||||||
|
has_it = if var := p.scope.find_var('it') {
|
||||||
|
mut variable := var
|
||||||
|
is_used := variable.is_used
|
||||||
|
variable.is_used = true
|
||||||
|
is_used
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
p.close_scope()
|
||||||
}
|
}
|
||||||
last_pos = p.tok.position()
|
last_pos = p.tok.position()
|
||||||
p.check(.rcbr)
|
p.check(.rcbr)
|
||||||
|
@ -127,8 +139,19 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
||||||
cap_expr = p.expr(0)
|
cap_expr = p.expr(0)
|
||||||
}
|
}
|
||||||
'init' {
|
'init' {
|
||||||
|
p.open_scope()
|
||||||
has_default = true
|
has_default = true
|
||||||
|
p.scope_register_it_as_index()
|
||||||
default_expr = p.expr(0)
|
default_expr = p.expr(0)
|
||||||
|
has_it = if var := p.scope.find_var('it') {
|
||||||
|
mut variable := var
|
||||||
|
is_used := variable.is_used
|
||||||
|
variable.is_used = true
|
||||||
|
is_used
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
p.close_scope()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p.error('wrong field `$key`, expecting `len`, `cap`, or `init`')
|
p.error('wrong field `$key`, expecting `len`, `cap`, or `init`')
|
||||||
|
@ -157,6 +180,7 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
||||||
len_expr: len_expr
|
len_expr: len_expr
|
||||||
has_cap: has_cap
|
has_cap: has_cap
|
||||||
has_default: has_default
|
has_default: has_default
|
||||||
|
has_it: has_it
|
||||||
cap_expr: cap_expr
|
cap_expr: cap_expr
|
||||||
default_expr: default_expr
|
default_expr: default_expr
|
||||||
}
|
}
|
||||||
|
@ -188,3 +212,13 @@ fn (mut p Parser) map_init() ast.MapInit {
|
||||||
pre_cmnts: pre_cmnts
|
pre_cmnts: pre_cmnts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut p Parser) scope_register_it_as_index() {
|
||||||
|
p.scope.objects['it'] = ast.Var{ // override it variable if it already exist, else create it variable
|
||||||
|
name: 'it'
|
||||||
|
pos: p.tok.position()
|
||||||
|
typ: ast.int_type
|
||||||
|
is_mut: false
|
||||||
|
is_used: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
fn test_array_with_it() {
|
||||||
|
assert [0, 1, 4, 9, 16, 25] == []int{len: 6, init: it * it}
|
||||||
|
assert [1, 2, 3, 4, 5] == []int{len: 5, init: it + 1}
|
||||||
|
assert [5, 4, 3, 2, 1] == []int{len: 5, init: 5 - it}
|
||||||
|
}
|
Loading…
Reference in New Issue