Skip to content

Commit bcfc069

Browse files
committed
transformer: move array logic to array.v
1 parent 996f0fe commit bcfc069

2 files changed

Lines changed: 163 additions & 152 deletions

File tree

‎vlib/v/transformer/array.v‎

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
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.
4+
module transformer
5+
6+
import v.ast
7+
8+
pub fn (mut t Transformer) array_init(mut node ast.ArrayInit) ast.Expr {
9+
// For JS and Go generate array init using their syntax
10+
// if t.pref.backend !in [.c, .native] {
11+
if !t.pref.new_transform || node.is_fixed {
12+
for mut expr in node.exprs {
13+
expr = t.expr(mut expr)
14+
}
15+
node.len_expr = t.expr(mut node.len_expr)
16+
node.cap_expr = t.expr(mut node.cap_expr)
17+
node.init_expr = t.expr(mut node.init_expr)
18+
return node
19+
}
20+
// For C and native transform into a function call `builtin__new_array_from_c_array_noscan(...)` etc
21+
// println('transformer array-init ${t.pref.backend}')
22+
// array_type := t.table.unwrap(node.typ)
23+
// mut array_styp := ''
24+
// elem_type := t.table.unwrap(node.elem_type)
25+
// mut shared_styp := '' // only needed for shared &[]{...}
26+
// is_shared := false // TODO g.is_shared => t.is_shared
27+
len := node.exprs.len
28+
// elem_sym := t.table.sym(t.unwrap_generic(node.elem_type))
29+
// elem_sym := t.table.sym(t.table.unwrap(node.elem_type))
30+
// if false { // array_type.unaliased_sym.kind == .array_fixed {
31+
// g.fixed_array_init(node, array_type, var_name, is_amp)
32+
// if is_amp {
33+
// g.write(')')
34+
//}
35+
//} else if len == 0 {
36+
// `[]int{len: 6, cap:10, init:22}`
37+
// g.array_init_with_fields(node, elem_type, is_amp, shared_styp, var_name)
38+
//} else {
39+
// `[1, 2, 3]`
40+
// elem_styp := g.styp(elem_type.typ)
41+
noscan := '' // if t.pref.backend != .native { '_noscan' } else { '' } // g.check_noscan(elem_type.typ)
42+
mut fn_name := 'builtin__new_array_from_c_array'
43+
len_arg := ast.CallArg{
44+
expr: ast.IntegerLiteral{
45+
val: len.str()
46+
}
47+
typ: ast.int_type
48+
}
49+
sizeof_arg := ast.CallArg{
50+
expr: ast.SizeOf{
51+
is_type: true
52+
typ: node.elem_type
53+
}
54+
typ: ast.int_type
55+
}
56+
fixed_array_arg := ast.CallArg{
57+
expr: ast.ArrayInit{
58+
is_fixed: true
59+
has_val: true
60+
typ: t.table.find_or_register_array_fixed(node.elem_type, len, ast.empty_expr,
61+
false)
62+
elem_type: node.elem_type
63+
exprs: node.exprs
64+
}
65+
typ: ast.voidptr_type_idx
66+
}
67+
// if false { // elem_type.unaliased_sym.kind == .function {
68+
//} else {
69+
fn_name = 'new_array_from_c_array' + noscan
70+
// g.write('builtin__new_array_from_c_array${noscan}(${len}, ${len}, sizeof(${elem_styp}), _MOV((${elem_styp}[${len}]){')
71+
//}
72+
call_expr := ast.CallExpr{
73+
name: fn_name
74+
mod: 'builtin'
75+
scope: ast.empty_scope // node.scope
76+
args: [len_arg, len_arg, sizeof_arg, fixed_array_arg] //, sizeof(voidptr), _MOV((voidptr[${len}]){')
77+
return_type: node.typ
78+
}
79+
// println('call expr')
80+
// println(call_expr)
81+
return call_expr
82+
/*
83+
if len > 8 {
84+
g.writeln('')
85+
g.write('\t\t')
86+
}
87+
is_iface_or_sumtype := elem_sym.kind in [.sum_type, .interface]
88+
for i, expr in node.exprs {
89+
expr_type := if node.expr_types.len > i { node.expr_types[i] } else { node.elem_type }
90+
if expr_type == ast.string_type
91+
&& expr !in [ast.IndexExpr, ast.CallExpr, ast.StringLiteral, ast.StringInterLiteral, ast.InfixExpr] {
92+
if is_iface_or_sumtype {
93+
g.expr_with_cast(expr, expr_type, node.elem_type)
94+
} else {
95+
g.write('builtin__string_clone(')
96+
g.expr(expr)
97+
g.write(')')
98+
}
99+
} else {
100+
if node.elem_type.has_flag(.option) {
101+
g.expr_with_opt(expr, expr_type, node.elem_type)
102+
} else if elem_type.unaliased_sym.kind == .array_fixed
103+
&& expr in [ast.Ident, ast.SelectorExpr] {
104+
info := elem_type.unaliased_sym.info as ast.ArrayFixed
105+
g.fixed_array_var_init(g.expr_string(expr), expr.is_auto_deref_var(),
106+
info.elem_type, info.size)
107+
} else {
108+
g.expr_with_cast(expr, expr_type, node.elem_type)
109+
}
110+
}
111+
if i != len - 1 {
112+
if i > 0 && i & 7 == 0 { // i > 0 && i % 8 == 0
113+
g.writeln(',')
114+
g.write('\t\t')
115+
} else {
116+
g.write(', ')
117+
}
118+
}
119+
}
120+
g.write('}))')
121+
if g.is_shared {
122+
g.write('}, sizeof(${shared_styp}))')
123+
} else if is_amp {
124+
g.write(')')
125+
}
126+
*/
127+
//}
128+
}
129+
130+
pub fn (mut t Transformer) find_new_array_len(node ast.AssignStmt) {
131+
if !t.pref.is_prod {
132+
return
133+
}
134+
// looking for, array := []type{len:int}
135+
mut right := node.right[0]
136+
if mut right is ast.ArrayInit {
137+
mut left := node.left[0]
138+
if mut left is ast.Ident {
139+
// we can not analyse mut array
140+
if left.is_mut {
141+
t.index.safe_access(left.name, -2)
142+
return
143+
}
144+
// as we do not need to check any value under the setup len
145+
if !right.has_len {
146+
t.index.safe_access(left.name, -1)
147+
return
148+
}
149+
150+
mut len := int(0)
151+
152+
value := right.len_expr
153+
if value is ast.IntegerLiteral {
154+
len = value.val.int() + 1
155+
}
156+
157+
t.index.safe_access(left.name, len)
158+
}
159+
}
160+
}

‎vlib/v/transformer/transformer.v‎

Lines changed: 3 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
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.
14
module transformer
25

36
import v.pref
@@ -54,37 +57,6 @@ pub fn (mut t Transformer) transform(mut ast_file ast.File) {
5457
}
5558
}
5659

57-
pub fn (mut t Transformer) find_new_array_len(node ast.AssignStmt) {
58-
if !t.pref.is_prod {
59-
return
60-
}
61-
// looking for, array := []type{len:int}
62-
mut right := node.right[0]
63-
if mut right is ast.ArrayInit {
64-
mut left := node.left[0]
65-
if mut left is ast.Ident {
66-
// we can not analyse mut array
67-
if left.is_mut {
68-
t.index.safe_access(left.name, -2)
69-
return
70-
}
71-
// as we do not need to check any value under the setup len
72-
if !right.has_len {
73-
t.index.safe_access(left.name, -1)
74-
return
75-
}
76-
77-
mut len := int(0)
78-
79-
value := right.len_expr
80-
if value is ast.IntegerLiteral {
81-
len = value.val.int() + 1
82-
}
83-
84-
t.index.safe_access(left.name, len)
85-
}
86-
}
87-
}
8860

8961
pub fn (mut t Transformer) find_new_range(node ast.AssignStmt) {
9062
if !t.pref.is_prod {
@@ -1148,127 +1120,6 @@ pub fn (mut t Transformer) infix_expr(mut node ast.InfixExpr) ast.Expr {
11481120
}
11491121
}
11501122

1151-
pub fn (mut t Transformer) array_init(mut node ast.ArrayInit) ast.Expr {
1152-
// For JS and Go generate array init using their syntax
1153-
// if t.pref.backend !in [.c, .native] {
1154-
if !t.pref.new_transform || node.is_fixed {
1155-
for mut expr in node.exprs {
1156-
expr = t.expr(mut expr)
1157-
}
1158-
node.len_expr = t.expr(mut node.len_expr)
1159-
node.cap_expr = t.expr(mut node.cap_expr)
1160-
node.init_expr = t.expr(mut node.init_expr)
1161-
return node
1162-
}
1163-
// For C and native transform into a function call `builtin__new_array_from_c_array_noscan(...)` etc
1164-
// println('transformer array-init ${t.pref.backend}')
1165-
// array_type := t.table.unwrap(node.typ)
1166-
// mut array_styp := ''
1167-
// elem_type := t.table.unwrap(node.elem_type)
1168-
// mut shared_styp := '' // only needed for shared &[]{...}
1169-
// is_shared := false // TODO g.is_shared => t.is_shared
1170-
len := node.exprs.len
1171-
// elem_sym := t.table.sym(t.unwrap_generic(node.elem_type))
1172-
// elem_sym := t.table.sym(t.table.unwrap(node.elem_type))
1173-
// if false { // array_type.unaliased_sym.kind == .array_fixed {
1174-
// g.fixed_array_init(node, array_type, var_name, is_amp)
1175-
// if is_amp {
1176-
// g.write(')')
1177-
//}
1178-
//} else if len == 0 {
1179-
// `[]int{len: 6, cap:10, init:22}`
1180-
// g.array_init_with_fields(node, elem_type, is_amp, shared_styp, var_name)
1181-
//} else {
1182-
// `[1, 2, 3]`
1183-
// elem_styp := g.styp(elem_type.typ)
1184-
noscan := if t.pref.backend != .native { '_noscan' } else { '' } // g.check_noscan(elem_type.typ)
1185-
mut fn_name := 'new_array_from_c_array'
1186-
len_arg := ast.CallArg{
1187-
expr: ast.IntegerLiteral{
1188-
val: len.str()
1189-
}
1190-
typ: ast.int_type
1191-
}
1192-
sizeof_arg := ast.CallArg{
1193-
expr: ast.SizeOf{
1194-
is_type: true
1195-
typ: node.elem_type
1196-
}
1197-
typ: ast.int_type
1198-
}
1199-
fixed_array_arg := ast.CallArg{
1200-
expr: ast.ArrayInit{
1201-
is_fixed: true
1202-
has_val: true
1203-
typ: t.table.find_or_register_array_fixed(node.elem_type, len, ast.empty_expr,
1204-
false)
1205-
elem_type: node.elem_type
1206-
exprs: node.exprs
1207-
}
1208-
typ: ast.voidptr_type_idx
1209-
}
1210-
// if false { // elem_type.unaliased_sym.kind == .function {
1211-
//} else {
1212-
fn_name = 'new_array_from_c_array' + noscan
1213-
// g.write('builtin__new_array_from_c_array${noscan}(${len}, ${len}, sizeof(${elem_styp}), _MOV((${elem_styp}[${len}]){')
1214-
//}
1215-
call_expr := ast.CallExpr{
1216-
name: fn_name
1217-
mod: 'builtin'
1218-
scope: ast.empty_scope // node.scope
1219-
args: [len_arg, len_arg, sizeof_arg, fixed_array_arg] //, sizeof(voidptr), _MOV((voidptr[${len}]){')
1220-
return_type: node.typ
1221-
}
1222-
// println('call expr')
1223-
// println(call_expr)
1224-
return call_expr
1225-
/*
1226-
if len > 8 {
1227-
g.writeln('')
1228-
g.write('\t\t')
1229-
}
1230-
is_iface_or_sumtype := elem_sym.kind in [.sum_type, .interface]
1231-
for i, expr in node.exprs {
1232-
expr_type := if node.expr_types.len > i { node.expr_types[i] } else { node.elem_type }
1233-
if expr_type == ast.string_type
1234-
&& expr !in [ast.IndexExpr, ast.CallExpr, ast.StringLiteral, ast.StringInterLiteral, ast.InfixExpr] {
1235-
if is_iface_or_sumtype {
1236-
g.expr_with_cast(expr, expr_type, node.elem_type)
1237-
} else {
1238-
g.write('builtin__string_clone(')
1239-
g.expr(expr)
1240-
g.write(')')
1241-
}
1242-
} else {
1243-
if node.elem_type.has_flag(.option) {
1244-
g.expr_with_opt(expr, expr_type, node.elem_type)
1245-
} else if elem_type.unaliased_sym.kind == .array_fixed
1246-
&& expr in [ast.Ident, ast.SelectorExpr] {
1247-
info := elem_type.unaliased_sym.info as ast.ArrayFixed
1248-
g.fixed_array_var_init(g.expr_string(expr), expr.is_auto_deref_var(),
1249-
info.elem_type, info.size)
1250-
} else {
1251-
g.expr_with_cast(expr, expr_type, node.elem_type)
1252-
}
1253-
}
1254-
if i != len - 1 {
1255-
if i > 0 && i & 7 == 0 { // i > 0 && i % 8 == 0
1256-
g.writeln(',')
1257-
g.write('\t\t')
1258-
} else {
1259-
g.write(', ')
1260-
}
1261-
}
1262-
}
1263-
g.write('}))')
1264-
if g.is_shared {
1265-
g.write('}, sizeof(${shared_styp}))')
1266-
} else if is_amp {
1267-
g.write(')')
1268-
}
1269-
*/
1270-
//}
1271-
}
12721123

12731124
pub fn (mut t Transformer) if_expr(mut node ast.IfExpr) ast.Expr {
12741125
for mut branch in node.branches {

0 commit comments

Comments
 (0)