v2 / vlib / v / transformer / array.v
100 lines · 97 sloc · 2.61 KB · 241dfe3d28938fc650cbe1407d88bc33c3f98815
Raw
1// Copyright (c) 2019-2025 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module transformer
5
6import v.ast
7
8pub fn (mut t Transformer) array_init(mut node ast.ArrayInit) ast.Expr {
9 for mut expr in node.exprs {
10 expr = t.expr(mut expr)
11 }
12 if node.has_len {
13 node.len_expr = t.expr(mut node.len_expr)
14 }
15 if node.has_cap {
16 node.cap_expr = t.expr(mut node.cap_expr)
17 }
18 if node.has_init {
19 node.init_expr = t.expr(mut node.init_expr)
20 }
21 if t.pref.backend == .js_node || !t.pref.new_transform || t.skip_array_transform
22 || node.is_fixed || t.inside_in || node.has_len || node.has_cap || node.exprs.len == 0 {
23 return node
24 }
25 // For C and native transform into a function call `builtin__new_array_from_c_array_noscan(...)` etc
26 len := node.exprs.len
27 len_arg := ast.CallArg{
28 expr: ast.IntegerLiteral{
29 val: len.str()
30 }
31 typ: ast.int_type
32 }
33 sizeof_arg := ast.CallArg{
34 expr: ast.SizeOf{
35 is_type: true
36 typ: node.elem_type
37 }
38 typ: ast.int_type
39 }
40 fixed_array_idx := t.table.find_or_register_array_fixed(node.elem_type, len, ast.empty_expr,
41 false)
42 fixed_array_typ := if node.elem_type.has_flag(.generic) {
43 ast.new_type(fixed_array_idx).set_flag(.generic)
44 } else {
45 ast.new_type(fixed_array_idx)
46 }
47 fixed_array_arg := ast.CallArg{
48 expr: ast.CastExpr{
49 expr: ast.ArrayInit{
50 is_fixed: true
51 has_val: true
52 typ: fixed_array_typ
53 elem_type: node.elem_type
54 exprs: node.exprs
55 expr_types: node.expr_types
56 }
57 typ: ast.voidptr_type
58 typname: 'voidptr'
59 expr_type: fixed_array_typ
60 }
61 typ: ast.voidptr_type_idx
62 }
63 mut call_expr := ast.CallExpr{
64 name: 'new_array_from_c_array'
65 mod: 'builtin'
66 scope: unsafe { nil }
67 args: [len_arg, len_arg, sizeof_arg, fixed_array_arg] //, sizeof(voidptr), _MOV((voidptr[${len}]){')
68 return_type: node.typ
69 }
70 return call_expr
71}
72
73pub fn (mut t Transformer) find_new_array_len(node ast.AssignStmt) {
74 if !t.pref.is_prod {
75 return
76 }
77 // looking for, array := []type{len:int}
78 mut right := node.right[0]
79 if mut right is ast.ArrayInit {
80 mut left := node.left[0]
81 if mut left is ast.Ident {
82 // we can not analyse mut array
83 if left.is_mut {
84 t.index.safe_access(left.name, -2)
85 return
86 }
87 // as we do not need to check any value under the setup len
88 if !right.has_len {
89 t.index.safe_access(left.name, -1)
90 return
91 }
92 mut len := int(0)
93 value := right.len_expr
94 if value is ast.IntegerLiteral {
95 len = value.val.int() + 1
96 }
97 t.index.safe_access(left.name, len)
98 }
99 }
100}
101