@@ -248,9 +248,22 @@ fn (mut p Parser) stmt() ast.Stmt {
248248 }
249249 .key_defer {
250250 p.next ()
251+ mut defer_mode := ast.DeferMode.scoped
252+ if p.tok == .lpar {
253+ p.next ()
254+ if p.tok == .key_fn {
255+ defer_mode = .function
256+ p.next ()
257+ } else {
258+ mode := p.expect_name ()
259+ p.error ('unknown `defer` mode: `${mode }`' )
260+ }
261+ p.expect (.rpar)
262+ }
251263 stmts := p.block ()
252264 p.expect (.semicolon)
253265 return ast.DeferStmt{
266+ mode: defer_mode
254267 stmts: stmts
255268 }
256269 }
@@ -1250,6 +1263,18 @@ fn (mut p Parser) expect_name() string {
12501263 return name
12511264}
12521265
1266+ // expect `.name` or keyword & return `p.lit` & go to next token
1267+ // used for C/JS function names where keywords are allowed (e.g. `C.select`)
1268+ @[inline]
1269+ fn (mut p Parser) expect_name_or_keyword () string {
1270+ if p.tok != .name && ! p.tok.is_keyword () {
1271+ p.error_expected (.name, p.tok)
1272+ }
1273+ name := p.lit
1274+ p.next ()
1275+ return name
1276+ }
1277+
12531278// return `p.lit` & go to next token
12541279@[inline]
12551280fn (mut p Parser) lit () string {
@@ -1778,7 +1803,8 @@ fn (mut p Parser) fn_decl(is_public bool, attributes []ast.Attribute) ast.FnDecl
17781803 }
17791804 }
17801805 language := p.decl_language ()
1781- name_ident := p.ident ()
1806+ // use ident_or_keyword() for C/JS functions to allow keywords as names (e.g. `C.select`)
1807+ name_ident := if language == .v { p.ident () } else { p.ident_or_keyword () }
17821808 mut name := name_ident.name
17831809 mut is_static := false
17841810 if p.tok == .dot {
@@ -1793,11 +1819,12 @@ fn (mut p Parser) fn_decl(is_public bool, attributes []ast.Attribute) ast.FnDecl
17931819 }
17941820 }
17951821 // eg. `Promise.resolve` in `JS.Promise.resolve`
1822+ // use expect_name_or_keyword() to allow keywords as names (e.g. `C.select`)
17961823 else {
1797- name + = '.' + p.expect_name ()
1824+ name + = '.' + p.expect_name_or_keyword ()
17981825 for p.tok == .dot {
17991826 p.next ()
1800- name + = '.' + p.expect_name ()
1827+ name + = '.' + p.expect_name_or_keyword ()
18011828 }
18021829 }
18031830 }
@@ -2390,6 +2417,15 @@ fn (mut p Parser) ident() ast.Ident {
23902417 }
23912418}
23922419
2420+ // like ident() but allows keywords as names (for C/JS function names like `C.select`)
2421+ @[inline]
2422+ fn (mut p Parser) ident_or_keyword () ast.Ident {
2423+ return ast.Ident{
2424+ pos: p.pos
2425+ name: p.expect_name_or_keyword ()
2426+ }
2427+ }
2428+
23932429@[inline]
23942430fn (mut p Parser) ident_or_selector_expr () ast.Expr {
23952431 ident := p.ident ()
@@ -2407,9 +2443,15 @@ fn (mut p Parser) ident_or_selector_expr() ast.Expr {
24072443 pos: p.pos
24082444 }
24092445 }
2446+ // for C/JS calls, allow keywords as names (e.g. `C.select`)
2447+ rhs := if ident.name == 'C' || ident.name == 'JS' {
2448+ p.ident_or_keyword ()
2449+ } else {
2450+ p.ident ()
2451+ }
24102452 return ast.SelectorExpr{
24112453 lhs: ident
2412- rhs: p. ident ()
2454+ rhs: rhs
24132455 pos: p.pos
24142456 }
24152457 }
0 commit comments