mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
array: fix fixed array errors
This commit is contained in:
parent
ec9566988a
commit
c26e83f58a
@ -13,7 +13,6 @@ const (
|
||||
'vlib/net/http/http_test.v',
|
||||
'vlib/regex/regex_test.v',
|
||||
'vlib/v/tests/enum_bitfield_test.v',
|
||||
'vlib/v/tests/fixed_array_test.v',
|
||||
'vlib/v/tests/num_lit_call_method_test.v',
|
||||
'vlib/v/tests/pointers_test.v',
|
||||
'vlib/v/tests/type_test.v',
|
||||
|
@ -11,7 +11,7 @@ const (
|
||||
0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
|
||||
47, 48, 49, 50, 51]!!
|
||||
47, 48, 49, 50, 51]
|
||||
|
||||
ending_table = [0, 2, 1]
|
||||
enc_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
|
@ -266,7 +266,7 @@ pub fn identity3() []f32 {
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1,
|
||||
] !
|
||||
]
|
||||
return res
|
||||
}
|
||||
|
||||
|
@ -635,6 +635,7 @@ pub:
|
||||
pos token.Position
|
||||
exprs []Expr
|
||||
is_fixed bool
|
||||
has_val bool
|
||||
mod string
|
||||
mut:
|
||||
elem_type table.Type
|
||||
|
@ -998,8 +998,13 @@ pub fn (mut c Checker) array_init(array_init mut ast.ArrayInit) table.Type {
|
||||
c.error('expected array element with type `$elem_type_sym.name`', array_init.pos)
|
||||
}
|
||||
}
|
||||
idx := c.table.find_or_register_array(elem_type, 1)
|
||||
array_init.typ = table.new_type(idx)
|
||||
if array_init.is_fixed {
|
||||
idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len, 1)
|
||||
array_init.typ = table.new_type(idx)
|
||||
} else {
|
||||
idx := c.table.find_or_register_array(elem_type, 1)
|
||||
array_init.typ = table.new_type(idx)
|
||||
}
|
||||
array_init.elem_type = elem_type
|
||||
} else if array_init.is_fixed && array_init.exprs.len == 1 && array_init.elem_type != table.void_type {
|
||||
// [50]byte
|
||||
|
@ -1,4 +1,4 @@
|
||||
vlib/v/checker/tests/inout/cannot_assign_array.v:9:11: error: cannot assign `array_f64` to variable `ctx.vb` of type `string`
|
||||
vlib/v/checker/tests/inout/cannot_assign_array.v:9:11: error: cannot assign `array_fixed_f64_8` to variable `ctx.vb` of type `string`
|
||||
7| mut ctx := Context{}
|
||||
8| x := 2.32
|
||||
9| ctx.vb = [1.1, x, 3.3, 4.4, 5.0, 6.0, 7.0, 8.9]!!
|
||||
|
@ -845,8 +845,12 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||
} else {
|
||||
right_sym := g.table.get_type_symbol(assign_stmt.right_types[i])
|
||||
mut is_fixed_array_init := false
|
||||
mut has_val := false
|
||||
match val {
|
||||
ast.ArrayInit { is_fixed_array_init = it.is_fixed }
|
||||
ast.ArrayInit {
|
||||
is_fixed_array_init = it.is_fixed
|
||||
has_val = it.has_val
|
||||
}
|
||||
else {}
|
||||
}
|
||||
is_decl := assign_stmt.op == .decl_assign
|
||||
@ -863,7 +867,12 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||
}
|
||||
}
|
||||
if is_fixed_array_init {
|
||||
g.write('= {0}')
|
||||
if has_val {
|
||||
g.write(' = ')
|
||||
g.expr(val)
|
||||
} else {
|
||||
g.write(' = {0}')
|
||||
}
|
||||
} else {
|
||||
g.write(' = ')
|
||||
if !is_decl {
|
||||
@ -972,6 +981,14 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||
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('}')
|
||||
}
|
||||
}
|
||||
ast.AsCast {
|
||||
@ -1265,32 +1282,43 @@ fn (mut g Gen) assign_expr(node ast.AssignExpr) {
|
||||
g.write(' = string_add(')
|
||||
str_add = true
|
||||
}
|
||||
g.assign_op = node.op
|
||||
g.expr(node.left)
|
||||
// arr[i] = val => `array_set(arr, i, val)`, not `array_get(arr, i) = val`
|
||||
if !g.is_array_set && !str_add {
|
||||
g.write(' $node.op.str() ')
|
||||
} else if str_add {
|
||||
g.write(', ')
|
||||
}
|
||||
g.is_assign_lhs = false
|
||||
right_sym := g.table.get_type_symbol(node.right_type)
|
||||
// left_sym := g.table.get_type_symbol(node.left_type)
|
||||
mut cloned := false
|
||||
// !g.is_array_set
|
||||
if g.autofree && right_sym.kind in [.array, .string] {
|
||||
if g.gen_clone_assignment(node.val, right_sym, false) {
|
||||
cloned = true
|
||||
if right_sym.kind == .array_fixed && node.op == .assign {
|
||||
right := node.val as ast.ArrayInit
|
||||
for j, expr in right.exprs {
|
||||
g.expr(node.left)
|
||||
g.write('[$j] = ')
|
||||
g.expr(expr)
|
||||
g.writeln(';')
|
||||
}
|
||||
} else {
|
||||
g.assign_op = node.op
|
||||
g.expr(node.left)
|
||||
// arr[i] = val => `array_set(arr, i, val)`, not `array_get(arr, i) = val`
|
||||
if !g.is_array_set && !str_add {
|
||||
g.write(' $node.op.str() ')
|
||||
} else if str_add {
|
||||
g.write(', ')
|
||||
}
|
||||
g.is_assign_lhs = false
|
||||
//right_sym := g.table.get_type_symbol(node.right_type)
|
||||
// left_sym := g.table.get_type_symbol(node.left_type)
|
||||
mut cloned := false
|
||||
// !g.is_array_set
|
||||
if g.autofree && right_sym.kind in [.array, .string] {
|
||||
if g.gen_clone_assignment(node.val, right_sym, false) {
|
||||
cloned = true
|
||||
}
|
||||
}
|
||||
if !cloned {
|
||||
g.expr_with_cast(node.val, node.right_type, node.left_type)
|
||||
}
|
||||
if g.is_array_set {
|
||||
g.write(' })')
|
||||
g.is_array_set = false
|
||||
} else if str_add {
|
||||
g.write(')')
|
||||
}
|
||||
}
|
||||
if !cloned {
|
||||
g.expr_with_cast(node.val, node.right_type, node.left_type)
|
||||
}
|
||||
if g.is_array_set {
|
||||
g.write(' })')
|
||||
g.is_array_set = false
|
||||
} else if str_add {
|
||||
g.write(')')
|
||||
}
|
||||
g.right_is_opt = false
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
||||
mut elem_type := table.void_type
|
||||
mut exprs := []ast.Expr
|
||||
mut is_fixed := false
|
||||
mut has_val := false
|
||||
if p.tok.kind == .rsbr {
|
||||
// []typ => `[]` and `typ` must be on the same line
|
||||
line_nr := p.tok.line_nr
|
||||
@ -47,21 +48,23 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
||||
}
|
||||
last_pos = p.tok.position()
|
||||
p.check(.rsbr)
|
||||
// [100]byte
|
||||
if exprs.len == 1 && p.tok.kind in [.name, .amp] && p.tok.line_nr == line_nr {
|
||||
// [100]byte
|
||||
elem_type = p.parse_type()
|
||||
is_fixed = true
|
||||
} else {
|
||||
if p.tok.kind == .not {
|
||||
last_pos = p.tok.position()
|
||||
p.next()
|
||||
}
|
||||
if p.tok.kind == .not {
|
||||
last_pos = p.tok.position()
|
||||
p.next()
|
||||
is_fixed = true
|
||||
has_val = true
|
||||
}
|
||||
}
|
||||
}
|
||||
// !
|
||||
if p.tok.kind == .not {
|
||||
last_pos = p.tok.position()
|
||||
p.next()
|
||||
}
|
||||
if p.tok.kind == .not {
|
||||
last_pos = p.tok.position()
|
||||
p.next()
|
||||
}
|
||||
if p.tok.kind == .lcbr && exprs.len == 0 {
|
||||
// `[]int{ len: 10, cap: 100}` syntax
|
||||
p.next()
|
||||
@ -85,6 +88,7 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
||||
}
|
||||
return ast.ArrayInit{
|
||||
is_fixed: is_fixed
|
||||
has_val: has_val
|
||||
mod: p.mod
|
||||
elem_type: elem_type
|
||||
typ: array_type
|
||||
|
33
vlib/v/tests/fixed_array_init_test.v
Normal file
33
vlib/v/tests/fixed_array_init_test.v
Normal file
@ -0,0 +1,33 @@
|
||||
fn test_fixed_array_init() {
|
||||
a1 := ['1', '2', '3']!!
|
||||
assert typeof(a1) == '[3]string'
|
||||
assert '$a1' == '["1", "2", "3"]'
|
||||
|
||||
a2 := ['a', 'b']!!
|
||||
assert typeof(a2) == '[2]string'
|
||||
assert '$a2' == '["a", "b"]'
|
||||
|
||||
c1 := [1, 2, 3]!!
|
||||
assert typeof(c1) == '[3]int'
|
||||
assert '$c1' == '[1, 2, 3]'
|
||||
|
||||
c2 := [i16(1), 2, 3]!!
|
||||
assert typeof(c2) == '[3]i16'
|
||||
assert '$c2' == '[1, 2, 3]'
|
||||
|
||||
mut c3 := [i64(1), 2, 3]!!
|
||||
assert typeof(c3) == '[3]i64'
|
||||
assert '$c3' == '[1, 2, 3]'
|
||||
|
||||
mut c4 := [u64(1), 2, 3]!!
|
||||
assert typeof(c4) == '[3]u64'
|
||||
assert '$c4' == '[1, 2, 3]'
|
||||
|
||||
mut d1 := [1.1, 2.2, 3.3]!!
|
||||
assert typeof(d1) == '[3]f64'
|
||||
assert '$d1' == '[1.1, 2.2, 3.3]'
|
||||
|
||||
mut d2 := [f32(1.1), 2.2, 3.3]!!
|
||||
assert typeof(d2) == '[3]f32'
|
||||
assert '$d2' == '[1.1, 2.2, 3.3]'
|
||||
}
|
Loading…
Reference in New Issue
Block a user