@@ -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
12731444fn 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