feat: add generic positional element access - #21
Conversation
📝 WalkthroughWalkthroughThe grammar now supports ChangesPositional element access
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@bindings/csharp/Expressif.Syntax/SyntaxNodes.cs`:
- Line 118: Update the positional-index parsing in the relevant syntax-node
constructor or binder around the Index assignment to catch overflow from
int.Parse and convert it to ExpressifBindingException, preserving the existing
binding flow so downstream binders can apply their out-of-range policy. Add
boundary tests covering the maximum valid index and an oversized value such as
$2147483648.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 93eb83ab-2ba1-45f5-a11f-ee7b79beee9f
📒 Files selected for processing (9)
README.mdbindings/csharp/Expressif.Syntax.Tests/SyntaxBindingTests.csbindings/csharp/Expressif.Syntax/ExpressifSyntax.csbindings/csharp/Expressif.Syntax/SyntaxNodes.csgrammar.jssrc/grammar.jsonsrc/node-types.jsonsrc/parser.ctest/corpus/references.txt
| : base(SyntaxKind.PositionalElementAccess, span, text) | ||
| { | ||
| FromEnd = text[1] == '^'; | ||
| Index = int.Parse(text.AsSpan(FromEnd ? 2 : 1), System.Globalization.CultureInfo.InvariantCulture); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -F '"positional_element_access"' src/grammar.json
rg -n -F '\\$\\^?(?:0|[1-9][0-9]*)' src/grammar.json
if rg -n 'Index\s*=\s*int\.Parse' \
bindings/csharp/Expressif.Syntax/SyntaxNodes.cs; then
echo "Found an unguarded Int32 parse for positional access."
exit 1
fiRepository: Seddryck/Expressif.Syntax
Length of output: 464
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- grammar ---'
sed -n '425,442p' src/grammar.json
printf '%s\n' '--- README contract ---'
sed -n '65,84p' README.md
printf '%s\n' '--- syntax node context ---'
sed -n '90,130p' bindings/csharp/Expressif.Syntax/SyntaxNodes.cs
printf '%s\n' '--- binding exception and positional index usage ---'
rg -n -C 3 'ExpressifBindingException|PositionalElementAccess|Index\b|FromEnd' \
bindings/csharp src tests 2>/dev/null || true
printf '%s\n' '--- relevant files ---'
git ls-files | rg '(^|/)(README\.md|.*(SyntaxNodes|Binding|Positional|ElementAccess|Test).*)$' | head -200Repository: Seddryck/Expressif.Syntax
Length of output: 11134
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- parser and binding flow ---'
sed -n '1,145p' bindings/csharp/Expressif.Syntax/ExpressifSyntax.cs
printf '%s\n' '--- current positional-access tests ---'
sed -n '60,125p' bindings/csharp/Expressif.Syntax.Tests/SyntaxBindingTests.cs
printf '%s\n' '--- exception assertions and parse API usage ---'
rg -n -C 4 'Assert\.Throws|ExpressifSyntax\.Parse|Errors|SyntaxError|OverflowException|out-of-range|out of range' \
bindings/csharp/Expressif.Syntax.Tests bindings/csharp/Expressif.Syntax README.md
printf '%s\n' '--- source/project metadata ---'
cat bindings/csharp/Expressif.Syntax/Expressif.Syntax.csproj
cat bindings/csharp/Expressif.Syntax.Tests/Expressif.Syntax.Tests.csproj
printf '%s\n' '--- behavioral probe for grammar and Int32 conversion ---'
python3 - <<'PY'
import json
import re
grammar = json.load(open("src/grammar.json", encoding="utf-8"))
pattern = re.compile(grammar["positional_element_access"]["value"])
for text in ("$0", "$^0", "$2147483647", "$2147483648", "$^9223372036854775808"):
match = bool(pattern.fullmatch(text))
try:
value = int(text[2:] if text.startswith("$^") else text[1:])
fits_int32 = -(2**31) <= value <= 2**31 - 1
except ValueError:
fits_int32 = False
print(f"{text}: grammar_match={match}, int32_fit={fits_int32}")
PYRepository: Seddryck/Expressif.Syntax
Length of output: 26252
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- grammar JSON shape and all positional definitions ---'
python3 - <<'PY'
import json
from pathlib import Path
data = json.loads(Path("src/grammar.json").read_text(encoding="utf-8"))
def walk(value, path=()):
if isinstance(value, dict):
if value.get("name") == "positional_element_access" or value.get("value") == r"\$\^?(?:0|[1-9][0-9]*)":
print("path:", ".".join(path) or "<root>")
print(value)
for key, child in value.items():
walk(child, path + (str(key),))
elif isinstance(value, list):
for index, child in enumerate(value):
walk(child, path + (str(index),))
walk(data)
PY
printf '%s\n' '--- grammar.js and generated parser references ---'
rg -n -C 5 'positional_element_access|\$\\\^|[Pp]ositional' grammar.js src/parser.c src 2>/dev/null || true
printf '%s\n' '--- exact Int32 boundary cases represented by the grammar ---'
python3 - <<'PY'
import re
pattern = re.compile(r"\$\^?(?:0|[1-9][0-9]*)")
for source in ("$2147483647", "$2147483648", "$^2147483647", "$^2147483648"):
digits = source[2:] if source.startswith("$^") else source[1:]
value = int(digits)
print(source, "grammar_match=", bool(pattern.fullmatch(source)),
"int32_fit=", 0 <= value <= 2**31 - 1)
PYRepository: Seddryck/Expressif.Syntax
Length of output: 31221
Convert oversized positional indexes to ExpressifBindingException.
The grammar accepts $2147483648, but int.Parse throws OverflowException during syntax binding. This prevents downstream binders from applying their out-of-range policy. Add boundary tests.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@bindings/csharp/Expressif.Syntax/SyntaxNodes.cs` at line 118, Update the
positional-index parsing in the relevant syntax-node constructor or binder
around the Index assignment to catch overflow from int.Parse and convert it to
ExpressifBindingException, preserving the existing binding flow so downstream
binders can apply their out-of-range policy. Add boundary tests covering the
maximum valid index and an oversized value such as $2147483648.
Adds runtime-agnostic positional element access for ordered values through$n and $ ^n, exposes index direction in the C# syntax binding, adds parser and binding coverage for arguments and pipelines, and documents the distinction from record-field access. Validation: reference corpus (12/12); C# tests on .NET 8, 9, and 10 (37/37 each). The full corpus retains four pre-existing Windows line-ending expectation mismatches unrelated to this change. Close #19.
Summary by CodeRabbit
New Features
$0,$1) and reverse ($^0,$^1) indexing.Documentation