v / vlib / v2 / ssa / build_init_expr_ptr_from_flat_test.v
117 lines · 109 sloc · 2.88 KB · b384d9b10920270ef9a04eca8044157ae01aa4c1
Raw
1// Copyright (c) 2026 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// vtest build: macos
5//
6// Bit-equality pin for s208: cursor-native `build_init_expr_ptr_from_flat` and
7// `collect_init_expr_values_from_flat`. The previous `build_prefix_from_flat`
8// `&InitExpr` branch decoded the inner InitExpr via `decode_expr` and
9// dispatched to legacy `build_init_expr_ptr`; the cursor-native rewrite
10// reads `typ` from edge(0) and walks the field aux cursors at edge(1..),
11// resolving each field name via `field_c.name()` and value via
12// `field_c.edge(0)` through `build_expr_from_flat`.
13module ssa
14
15import v2.ast
16import v2.types
17
18fn ip_ident(name string) ast.Expr {
19 return ast.Expr(ast.Ident{
20 name: name
21 })
22}
23
24fn ip_num(value string) ast.Expr {
25 return ast.Expr(ast.BasicLiteral{
26 kind: .number
27 value: value
28 })
29}
30
31fn make_init_ptr_fixture() []ast.File {
32 mut stmts := [
33 ast.Stmt(ast.ModuleStmt{
34 name: 'main'
35 }),
36 ]
37 stmts << ast.Stmt(ast.StructDecl{
38 name: 'Point'
39 fields: [
40 ast.FieldDecl{
41 name: 'x'
42 typ: ip_ident('int')
43 },
44 ast.FieldDecl{
45 name: 'y'
46 typ: ip_ident('int')
47 },
48 ]
49 })
50 // fn make_point() { p := &Point{x: 1, y: 2} _ = p }
51 stmts << ast.Stmt(ast.FnDecl{
52 name: 'make_point'
53 typ: ast.FnType{
54 return_type: ast.empty_expr
55 }
56 stmts: [
57 ast.Stmt(ast.AssignStmt{
58 op: .decl_assign
59 lhs: [ip_ident('p')]
60 rhs: [
61 ast.Expr(ast.PrefixExpr{
62 op: .amp
63 expr: ast.Expr(ast.InitExpr{
64 typ: ip_ident('Point')
65 fields: [
66 ast.FieldInit{
67 name: 'x'
68 value: ip_num('1')
69 },
70 ast.FieldInit{
71 name: 'y'
72 value: ip_num('2')
73 },
74 ]
75 })
76 }),
77 ]
78 }),
79 ]
80 })
81 return [
82 ast.File{
83 name: 'main.v'
84 mod: 'main'
85 stmts: stmts
86 },
87 ]
88}
89
90fn build_via_legacy_init_ptr(files []ast.File, env &types.Environment, name string) &Module {
91 mut mod := Module.new(name)
92 mut b := Builder.new_with_env(mod, env)
93 b.register_fn_signatures(files[0])
94 b.build_fn_bodies(files[0])
95 return mod
96}
97
98fn build_via_flat_init_ptr(files []ast.File, env &types.Environment, name string) &Module {
99 flat := ast.flatten_files(files)
100 mut mod := Module.new(name)
101 mut b := Builder.new_with_env(mod, env)
102 b.register_fn_signatures_from_flat(flat.file_cursor(0))
103 b.build_fn_bodies_from_flat(flat.file_cursor(0))
104 return mod
105}
106
107fn test_build_init_expr_ptr_from_flat_matches_legacy() {
108 files := make_init_ptr_fixture()
109 env := types.Environment.new()
110 mod_legacy := build_via_legacy_init_ptr(files, env, 'init_ptr_legacy')
111 mod_flat := build_via_flat_init_ptr(files, env, 'init_ptr_flat')
112
113 assert mod_legacy.funcs.len == mod_flat.funcs.len
114 assert mod_legacy.blocks.len == mod_flat.blocks.len
115 assert mod_legacy.instrs.len == mod_flat.instrs.len
116 assert mod_legacy.values.len == mod_flat.values.len
117}
118