Skip to content

feat: add generic positional element access - #21

Merged
Seddryck merged 1 commit into
mainfrom
codex/issue-19-positional-access
Aug 12, 2026
Merged

feat: add generic positional element access#21
Seddryck merged 1 commit into
mainfrom
codex/issue-19-positional-access

Conversation

@Seddryck

@Seddryck Seddryck commented Aug 12, 2026

Copy link
Copy Markdown
Owner

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

    • Added positional element access using forward ($0, $1) and reverse ($^0, $^1) indexing.
    • Positional access can now be used as function arguments and pipeline sources.
    • Access expressions expose their zero-based index and direction.
  • Documentation

    • Added guidance on structural access, including named, positional, tuple, and array elements.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The grammar now supports $n and $^n positional access. Generated parser artifacts recognize the new syntax. C# bindings expose its index and direction. Tests cover arguments and pipelines. The README documents structural access semantics.

Changes

Positional element access

Layer / File(s) Summary
Grammar and node contract
grammar.js, src/grammar.json, src/node-types.json
Defines $n and $^n as named positional element access values.
Generated parser support
src/parser.c
Regenerates lexer states, symbols, parser transitions, and parse tables for the new grammar node.
C# syntax binding
bindings/csharp/Expressif.Syntax/SyntaxNodes.cs, bindings/csharp/Expressif.Syntax/ExpressifSyntax.cs
Adds PositionalElementAccessSyntax with Index and FromEnd, and binds parser nodes to it.
Usage validation and documentation
bindings/csharp/Expressif.Syntax.Tests/SyntaxBindingTests.cs, test/corpus/references.txt, README.md
Tests forward and reverse access in values, arguments, and pipelines. Documents structural access syntax.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR implements generic $n and $^n syntax, but the provided changes do not show evaluator coverage for both tuples and arrays as required by issue #19. Add binding and evaluation tests for tuple and array access, including forward and reverse indexing, expression parameters, and pipelines.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the addition of generic positional element access, which is the main change.
Out of Scope Changes check ✅ Passed The grammar, parser, C# binding, tests, and documentation changes are directly related to the positional access requirements in issue #19.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-19-positional-access

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 95e2303 and c5676a0.

📒 Files selected for processing (9)
  • README.md
  • bindings/csharp/Expressif.Syntax.Tests/SyntaxBindingTests.cs
  • bindings/csharp/Expressif.Syntax/ExpressifSyntax.cs
  • bindings/csharp/Expressif.Syntax/SyntaxNodes.cs
  • grammar.js
  • src/grammar.json
  • src/node-types.json
  • src/parser.c
  • test/corpus/references.txt

: base(SyntaxKind.PositionalElementAccess, span, text)
{
FromEnd = text[1] == '^';
Index = int.Parse(text.AsSpan(FromEnd ? 2 : 1), System.Globalization.CultureInfo.InvariantCulture);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 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
fi

Repository: 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 -200

Repository: 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}")
PY

Repository: 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)
PY

Repository: 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.

@Seddryck
Seddryck merged commit 23b186d into main Aug 12, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Review $ positional access semantics for tuples and arrays

1 participant