Skip to content

Commit c4e41c1

Browse files
committed
transformer: transform ArrayInit into a function call for C and native backends (part 1)
1 parent 334f48a commit c4e41c1

File tree

4 files changed

+133
-10
lines changed

4 files changed

+133
-10
lines changed

vlib/v/ast/table.v

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2837,3 +2837,8 @@ pub fn (mut t Table) get_veb_result_type_idx() int {
28372837
pub fn (mut t Table) register_vls_info(key string, val VlsInfo) {
28382838
t.vls_info[key] = val
28392839
}
2840+
2841+
pub fn (t &Table) unwrap(typ Type) Type {
2842+
ts := t.sym(typ)
2843+
return if ts.info is Alias { t.unwrap(ts.info.parent_type) } else { typ }
2844+
}

vlib/v/gen/c/array.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit, var_name string) {
2424
}
2525
len := node.exprs.len
2626
elem_sym := g.table.sym(g.unwrap_generic(node.elem_type))
27-
if array_type.unaliased_sym.kind == .array_fixed {
27+
if node.is_fixed || array_type.unaliased_sym.kind == .array_fixed {
2828
g.fixed_array_init(node, array_type, var_name, is_amp)
2929
if is_amp {
3030
g.write(')')

vlib/v/pref/pref.v

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,10 @@ pub mut:
257257
// forwards compatibility settings:
258258
relaxed_gcc14 bool = true // turn on the generated pragmas, that make gcc versions > 14 a lot less pedantic. The default is to have those pragmas in the generated C output, so that gcc-14 can be used on Arch etc.
259259
//
260-
subsystem Subsystem // the type of the window app, that is going to be generated; has no effect on !windows
261-
is_vls bool
262-
json_errors bool // -json-errors, for VLS and other tools
260+
subsystem Subsystem // the type of the window app, that is going to be generated; has no effect on !windows
261+
is_vls bool
262+
json_errors bool // -json-errors, for VLS and other tools
263+
new_transform bool // temporary for the new transformer
263264
}
264265

265266
pub fn parse_args(known_external_commands []string, args []string) (&Preferences, string) {
@@ -762,6 +763,9 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin
762763
'-experimental' {
763764
res.experimental = true
764765
}
766+
'-new-transformer' {
767+
res.new_transform = true
768+
}
765769
'-usecache' {
766770
res.use_cache = true
767771
}

vlib/v/transformer/transformer.v

Lines changed: 120 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -554,12 +554,7 @@ pub fn (mut t Transformer) expr(mut node ast.Expr) ast.Expr {
554554
node.expr = t.expr(mut node.expr)
555555
}
556556
ast.ArrayInit {
557-
for mut expr in node.exprs {
558-
expr = t.expr(mut expr)
559-
}
560-
node.len_expr = t.expr(mut node.len_expr)
561-
node.cap_expr = t.expr(mut node.cap_expr)
562-
node.init_expr = t.expr(mut node.init_expr)
557+
return t.array_init(mut node)
563558
}
564559
ast.AsCast {
565560
node.expr = t.expr(mut node.expr)
@@ -1153,6 +1148,125 @@ pub fn (mut t Transformer) infix_expr(mut node ast.InfixExpr) ast.Expr {
11531148
}
11541149
}
11551150

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 := '_noscan' // 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+
}
1191+
sizeof_arg := ast.CallArg{
1192+
expr: ast.SizeOf{
1193+
is_type: true
1194+
typ: node.elem_type
1195+
}
1196+
}
1197+
fixed_array_arg := ast.CallArg{
1198+
expr: ast.ArrayInit{
1199+
is_fixed: true
1200+
has_val: true
1201+
typ: t.table.find_or_register_array_fixed(node.elem_type, len, ast.empty_expr,
1202+
false)
1203+
elem_type: node.elem_type
1204+
exprs: node.exprs
1205+
}
1206+
}
1207+
// if false { // elem_type.unaliased_sym.kind == .function {
1208+
//} else {
1209+
fn_name = 'new_array_from_c_array' + noscan
1210+
// g.write('builtin__new_array_from_c_array${noscan}(${len}, ${len}, sizeof(${elem_styp}), _MOV((${elem_styp}[${len}]){')
1211+
//}
1212+
call_expr := ast.CallExpr{
1213+
name: fn_name
1214+
mod: 'builtin'
1215+
scope: ast.empty_scope // node.scope
1216+
args: [len_arg, len_arg, sizeof_arg, fixed_array_arg] //, sizeof(voidptr), _MOV((voidptr[${len}]){')
1217+
return_type: node.typ
1218+
}
1219+
// println('call expr')
1220+
// println(call_expr)
1221+
return call_expr
1222+
/*
1223+
if len > 8 {
1224+
g.writeln('')
1225+
g.write('\t\t')
1226+
}
1227+
is_iface_or_sumtype := elem_sym.kind in [.sum_type, .interface]
1228+
for i, expr in node.exprs {
1229+
expr_type := if node.expr_types.len > i { node.expr_types[i] } else { node.elem_type }
1230+
if expr_type == ast.string_type
1231+
&& expr !in [ast.IndexExpr, ast.CallExpr, ast.StringLiteral, ast.StringInterLiteral, ast.InfixExpr] {
1232+
if is_iface_or_sumtype {
1233+
g.expr_with_cast(expr, expr_type, node.elem_type)
1234+
} else {
1235+
g.write('builtin__string_clone(')
1236+
g.expr(expr)
1237+
g.write(')')
1238+
}
1239+
} else {
1240+
if node.elem_type.has_flag(.option) {
1241+
g.expr_with_opt(expr, expr_type, node.elem_type)
1242+
} else if elem_type.unaliased_sym.kind == .array_fixed
1243+
&& expr in [ast.Ident, ast.SelectorExpr] {
1244+
info := elem_type.unaliased_sym.info as ast.ArrayFixed
1245+
g.fixed_array_var_init(g.expr_string(expr), expr.is_auto_deref_var(),
1246+
info.elem_type, info.size)
1247+
} else {
1248+
g.expr_with_cast(expr, expr_type, node.elem_type)
1249+
}
1250+
}
1251+
if i != len - 1 {
1252+
if i > 0 && i & 7 == 0 { // i > 0 && i % 8 == 0
1253+
g.writeln(',')
1254+
g.write('\t\t')
1255+
} else {
1256+
g.write(', ')
1257+
}
1258+
}
1259+
}
1260+
g.write('}))')
1261+
if g.is_shared {
1262+
g.write('}, sizeof(${shared_styp}))')
1263+
} else if is_amp {
1264+
g.write(')')
1265+
}
1266+
*/
1267+
//}
1268+
}
1269+
11561270
pub fn (mut t Transformer) if_expr(mut node ast.IfExpr) ast.Expr {
11571271
for mut branch in node.branches {
11581272
branch.cond = t.expr(mut branch.cond)

0 commit comments

Comments
 (0)