Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,20 @@ Expressif distinguishes record fields from elements of ordered values:
```text
.name named field of the current record
.0 positional field of the current record
^.name named field of the original immutable input record
^.0 positional field of the original immutable input record
$0 first element of the current tuple or array
$1 second element of the current tuple or array
$^0 last element of the current tuple or array
$^1 second-to-last element of the current tuple or array
```

Record access always uses `.` for navigation. A leading `^` changes the root
from the current pipeline value to the original immutable input; it does not
change how fields are selected. Access can be chained for nested records, for
example `.customer.address` or `^.customer.0`. The former bracket forms
`[name]` and `[0]` are replaced by `^.name` and `^.0` respectively.

Element positions are zero-based. `$n` counts from the beginning and `$^n`
counts from the end. The parser represents both tuple and array access with the
same `positional_element_access` node; downstream binders decide whether the
Expand Down
37 changes: 32 additions & 5 deletions grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ export default grammar({

value: ($) => choice(
$.variable,
$.property_reference,
$.index_reference,
$.record_access,
$.positional_element_access,
$.numeric_literal,
$.boolean_literal,
Expand Down Expand Up @@ -102,15 +101,43 @@ export default grammar({
$.backtick_quoted_literal,
),

unquoted_record_field_name: (_) => /[A-Za-z]+(?:-[A-Za-z0-9]+)*/,
unquoted_record_field_name: (_) => /[A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)*/,

numeric_literal: (_) => /-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?/,

variable: (_) => /@[A-Za-z][A-Za-z0-9]*/,

property_reference: (_) => /\[[A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)*\]/,
record_access: ($) => seq(
choice(
field("field", $.record_field_selector),
seq(
field("root", $.original_input),
field("field", $.original_record_field_selector),
),
),
repeat(field("field", $.immediate_record_field_selector)),
),
Comment thread
coderabbitai[bot] marked this conversation as resolved.

original_input: (_) => /\^\./,

record_field_selector: ($) => choice(
$.named_record_field,
$.positional_record_field,
),

immediate_record_field_selector: ($) => choice(
alias(token.immediate(/\.[A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)*/), $.named_record_field),
alias(token.immediate(/\.(?:0|[1-9][0-9]*)/), $.positional_record_field),
),

original_record_field_selector: ($) => choice(
alias(token.immediate(prec(-1, /[A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)*/)), $.named_record_field),
alias(token.immediate(prec(-1, /(?:0|[1-9][0-9]*)/)), $.positional_record_field),
),

named_record_field: (_) => /\.[A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)*/,

index_reference: (_) => /\[(?:0|[1-9][0-9]*)\]/,
positional_record_field: (_) => /\.(?:0|[1-9][0-9]*)/,

positional_element_access: (_) => /\$\^?(?:0|[1-9][0-9]*)/,

Expand Down
149 changes: 139 additions & 10 deletions src/grammar.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading