array: fix fixed array errors

pull/4586/head
yuyi 2020-04-26 00:26:38 +08:00 committed by GitHub
parent ec9566988a
commit c26e83f58a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 112 additions and 42 deletions

View File

@ -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',

View File

@ -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+/'

View File

@ -266,7 +266,7 @@ pub fn identity3() []f32 {
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
] !
]
return res
}

View File

@ -635,6 +635,7 @@ pub:
pos token.Position
exprs []Expr
is_fixed bool
has_val bool
mod string
mut:
elem_type table.Type

View File

@ -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

View File

@ -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]!!

View File

@ -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
}

View File

@ -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

View 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]'
}