ReviewOS

also looking at this

home-lang/home

fix(parser): accept prefixed and suffixed numeric literals in match patterns

#927
Open mkantautas wants to merge fix/match-pattern-int-literals into main
2 files +103 -6
packages/parser/tests/parser_test.zigmodified+57-0
Changes to packages/parser/tests/parser_test.zig
@@ -2087,3 +2087,60 @@ test "parser: assert macro preserves a comparison condition" {
20872087 try testing.expect(assert_stmt.message.?.* == .StringLiteral);
20882088 try testing.expectEqualStrings("division by zero", assert_stmt.message.?.StringLiteral.value);
20892089}
2090
2091test "parser: match statement numeric patterns accept hex, binary, octal and type suffixes" {
2092 const allocator = testing.allocator;
2093 const source =
2094 \\match x {
2095 \\ 0xFF => 1,
2096 \\ 0b101 => 2,
2097 \\ 0o17 => 3,
2098 \\ 7u8 => 4,
2099 \\ -0x10 => 5,
2100 \\ 0x30..=0x39 => 6,
2101 \\ 1.5f32 => 7,
2102 \\ _ => 0,
2103 \\}
2104 ;
2105 var lexer = Lexer.init(allocator, source);
2106 var tokens = try lexer.tokenize();
2107 defer tokens.deinit(allocator);
2108 var parser = try Parser.init(allocator, tokens.items);
2109 defer parser.deinit();
2110 const program = try parser.parse();
2111 defer program.deinit(allocator);
2112
2113 try testing.expectEqual(@as(usize, 0), parser.errors.items.len);
2114 try testing.expectEqual(@as(usize, 1), program.statements.len);
2115 try testing.expect(program.statements[0] == .MatchStmt);
2116
2117 const arms = program.statements[0].MatchStmt.arms;
2118 try testing.expectEqual(@as(usize, 8), arms.len);
2119 try testing.expectEqual(@as(i64, 255), arms[0].pattern.IntLiteral);
2120 try testing.expectEqual(@as(i64, 5), arms[1].pattern.IntLiteral);
2121 try testing.expectEqual(@as(i64, 15), arms[2].pattern.IntLiteral);
2122 try testing.expectEqual(@as(i64, 7), arms[3].pattern.IntLiteral);
2123 try testing.expectEqual(@as(i64, -16), arms[4].pattern.IntLiteral);
2124 try testing.expectEqual(@as(i128, 0x30), arms[5].pattern.Range.start.IntegerLiteral.value);
2125 try testing.expectEqual(@as(i128, 0x39), arms[5].pattern.Range.end.IntegerLiteral.value);
2126 try testing.expectEqual(@as(f64, 1.5), arms[6].pattern.FloatLiteral);
2127 try testing.expect(arms[7].pattern.* == .Wildcard);
2128}
2129
2130test "parser: match statement reports numeric patterns that do not parse" {
2131 const allocator = testing.allocator;
2132 for ([_][]const u8{
2133 "match x {\n 0xFFFFFFFFFFFFFFFF => 1,\n _ => 0,\n}",
2134 "match x {\n 1.0e+ => 1,\n _ => 0,\n}",
2135 }) |source| {
2136 var lexer = Lexer.init(allocator, source);
2137 var tokens = try lexer.tokenize();
2138 defer tokens.deinit(allocator);
2139 var parser = try Parser.init(allocator, tokens.items);
2140 defer parser.deinit();
2141 const program = try parser.parse();
2142 defer program.deinit(allocator);
2143
2144 try testing.expect(parser.errors.items.len > 0);
2145 }
2146}