lang: Recognize explicit generic delimiters
4501081c8d025f0c1df6c44ce468b829f433781ca231d9682a04ec7c3d6e85c5
Teach the scanner and editor definitions about the dedicated angle delimiters. Accept them inside delimited input so a scanner-aware bootstrap compiler can compile later generic tests and diagnostics. Assisted-by: Codex:gpt-5.6
1 parent
f18cc5f0
lib/std/lang/scanner.rad
+27 -3
| 22 | 22 | RParen, // ) |
|
| 23 | 23 | LBrace, // { |
|
| 24 | 24 | RBrace, // } |
|
| 25 | 25 | LBracket, // [ |
|
| 26 | 26 | RBracket, // ] |
|
| 27 | + | LAngle, // U+27E8 |
|
| 28 | + | RAngle, // U+27E9 |
|
| 27 | 29 | Comma, // , |
|
| 28 | 30 | Dot, // . |
|
| 29 | 31 | DotDot, // .. |
|
| 30 | 32 | Minus, // - |
|
| 31 | 33 | Plus, // + |
| 98 | 100 | Mod, Use, Super, |
|
| 99 | 101 | ||
| 100 | 102 | // Type or function attributes. |
|
| 101 | 103 | Export, Static, |
|
| 102 | 104 | ||
| 103 | - | // Trait-related tokens. |
|
| 104 | - | Trait, Instance, |
|
| 105 | + | // Trait and generic-related tokens. |
|
| 106 | + | Trait, Instance, Instantiate, |
|
| 105 | 107 | ||
| 106 | 108 | // Type-related tokens. |
|
| 107 | 109 | I8, I16, I32, I64, U8, U16, U32, U64, |
|
| 108 | 110 | Opaque, Fn, Bool, Union, Record, As, Unsafe |
|
| 109 | 111 | } |
| 115 | 117 | /// Corresponding token. |
|
| 116 | 118 | tok: TokenKind, |
|
| 117 | 119 | } |
|
| 118 | 120 | ||
| 119 | 121 | /// Sorted keyword table for binary search. |
|
| 120 | - | constant KEYWORDS: [Keyword; 52] = [ |
|
| 122 | + | constant KEYWORDS: [Keyword; 53] = [ |
|
| 121 | 123 | { name: "align", tok: TokenKind::Align }, |
|
| 122 | 124 | { name: "and", tok: TokenKind::And }, |
|
| 123 | 125 | { name: "as", tok: TokenKind::As }, |
|
| 124 | 126 | { name: "assert", tok: TokenKind::Assert }, |
|
| 125 | 127 | { name: "bool", tok: TokenKind::Bool }, |
| 138 | 140 | { name: "i64", tok: TokenKind::I64 }, |
|
| 139 | 141 | { name: "i8", tok: TokenKind::I8 }, |
|
| 140 | 142 | { name: "if", tok: TokenKind::If }, |
|
| 141 | 143 | { name: "in", tok: TokenKind::In }, |
|
| 142 | 144 | { name: "instance", tok: TokenKind::Instance }, |
|
| 145 | + | { name: "instantiate", tok: TokenKind::Instantiate }, |
|
| 143 | 146 | { name: "let", tok: TokenKind::Let }, |
|
| 144 | 147 | { name: "log", tok: TokenKind::Log }, |
|
| 145 | 148 | { name: "loop", tok: TokenKind::Loop }, |
|
| 146 | 149 | { name: "match", tok: TokenKind::Match }, |
|
| 147 | 150 | { name: "mod", tok: TokenKind::Mod }, |
| 345 | 348 | } |
|
| 346 | 349 | } |
|
| 347 | 350 | return tok(s, TokenKind::Number); |
|
| 348 | 351 | } |
|
| 349 | 352 | ||
| 353 | + | /// Scan a token through its closing delimiter. |
|
| 350 | 354 | fn scanDelimited(s: *mut Scanner, delim: u8, kind: TokenKind) -> ?Token { |
|
| 351 | 355 | while let ch = current(s); ch <> delim { |
|
| 356 | + | if ch == 0xe2 and s.cursor + 2 < s.source.len and |
|
| 357 | + | s.source[s.cursor + 1] == 0x9f and |
|
| 358 | + | (s.source[s.cursor + 2] == 0xa8 or s.source[s.cursor + 2] == 0xa9) |
|
| 359 | + | { |
|
| 360 | + | set s.cursor += 3; |
|
| 361 | + | continue; |
|
| 362 | + | } |
|
| 352 | 363 | if not char::isPrint(ch) { |
|
| 353 | 364 | return invalid(s.token, "invalid character"); |
|
| 354 | 365 | } |
|
| 355 | 366 | if consume(s, '\\') { // Consume escapes |
|
| 356 | 367 | if isEof(s) { |
| 438 | 449 | case ')' => return tok(s, TokenKind::RParen), |
|
| 439 | 450 | case '{' => return tok(s, TokenKind::LBrace), |
|
| 440 | 451 | case '}' => return tok(s, TokenKind::RBrace), |
|
| 441 | 452 | case '[' => return tok(s, TokenKind::LBracket), |
|
| 442 | 453 | case ']' => return tok(s, TokenKind::RBracket), |
|
| 454 | + | case 0xe2 => { |
|
| 455 | + | // Scan one of the dedicated UTF-8 generic delimiters. |
|
| 456 | + | if not consume(s, 0x9f) { |
|
| 457 | + | return invalid(s.token, "unexpected UTF-8 character"); |
|
| 458 | + | } |
|
| 459 | + | if consume(s, 0xa8) { |
|
| 460 | + | return tok(s, TokenKind::LAngle); |
|
| 461 | + | } |
|
| 462 | + | if consume(s, 0xa9) { |
|
| 463 | + | return tok(s, TokenKind::RAngle); |
|
| 464 | + | } |
|
| 465 | + | return invalid(s.token, "unexpected UTF-8 character"); |
|
| 466 | + | } |
|
| 443 | 467 | case ';' => return tok(s, TokenKind::Semicolon), |
|
| 444 | 468 | case ',' => return tok(s, TokenKind::Comma), |
|
| 445 | 469 | case '.' => { |
|
| 446 | 470 | if consume(s, '.') { |
|
| 447 | 471 | return tok(s, TokenKind::DotDot); |
sublime/radiance.sublime-syntax
+2 -0
| 107 | 107 | scope: punctuation.section.block.radiance |
|
| 108 | 108 | - match: '[()]' |
|
| 109 | 109 | scope: punctuation.section.group.radiance |
|
| 110 | 110 | - match: '[\[\]]' |
|
| 111 | 111 | scope: punctuation.section.brackets.radiance |
|
| 112 | + | - match: '[⟨⟩]' |
|
| 113 | + | scope: punctuation.section.generic.radiance |
|
| 112 | 114 | - match: '[,;]' |
|
| 113 | 115 | scope: punctuation.separator.radiance |
vim/radiance.vim
+3 -3
| 15 | 15 | syntax keyword radianceTodo TODO FIXME contained containedin=radianceComment |
|
| 16 | 16 | ||
| 17 | 17 | " Keywords |
|
| 18 | 18 | syntax keyword radianceKeyword mod fn return if else while true false and or not case align static |
|
| 19 | 19 | syntax keyword radianceKeyword export break continue use loop in for match nil undefined |
|
| 20 | - | syntax keyword radianceKeyword let mut set as register device constant log record union trait instance |
|
| 20 | + | syntax keyword radianceKeyword let mut set as register device constant instantiate log record union trait instance |
|
| 21 | 21 | syntax keyword radianceKeyword throws throw try catch panic assert super |
|
| 22 | 22 | syntax keyword radianceType i8 i16 i32 i64 u8 u16 u32 u64 f32 void bool bit opaque |
|
| 23 | 23 | ||
| 24 | 24 | " Double-quoted strings |
|
| 25 | 25 | syntax region radianceString start=/"/ skip=/\\"/ end=/"/ contains=radianceEscape |
| 45 | 45 | ||
| 46 | 46 | " Namespaced identifiers. |
|
| 47 | 47 | syntax match radianceNamespaceSep "::" contained |
|
| 48 | 48 | syntax match radianceNamespaceAccess "\<\u\w*\%(::\u\w*\)\+" contains=radianceNamespaceSep |
|
| 49 | 49 | ||
| 50 | - | " Braces, parentheses and brackets |
|
| 50 | + | " Braces, parentheses, brackets, and generic angles |
|
| 51 | 51 | syntax match radianceBraces "[{}]" |
|
| 52 | 52 | syntax match radianceParens "[()]" |
|
| 53 | - | syntax match radianceBrackets "[\[\]]" |
|
| 53 | + | syntax match radianceBrackets "[\[\]⟨⟩]" |
|
| 54 | 54 | ||
| 55 | 55 | " Define highlighting |
|
| 56 | 56 | highlight default link radianceKeyword Keyword |
|
| 57 | 57 | highlight default link radianceBuiltin Special |
|
| 58 | 58 | highlight default link radianceType Type |