Skip to content

Commit f999bda

Browse files
committed
v2: move lots of logic from cleanc to transformer
1 parent de46b1c commit f999bda

7 files changed

Lines changed: 1930 additions & 1384 deletions

File tree

‎cmd/v2/test.v‎

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,37 @@ fn flag_enum_check_int_args() int {
545545
return simple_two_arg(3, 4) // Expected: 304
546546
}
547547

548+
fn test_flag_enum_set_clear() {
549+
mut p := Permissions.read
550+
// .set() adds a flag
551+
p.set(.write)
552+
assert p.has(.read)
553+
assert p.has(.write)
554+
assert !p.has(.execute)
555+
print_int(int(p)) // 3 (read=1 | write=2)
556+
557+
// .set() another flag
558+
p.set(.execute)
559+
assert p.has(.execute)
560+
assert p.all(Permissions.read | Permissions.write | Permissions.execute)
561+
print_int(int(p)) // 7 (1|2|4)
562+
563+
// .clear() removes a flag
564+
p.clear(.write)
565+
assert p.has(.read)
566+
assert !p.has(.write)
567+
assert p.has(.execute)
568+
print_int(int(p)) // 5 (read=1 | execute=4)
569+
570+
// .clear() then .set() same flag
571+
p.clear(.read)
572+
p.set(.write)
573+
assert !p.has(.read)
574+
assert p.has(.write)
575+
assert p.has(.execute)
576+
print_int(int(p)) // 6 (write=2 | execute=4)
577+
}
578+
548579
// ===================== IF-GUARD HELPERS =====================
549580

550581
// Returns the value if positive, none otherwise
@@ -1268,6 +1299,146 @@ fn test_map_or_array_value() {
12681299
print_str('map or-block array value type: ok')
12691300
}
12701301

1302+
fn test_interface_fn_pointer_dispatch() {
1303+
// Interface method calls are lowered by the transformer into fn-pointer
1304+
// field calls: iface.method(iface._object, args...).
1305+
// cleanc handles these through the generic fn-pointer call path.
1306+
1307+
// 93.1 Drawable interface - zero-arg method
1308+
pt1 := Point{
1309+
x: 8
1310+
y: 2
1311+
}
1312+
d1 := Drawable(pt1)
1313+
print_int(d1.draw()) // 8*1000 + 2 = 8002
1314+
1315+
// 93.2 Calculator interface - multi-arg method
1316+
pt2 := Point{
1317+
x: 10
1318+
y: 5
1319+
}
1320+
calc := Calculator(pt2)
1321+
print_int(calc.add(3, 7)) // 10 + 5 + 3 + 7 = 25
1322+
print_int(calc.multiply(4)) // (10 + 5) * 4 = 60
1323+
1324+
// 93.3 Shape interface - multiple methods
1325+
rect := Rectangle{
1326+
width: 6
1327+
height: 4
1328+
origin: Point{
1329+
x: 0
1330+
y: 0
1331+
}
1332+
}
1333+
shape := Shape(rect)
1334+
print_int(shape.area()) // 6 * 4 = 24
1335+
print_int(shape.perimeter()) // 2 * (6 + 4) = 20
1336+
1337+
// 93.4 Sum of interface method results
1338+
pt3 := Point{
1339+
x: 3
1340+
y: 7
1341+
}
1342+
d2 := Drawable(pt3)
1343+
pt4 := Point{
1344+
x: 1
1345+
y: 9
1346+
}
1347+
d3 := Drawable(pt4)
1348+
print_int(d2.draw() + d3.draw()) // 3007 + 1009 = 4016
1349+
}
1350+
1351+
fn test_sumtype_type_name() {
1352+
// Test .type_name() on sumtype with struct variants
1353+
s1 := Stmt89(AssignStmt89{
1354+
value: 42
1355+
})
1356+
assert s1.type_name() == 'AssignStmt89'
1357+
1358+
s2 := Stmt89(ExprStmt89{
1359+
value: 7
1360+
})
1361+
assert s2.type_name() == 'ExprStmt89'
1362+
1363+
s3 := Stmt89(BlockStmt89{
1364+
stmts: []
1365+
})
1366+
assert s3.type_name() == 'BlockStmt89'
1367+
1368+
// Test .type_name() on sumtype with primitive variants
1369+
v1 := InnerSumType(123)
1370+
assert v1.type_name() == 'int'
1371+
1372+
v2 := InnerSumType('hello')
1373+
assert v2.type_name() == 'string'
1374+
1375+
// Test .type_name() on nested sumtype
1376+
v3 := OuterSumType(true)
1377+
assert v3.type_name() == 'bool'
1378+
1379+
print_str('sumtype type_name: ok')
1380+
}
1381+
1382+
// ==== Test 95: Method call resolution ====
1383+
// Tests that the transformer correctly resolves receiver.method(args) -> Type__method(receiver, args)
1384+
1385+
struct Counter95 {
1386+
mut:
1387+
value int
1388+
}
1389+
1390+
fn (c &Counter95) get() int {
1391+
return c.value
1392+
}
1393+
1394+
fn (mut c Counter95) add(n int) {
1395+
c.value += n
1396+
}
1397+
1398+
fn (c &Counter95) sum_with(other &Counter95) int {
1399+
return c.value + other.value
1400+
}
1401+
1402+
fn test_method_call_resolution() {
1403+
// 95.1 Struct method call (immutable receiver)
1404+
c1 := Counter95{
1405+
value: 42
1406+
}
1407+
assert c1.get() == 42
1408+
1409+
// 95.2 Struct method call (mutable receiver)
1410+
mut c2 := Counter95{
1411+
value: 10
1412+
}
1413+
c2.add(5)
1414+
assert c2.get() == 15
1415+
1416+
// 95.3 Method call with struct argument
1417+
c3 := Counter95{
1418+
value: 20
1419+
}
1420+
assert c2.sum_with(c3) == 35
1421+
1422+
// 95.4 Array method (push + len chain)
1423+
mut arr := []int{}
1424+
arr << 1
1425+
arr << 2
1426+
arr << 3
1427+
assert arr.len == 3
1428+
1429+
// 95.5 String method call
1430+
s := 'hello world'
1431+
assert s.contains('world')
1432+
assert s.replace('world', 'v') == 'hello v'
1433+
1434+
// 95.6 Chained method calls
1435+
s2 := 'Hello World'
1436+
result := s2.replace('World', 'V').replace('Hello', 'Hi')
1437+
assert result == 'Hi V'
1438+
1439+
print_str('method call resolution: ok')
1440+
}
1441+
12711442
// ===================== MAIN TEST FUNCTION =====================
12721443

12731444
fn main() {
@@ -3804,6 +3975,18 @@ fn main() {
38043975
small_nums := filter_arr.filter(it <= 6)
38053976
print_int(small_nums.len) // 6
38063977

3978+
// 56.5 Filter as function argument (non-assignment context)
3979+
print_int(filter_arr.filter(it > 3).len) // 3
3980+
3981+
// 56.6 Map in assignment context
3982+
mapped := filter_arr.map(it * 2)
3983+
print_int(mapped.len) // 6
3984+
print_int(mapped[0]) // 2
3985+
print_int(mapped[5]) // 12
3986+
3987+
// 56.7 Map as function argument (non-assignment context)
3988+
print_int(filter_arr.map(it + 10).len) // 6
3989+
38073990
// ==================== 57. ARRAY STR (auto-generated) ====================
38083991
print_str('--- 57. Array str ---')
38093992

@@ -4791,5 +4974,22 @@ fn main() {
47914974
print_str('--- Test 91: Map or-block with array value ---')
47924975
test_map_or_array_value()
47934976

4977+
// ==================== 92. FLAG ENUM SET/CLEAR ====================
4978+
// Tests flag enum .set() and .clear() methods (transformer lowering to |= and &=~)
4979+
print_str('--- Test 92: Flag enum set/clear ---')
4980+
test_flag_enum_set_clear()
4981+
4982+
print_str('--- Test 93: Interface method dispatch via fn-pointer ---')
4983+
test_interface_fn_pointer_dispatch()
4984+
4985+
print_str('--- Test 94: Sumtype .type_name() ---')
4986+
test_sumtype_type_name()
4987+
4988+
// ==================== 95. METHOD CALL RESOLUTION ====================
4989+
// Tests transformer-based method resolution: receiver.method(args) -> Type__method(receiver, args)
4990+
// Exercises struct methods, array methods, and chained calls.
4991+
print_str('--- Test 95: Method call resolution ---')
4992+
test_method_call_resolution()
4993+
47944994
print_str('=== All tests completed ===')
47954995
}

0 commit comments

Comments
 (0)