add generics

This commit is contained in:
paul committed 2026-10-23 02:13:30 -04:00
1 parent 79533e9537
commit 2204d58102
22 files changed
+47358 -37579

No files matched your search

+58 -15
View File
@@ -15,6 +15,7 @@ and `value_expression` rules are hidden supertypes.
- `name` for a named declaration;
- `pattern` for a destructuring declaration;
- `binder` for the type parameters of a generic function declaration;
- `type` for an explicit type;
- `value` for an initializer.
@@ -22,6 +23,21 @@ The punctuation distinguishes immutable, mutable, typed, and deferred forms.
Consumers should inspect that punctuation rather than infer the form from the
set of fields alone.
A `binder` holds one `binder_entry` per parameter or bound. Each entry exposes
`type` and, after `:`, an optional `constraint`, which is a constraint name or
an inline `constraint_body`. A `constraint_body` (`<>{ ... }`) also appears as
the whole initializer of a `::` declaration, inside `type_definition`. It
contains `constraint_entry` nodes with `name` and `output` fields and
`constraint_spread` nodes with a `constraint` field.
## Modules
`use_declaration` contains a `module_path` and either an `alias`, an
`import_filter`, or `import_member` nodes. An `import_member` exposes `name`
and either `alias` or an `import_filter`. `import_filter` wraps the `for`
clause and exposes its `type`. `pub_declaration` contains `pub_entry` nodes,
each with a `name` and an optional `import_filter`.
## Expressions
Only expressions that actually contain an operator produce an operator node:
@@ -39,16 +55,27 @@ Precedence-only rules are hidden. For example, `a + b * -c` has one outer and
one inner `binary_expression`, then a `unary_expression`; it does not contain a
wrapper for every precedence level.
Literal leaves are named. Boolean and nil values use `boolean_literal` and
`nil_literal`; numeric, string, character, and unit literals retain their
specific nodes. `default_expression` is also named.
Pipeline stages are postfix. A same-line stage binds to the operand
immediately to its left, tighter than every prefix and infix operator, so
`-x->abs` is a `unary_expression` whose operand is a `pipeline_expression`,
and `a + b->f` is a `binary_expression` whose right operand is one. A
`pipeline_expression` is one flat node: its `input` is followed by every stage
that applies to it, same-line and continuation alike. A leading-operator
continuation applies to the complete ordinary expression on the preceding
line, so in `a + b->f` followed by a continuation `->g` the outer
`pipeline_expression` has the `binary_expression` as its `input`. A negative
literal is never a stage input: `-3->f` negates the pipeline, while a bare `-3`
remains one `signed_numeric_literal`.
`some`, `ok`, and `err` construct optional and result values. They are prefix
operators, so `some value` and `ok {x->f}` appear as `unary_expression` nodes
whose `operator` is the keyword. They bind like `-` and `~`, so `ok x->f`
wraps `x` and then pipes the result into `f`, while `ok {x->f}` wraps the
pipeline. The older `|.some`/`|.ok`/`|.err`
constructors, postfix `value!`, and prefix `!error` are no longer accepted.
Literal leaves are named. Boolean values use `boolean_literal`; numeric,
string, character, and unit literals retain their specific nodes.
`default_expression` is also named.
Optionals and results are ordinary sums. `|.none` is a `sum_constructor`, and
`value->|.some`, `value->|.ok`, and `error->|.err` are pipelines whose stage
callable is a `sum_constructor`. `sum_constructor` exposes an optional `type`
and the `variant`. The former `some`, `ok`, `err`, and `nil` keywords are
ordinary identifiers. Postfix `value!` and prefix `!error` are not accepted.
`function_literal` takes one input and owns the `body` field. A pattern with
one annotation for the whole input, such as `@ value: i32` or
@@ -66,10 +93,10 @@ may also expose `effect` (`->` or `=>`) and `result`.
## Patterns
`wrapper_pattern` matches `some`, `ok`, or `err` applied to one pattern atom.
It exposes `wrapper` (the keyword) and `value` (the inner pattern). `nil` is
still a `nil_literal` pattern. Sum patterns retain `sum_pattern` with a
`variant` field.
`sum_pattern` matches a variant, including `|.none`, `|.some pattern`,
`|.ok pattern`, and `|.err pattern`. It exposes an optional `type`, the
`variant`, and an optional `payload` pattern atom. `bits_pattern` exposes the
optional `type` as well.
## Types
@@ -84,9 +111,13 @@ Meaningful type constructors are named directly:
| `map_type` | `key`, `value` |
| `grouped_type` | `value` |
| `type_application` | `constructor` followed by its type arguments |
| `output_type` | `constructor`, `function`, `output` |
Primitive, unit, tuple, product, sum, and bits types retain their corresponding
named nodes. Internal primary/container/result categories are hidden.
`output_type` is the `Output<f: U>` spelling: a type name applied to a
function name and a type. The grammar does not check that the constructor is
spelled `Output`. Primitive, unit, tuple, product, sum, and bits types retain
their corresponding named nodes. Internal primary/container/result categories
are hidden.
## Trivia and physical lines
@@ -96,6 +127,9 @@ alongside the tree. Leading-operator and pipeline continuations use composite
tokens containing their newline; this prevents a scope separator from stealing
a valid continuation and preserves the language's physical-line rules.
The future-reserved word `context` is a `reserved_word` token that no
production accepts, so it is rejected wherever an identifier is expected.
## Compatibility
Adding nodes or fields is compatible. Removing or renaming a named node or
@@ -103,5 +137,14 @@ field, changing its meaning, or changing which source construct owns it is a
breaking CST change. Until the package reaches 1.0, such changes require corpus
snapshot updates and a version change, and must be called out in release notes.
Version 0.2.0 made these breaking changes:
- `nil_literal` and `wrapper_pattern` are gone, and `some`, `ok`, `err`, and
`nil` are no longer keywords; optionals and results use `sum_constructor`
and `sum_pattern`.
- A same-line pipeline is an operand of prefix and infix operators rather than
taking an operator expression as its `input`.
- `pub_declaration` contains `pub_entry` nodes instead of bare identifiers.
The Tree-sitter tree is designed for source tooling and error recovery; it does
not perform semantic validation.