parser: support custom fixed size ArrayInit: `[3]int{init: -1}` (#6114)
parent
5f3ced7213
commit
0f0a91fc9e
|
@ -733,7 +733,7 @@ pub struct ArrayInit {
|
|||
pub:
|
||||
pos token.Position
|
||||
elem_type_pos token.Position
|
||||
exprs []Expr
|
||||
exprs []Expr // `[expr, expr]` or `[expr]Type{}` for fixed array
|
||||
is_fixed bool
|
||||
has_val bool // fixed size literal `[expr, expr]!!`
|
||||
mod string
|
||||
|
|
|
@ -1734,6 +1734,11 @@ pub fn (mut f Fmt) array_init(it ast.ArrayInit) {
|
|||
// `[100]byte`
|
||||
if it.is_fixed {
|
||||
f.write(f.type_to_str(it.elem_type))
|
||||
if it.has_default {
|
||||
f.write('{init: $it.default_expr}')
|
||||
} else {
|
||||
f.write('{}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ fn main() {
|
|||
]
|
||||
x := []int{len: 10, cap: 100, init: 1}
|
||||
_ := expected_flags
|
||||
buf := [100]byte
|
||||
buf := [100]byte{}
|
||||
println(x)
|
||||
println(buf)
|
||||
}
|
||||
|
|
|
@ -1499,7 +1499,20 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
if !cloned {
|
||||
if is_decl {
|
||||
if is_fixed_array_init && !has_val {
|
||||
if val is ast.ArrayInit {
|
||||
if val.has_default {
|
||||
g.write('{$val.default_expr')
|
||||
info := right_sym.info as table.ArrayFixed
|
||||
for _ in 1 .. info.size {
|
||||
g.write(', $val.default_expr')
|
||||
}
|
||||
g.write('}')
|
||||
} else {
|
||||
g.write('{0}')
|
||||
}
|
||||
} else {
|
||||
g.write('{0}')
|
||||
}
|
||||
} else {
|
||||
g.expr(val)
|
||||
}
|
||||
|
@ -2152,8 +2165,8 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
|||
g.write(')')
|
||||
} else if node.op in [.eq, .ne] &&
|
||||
left_sym.kind == .array_fixed && right_sym.kind == .array_fixed {
|
||||
af := left_sym.info as table.ArrayFixed
|
||||
et := af.elem_type
|
||||
info := left_sym.info as table.ArrayFixed
|
||||
et := info.elem_type
|
||||
if !et.is_ptr() && !et.is_pointer() && !et.is_number() && et.idx() !in [table.bool_type_idx, table.char_type_idx] {
|
||||
verror('`==` on fixed array only supported with POD element types ATM')
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
|||
mut is_fixed := false
|
||||
mut has_val := false
|
||||
mut has_type := false
|
||||
mut has_default := false
|
||||
mut default_expr := ast.Expr{}
|
||||
if p.tok.kind == .rsbr {
|
||||
// []typ => `[]` and `typ` must be on the same line
|
||||
line_nr := p.tok.line_nr
|
||||
|
@ -28,7 +30,7 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
|||
elem_type_pos = p.tok.position()
|
||||
elem_type = p.parse_type()
|
||||
sym := p.table.get_type_symbol(elem_type)
|
||||
// this is set here becasue its a known type, others could be the
|
||||
// this is set here because it's a known type, others could be the
|
||||
// result of expr so we do those in checker
|
||||
idx := p.table.find_or_register_array(elem_type, 1, sym.mod)
|
||||
array_type = table.new_type(idx)
|
||||
|
@ -55,6 +57,24 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
|||
// [100]byte
|
||||
elem_type = p.parse_type()
|
||||
is_fixed = true
|
||||
if p.tok.kind == .lcbr {
|
||||
p.next()
|
||||
if p.tok.kind != .rcbr {
|
||||
pos := p.tok.position()
|
||||
n := p.check_name()
|
||||
if n != 'init' {
|
||||
p.error_with_pos('expected `init:`, not `$n`', pos)
|
||||
}
|
||||
p.check(.colon)
|
||||
has_default = true
|
||||
default_expr = p.expr(0)
|
||||
}
|
||||
last_pos = p.tok.position()
|
||||
p.check(.rcbr)
|
||||
}
|
||||
else {
|
||||
// p.warn_with_pos('use e.g. `x := [1]Type{}` instead of `x := [1]Type`', last_pos)
|
||||
}
|
||||
} else {
|
||||
if p.tok.kind == .not {
|
||||
last_pos = p.tok.position()
|
||||
|
@ -73,10 +93,8 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
|||
}
|
||||
mut has_len := false
|
||||
mut has_cap := false
|
||||
mut has_default := false
|
||||
mut len_expr := ast.Expr{}
|
||||
mut cap_expr := ast.Expr{}
|
||||
mut default_expr := ast.Expr{}
|
||||
if p.tok.kind == .lcbr && exprs.len == 0 {
|
||||
// `[]int{ len: 10, cap: 100}` syntax
|
||||
p.next()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
fn test_fixed_array_init() {
|
||||
fn test_fixed_array_lit_init() {
|
||||
a1 := ['1', '2', '3']!!
|
||||
assert typeof(a1) == '[3]string'
|
||||
assert '$a1' == "['1', '2', '3']"
|
||||
|
@ -37,7 +37,20 @@ fn test_fixed_type_init() {
|
|||
assert a == [2]int
|
||||
assert a == [0,0]!!
|
||||
assert a == a
|
||||
c := [3,3]!!
|
||||
mut c := [3,3]!!
|
||||
assert a != c
|
||||
assert c == [3,3]!!
|
||||
c = [2]int
|
||||
assert a == c
|
||||
}
|
||||
|
||||
fn test_fixed_custom_init() {
|
||||
a := [2]byte{init: 7}
|
||||
assert a == [byte(7), 7]!!
|
||||
|
||||
mut b := [3]int{}
|
||||
assert b == [0,0,0]!!
|
||||
// assign
|
||||
b = [3]int{init:5}
|
||||
assert b == [5,5,5]!!
|
||||
}
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
fn test_fixed_array_can_be_assigned() {
|
||||
x := 2.32
|
||||
mut v := [8]f64
|
||||
mut v := [8]f64{}
|
||||
assert v[1] == 0
|
||||
v = [1.0, x, 3.0,4.0,5.0,6.0,7.0,8.0]!!
|
||||
assert v[1] == x
|
||||
v = [8]f64
|
||||
v = [8]f64{}
|
||||
assert v[1] == 0
|
||||
// test slicing
|
||||
for e in v[0..8] {
|
||||
assert e == 0
|
||||
}
|
||||
v = [8]f64{init: 3.0}
|
||||
assert v[1] == 3.0
|
||||
}
|
||||
|
||||
fn test_fixed_array_can_be_used_in_declaration() {
|
||||
|
|
Loading…
Reference in New Issue