@@ -11,75 +11,109 @@ import v.token
1111const maximum_inline_sum_type_variants = 3
1212const generic_type_level_cutoff_limit = 10 // it is very rarely deeper than 4
1313
14- fn (mut p Parser) parse_array_type (expecting token.Kind, is_option bool ) ast.Type {
15- p.check (expecting)
16- // fixed array
17- if p.tok.kind in [.number, .name, .dollar] {
18- mut fixed_size := 0
19- mut size_expr := p.expr (0 )
20- mut size_unresolved := true
21- if p.pref.is_fmt {
22- fixed_size = 987654321
23- } else {
24- match mut size_expr {
14+ fn (mut p Parser) eval_array_fixed_sizes (mut size_expr ast.Expr) (int , bool ) {
15+ mut fixed_size := 0
16+ mut size_unresolved := true
17+ match mut size_expr {
18+ ast.ParExpr {
19+ return p.eval_array_fixed_sizes (mut size_expr.expr)
20+ }
21+ ast.IntegerLiteral {
22+ fixed_size = size_expr.val.int ()
23+ size_unresolved = false
24+ }
25+ ast.ComptimeCall {
26+ if size_expr.kind == .d {
27+ size_expr.resolve_compile_value (p.pref.compile_values) or {
28+ p.error_with_pos (err.msg (), size_expr.pos)
29+ }
30+ if size_expr.result_type != ast.i64_ type {
31+ p.error_with_pos ('value from \$ d() can only be positive integers when used as fixed size' ,
32+ size_expr.pos)
33+ }
34+ fixed_size = size_expr.compile_value.int ()
35+ size_unresolved = false
36+ } else {
37+ p.error_with_pos ('only \$ d() is supported as fixed array size quantifier at compile time' ,
38+ size_expr.pos)
39+ }
40+ }
41+ ast.CastExpr {
42+ if ! size_expr.typ.is_pure_int () {
43+ p.error_with_pos ('only integer types are allowed' , size_expr.pos)
44+ }
45+ match mut size_expr.expr {
2546 ast.IntegerLiteral {
26- fixed_size = size_expr.val.int ()
47+ fixed_size = size_expr.expr. val.int ()
2748 size_unresolved = false
2849 }
29- ast.ComptimeCall {
30- if size_expr.kind == .d {
31- size_expr.resolve_compile_value (p.pref.compile_values) or {
32- p.error_with_pos (err.msg (), size_expr.pos)
33- }
34- if size_expr.result_type != ast.i64_ type {
35- p.error_with_pos ('value from \$ d() can only be positive integers when used as fixed size' ,
36- size_expr.pos)
37- }
38- fixed_size = size_expr.compile_value.int ()
50+ ast.FloatLiteral {
51+ fixed_size = int (size_expr.expr.val.f64 ())
52+ size_unresolved = false
53+ }
54+ ast.EnumVal {
55+ if val := p.table.find_enum_field_val (size_expr.expr.enum_name, size_expr.expr.val) {
56+ fixed_size = int (val)
3957 size_unresolved = false
40- } else {
41- p.error_with_pos ('only \$ d() is supported as fixed array size quantifier at compile time' ,
42- size_expr.pos)
4358 }
4459 }
45- ast.Ident {
46- if mut const_field := p.table.global_scope.find_const (size_expr.full_name ()) {
47- if mut const_field.expr is ast.IntegerLiteral {
48- fixed_size = const_field.expr.val.int ()
49- size_unresolved = false
50- } else if mut const_field.expr is ast.InfixExpr {
51- mut t := transformer.new_transformer_with_table (p.table, p.pref)
52- folded_expr := t.infix_expr (mut const_field.expr)
53-
54- if folded_expr is ast.IntegerLiteral {
55- fixed_size = folded_expr.val.int ()
56- size_unresolved = false
57- }
58- }
59- } else {
60- if p.pref.is_fmt {
61- // for vfmt purposes, pretend the constant does exist
62- // it may have been defined in another .v file:
63- fixed_size = 1
64- size_unresolved = false
65- }
66- }
60+ else {
61+ size , unresolved := p.eval_array_fixed_sizes (mut size_expr.expr)
62+ return int (size), unresolved
6763 }
68- ast.InfixExpr {
64+ }
65+ }
66+ ast.Ident {
67+ if mut const_field := p.table.global_scope.find_const (size_expr.full_name ().all_after ('builtin.' )) {
68+ if mut const_field.expr is ast.IntegerLiteral {
69+ fixed_size = const_field.expr.val.int ()
70+ size_unresolved = false
71+ } else if mut const_field.expr is ast.InfixExpr {
6972 mut t := transformer.new_transformer_with_table (p.table, p.pref)
70- folded_expr := t.infix_expr (mut size_expr )
73+ folded_expr := t.infix_expr (mut const_field.expr )
7174
7275 if folded_expr is ast.IntegerLiteral {
7376 fixed_size = folded_expr.val.int ()
7477 size_unresolved = false
7578 }
7679 }
77- else {
78- p.error_with_pos ('fixed array size cannot use non-constant value' ,
79- size_expr.pos ())
80+ } else {
81+ if p.pref.is_fmt {
82+ // for vfmt purposes, pretend the constant does exist
83+ // it may have been defined in another .v file:
84+ fixed_size = 1
85+ size_unresolved = false
8086 }
8187 }
8288 }
89+ ast.InfixExpr {
90+ mut t := transformer.new_transformer_with_table (p.table, p.pref)
91+ folded_expr := t.infix_expr (mut size_expr)
92+
93+ if folded_expr is ast.IntegerLiteral {
94+ fixed_size = folded_expr.val.int ()
95+ size_unresolved = false
96+ }
97+ }
98+ else {
99+ p.error_with_pos ('fixed array size cannot use non-constant value' , size_expr.pos ())
100+ }
101+ }
102+ return fixed_size, size_unresolved
103+ }
104+
105+ fn (mut p Parser) parse_array_type (expecting token.Kind, is_option bool ) ast.Type {
106+ p.check (expecting)
107+ // fixed array
108+ if p.tok.kind != .rsbr {
109+ mut fixed_size := 0
110+ mut size_expr := p.expr (0 )
111+ mut size_unresolved := true
112+ if p.pref.is_fmt {
113+ fixed_size = 987654321
114+ } else {
115+ fixed_size , size_unresolved = p.eval_array_fixed_sizes (mut size_expr)
116+ }
83117 p.check (.rsbr)
84118 p.fixed_array_dim++
85119 defer {
0 commit comments