Parse remaining GRIT_POWER grammar extensions (INTABLE, TABINIT, SAFENAV, CCOMMENT) - #1
Merged
solareon merged 6 commits intoAug 29, 2026
Conversation
Matches GRIT_POWER_INTABLE's local-declaration form: `local a, b in t` desugars at parse time into `local a, b = t.a, t.b`, so the rest of the checker treats it identically to a normal local assignment. Note: if `t` itself is undefined, this reports one warning per destructured name at the same position, since the desugar references the single physical occurrence of `t` once per field.
Matches GRIT_POWER_INTABLE's non-local form: `a, b in t` desugars into `a, b = t.a, t.b`. Each lhs target's own name/field selects the key read back out of t: `a` reads t.a, `x.y` or `x[1]` reads t.y or t[1]. Targets without a literal name or index (e.g. `x[y]`) are rejected, matching the same restriction the reference grammar enforces at the assignment-key step. Same disclosed caveat as the local form: if t itself is undefined, it warns once per destructured name at the same position.
Matches GRIT_POWER_TABINIT: a table-constructor field can now be written
as `.name` (alternative to `name =`/`[expr] =`) and either dot or
bracket form may omit `= expr`, in which case the value defaults to
`true` (the synthesized True node borrows the key's own source range).
`{ .a = 1, .b, [2] = 3, [4] }` now parses like
`{ a = 1, b = true, [2] = 3, [4] = true }`.
Matches the rest of GRIT_POWER_SAFENAV: `?.` and `?[` were already
supported, but `?:` (safe method call) and `?(`/`?{`/`?"..."` (safe
funcargs) were not. The lexer already falls back to a bare "?" token for
anything other than `?.`/`?[` (it only special-cases those two), so this
adds one generic suffix_handlers["?"] that delegates to whichever plain
handler follows: safe navigation only changes runtime short-circuiting,
not the AST shape, so `t?:m()` parses to the same Invoke node as
`t:m()`. Chains like `t?.a?.b?:c()` fall out for free since the suffix
loop already re-enters on each iteration.
Matches GRIT_POWER_CCOMMENT: /* ... */ is now recognized after '/' in lex_div, alongside the existing '/' and '//' cases. It reuses the existing "long_comment" token type, so the parser needs no changes: it's treated exactly like a "--[[ ]]" long comment for line-ending and line-count tracking. Like "--[[ ]]" today, its contents are not captured and it does not feed inline "luacheck: ignore" directives, only "--" short comments do that. Closer detection tracks the previous byte (mirroring the reference lexer's last == '*' && current == '/' check), so a lone '*' followed by non-'/' or a stray leading '/' (e.g. "/*/ ... */") doesn't close early.
suffix_handlers["?"] delegated to whatever handler matched the next
token, which included "?." and "?[" themselves, so "t??.b" and
"t??[1]" silently parsed as valid (delegating straight into those
combined-token handlers) even though the reference grammar has no
second '?' to consume there, only "?:" and "?("/"?{"/"?\"...\"" are
valid after a bare '?'. Restrict the delegation to that exact set.
Author
|
*Claude Code Assistance |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fills in the FiveM/GRIT-Lua syntax extensions this fork's parser/lexer didn't yet recognize, checked directly against
citizenfx/luaatluaglm-548(CMakeLists.txtGRIT_POWER_* options +lparser.c/llex.c), not just from memory of the feature names.Each commit is one feature, self-contained:
local a, b in t) and destructuring reassignment (a, b in t) — the two grammar positionsGRIT_POWER_INTABLEcovers (localstatandrestassignin the reference parser). Both desugar at parse time into the equivalent field-access assignment (a, b = t.a, t.b), so the rest of the checker treats them like ordinary assignments with zero changes elsewhere. For the reassignment form, each lhs target's own name/field selects the key read back out oft(x.yreadst.y,x[1]readst[1]); targets without a literal name or index (x[y]) are rejected, matching the same restrictiongetassignkeyenforces in the reference implementation.GRIT_POWER_TABINIT) —.name = valas an alternative toname =/[expr] =, and either dot or bracket form may omit= expr, defaulting the value totrue.GRIT_POWER_SAFENAV) —?.and?[already worked; this adds?:,?(,?{,?"...". The lexer already falls back to a bare"?"token for anything other than?./?[(confirmed by readinglex_qm, not assumed), so this is one genericsuffix_handlers["?"]that delegates to whichever plain handler follows, restricted to the funcargs/method token set so a strayt??.bstill correctly errors (caught by a second review pass, see commit history).GRIT_POWER_CCOMMENT) —/* ... */, reusing the existing"long_comment"token so the parser needs no changes; treated exactly like--[[ ]]for line tracking, and like--[[ ]]it doesn't feed inlineluacheck: ignoredirectives (only--short comments do that today).Deliberately not included:
GRIT_POWER_EACH/BLOB/WOW/CHRONO/READLINE_HISTORY/DEFER_OLDare runtime/stdlib features (a__itermetamethod, C API additions, timers, REPL history, a library function), not grammar — nothing for a static parser to recognize.GRIT_POWER_NAMESPACE_SELshipsOFFin this repo's ownCMakeLists.txt/makefile, so it isn't part of the actual reference build.GRIT_POWER_COMPOUND(+=etc.) turned out to already work end-to-end (compound_operators+ theOpSetnode), so there's no commit for it.Known limitation (disclosed, not fixed)
All three
in/desugar-style features share one artifact: if the right-hand base expression is itself undefined, you get one warning per destructured name/target, at the same line:column, since the desugar references one physical source occurrence multiple times. E.g.local a, b in undefinedTblreportsaccessing undefined variable 'undefinedTbl'twice at the identical position, rather than the hand-written form's two distinct columns. Happy to add dedup if you'd rather have it, but didn't want to build a hidden-temp-local AST shape to chase a cosmetic duplicate without checking first.Test plan
luacheck.check_stringsreports syntax errors as report items rather than exceptions, so this required checking for code011explicitly, not pcall alone)spec/parser_spec.lua/spec/lexer_spec.lua, matching existing style and asserting real captured offsets, not guessed ones?./?[, existing comments, etc.)