add generics
This commit is contained in:
1 parent
79533e9537
commit
2204d58102
22 files changed
+47358
-37579
No files matched your search
@@ -10,7 +10,9 @@ The public named-node and field contract is documented in
|
|||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
Tree-sitter 0.27 and Node.js are required.
|
Tree-sitter 0.27 is required. `tree-sitter generate` evaluates `grammar.js`
|
||||||
|
with Node.js by default; without Node.js, pass `--js-runtime native` to use the
|
||||||
|
CLI's bundled QuickJS runtime.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm install
|
npm install
|
||||||
@@ -28,9 +30,8 @@ script: the adjacency-only `=-` and `!=` lexer errors, and recovery after a
|
|||||||
repeated result operator. These need lexical or recovery handling rather than
|
repeated result operator. These need lexical or recovery handling rather than
|
||||||
a looser grammar rule.
|
a looser grammar rule.
|
||||||
|
|
||||||
The future-reserved word `context` is not yet emitted as a Tree-sitter keyword
|
The future-reserved word `context` is a `reserved_word` token with no grammar
|
||||||
because it has no grammar production. It should move into lexical handling with
|
production, so it is rejected wherever an identifier is expected.
|
||||||
the two adjacency checks above.
|
|
||||||
|
|
||||||
Generated parser sources under `src/` are committed so consumers do not need
|
Generated parser sources under `src/` are committed so consumers do not need
|
||||||
Node.js or the Tree-sitter CLI.
|
Node.js or the Tree-sitter CLI.
|
||||||
+270
-13
@@ -196,10 +196,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn exposes_wrappers_and_untyped_inputs() {
|
fn exposes_sum_spelled_optionals_and_untyped_inputs() {
|
||||||
let source = "present: i32?: some 1\n\
|
let source = "present: i32?: 1->|.some\n\
|
||||||
double :: @ value { value * 2 }\n\
|
double :: @ value { value * 2 }\n\
|
||||||
unwrap :: @ result { match result { ok inner => inner; err _ => 0 } }\n";
|
unwrap :: @ result { match result { |.ok inner => inner; |.err _ => 0 } }\n";
|
||||||
let tree = parse(source);
|
let tree = parse(source);
|
||||||
assert!(
|
assert!(
|
||||||
!tree.root_node().has_error(),
|
!tree.root_node().has_error(),
|
||||||
@@ -209,10 +209,22 @@ mod tests {
|
|||||||
|
|
||||||
let present = tree.root_node().named_child(0).unwrap();
|
let present = tree.root_node().named_child(0).unwrap();
|
||||||
let wrapped = present.child_by_field_name("value").unwrap();
|
let wrapped = present.child_by_field_name("value").unwrap();
|
||||||
assert_eq!(wrapped.kind(), "unary_expression");
|
assert_eq!(wrapped.kind(), "pipeline_expression");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
wrapped
|
wrapped.child_by_field_name("input").unwrap().kind(),
|
||||||
.child_by_field_name("operator")
|
"signed_numeric_literal"
|
||||||
|
);
|
||||||
|
let stage = wrapped.named_child(1).unwrap();
|
||||||
|
assert_eq!(stage.kind(), "direct_pipeline_stage");
|
||||||
|
let constructor = stage
|
||||||
|
.child_by_field_name("callable")
|
||||||
|
.unwrap()
|
||||||
|
.named_child(0)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(constructor.kind(), "sum_constructor");
|
||||||
|
assert_eq!(
|
||||||
|
constructor
|
||||||
|
.child_by_field_name("variant")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.utf8_text(source.as_bytes())
|
.utf8_text(source.as_bytes())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@@ -233,25 +245,270 @@ mod tests {
|
|||||||
let body = function.child_by_field_name("body").unwrap();
|
let body = function.child_by_field_name("body").unwrap();
|
||||||
let arm = body.named_child(0).unwrap().named_child(1).unwrap();
|
let arm = body.named_child(0).unwrap().named_child(1).unwrap();
|
||||||
let pattern = arm.child_by_field_name("pattern").unwrap();
|
let pattern = arm.child_by_field_name("pattern").unwrap();
|
||||||
let wrapper = pattern.named_child(0).unwrap();
|
let variant = pattern.named_child(0).unwrap();
|
||||||
assert_eq!(wrapper.kind(), "wrapper_pattern");
|
assert_eq!(variant.kind(), "sum_pattern");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
wrapper
|
variant
|
||||||
.child_by_field_name("wrapper")
|
.child_by_field_name("variant")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.utf8_text(source.as_bytes())
|
.utf8_text(source.as_bytes())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
"ok"
|
"ok"
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
variant.child_by_field_name("payload").unwrap().kind(),
|
||||||
|
"identifier"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rejects_removed_wrapper_forms() {
|
fn binds_same_line_stages_tighter_than_operators() {
|
||||||
|
let source = "mixed :: -3->add_ten + 2 * 3->double - {1 + 1}->double\n";
|
||||||
|
let tree = parse(source);
|
||||||
|
assert!(
|
||||||
|
!tree.root_node().has_error(),
|
||||||
|
"{}",
|
||||||
|
tree.root_node().to_sexp()
|
||||||
|
);
|
||||||
|
|
||||||
|
let declaration = tree.root_node().named_child(0).unwrap();
|
||||||
|
let subtraction = declaration.child_by_field_name("value").unwrap();
|
||||||
|
assert_eq!(subtraction.kind(), "binary_expression");
|
||||||
|
assert_eq!(
|
||||||
|
subtraction
|
||||||
|
.child_by_field_name("operator")
|
||||||
|
.unwrap()
|
||||||
|
.utf8_text(source.as_bytes())
|
||||||
|
.unwrap(),
|
||||||
|
"-"
|
||||||
|
);
|
||||||
|
|
||||||
|
let addition = subtraction.child_by_field_name("left").unwrap();
|
||||||
|
assert_eq!(addition.kind(), "binary_expression");
|
||||||
|
let negation = addition.child_by_field_name("left").unwrap();
|
||||||
|
assert_eq!(negation.kind(), "unary_expression");
|
||||||
|
let negated = negation.child_by_field_name("operand").unwrap();
|
||||||
|
assert_eq!(negated.kind(), "pipeline_expression");
|
||||||
|
assert_eq!(
|
||||||
|
negated
|
||||||
|
.child_by_field_name("input")
|
||||||
|
.unwrap()
|
||||||
|
.utf8_text(source.as_bytes())
|
||||||
|
.unwrap(),
|
||||||
|
"3"
|
||||||
|
);
|
||||||
|
|
||||||
|
let product = addition.child_by_field_name("right").unwrap();
|
||||||
|
assert_eq!(product.kind(), "binary_expression");
|
||||||
|
assert_eq!(
|
||||||
|
product.child_by_field_name("right").unwrap().kind(),
|
||||||
|
"pipeline_expression"
|
||||||
|
);
|
||||||
|
|
||||||
|
let grouped = subtraction.child_by_field_name("right").unwrap();
|
||||||
|
assert_eq!(grouped.kind(), "pipeline_expression");
|
||||||
|
assert_eq!(
|
||||||
|
grouped.child_by_field_name("input").unwrap().kind(),
|
||||||
|
"block"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn applies_continuation_stages_to_the_whole_preceding_expression() {
|
||||||
|
let source = "flat := value->first\n->second\nwhole := a + b->f\n->g\n";
|
||||||
|
let tree = parse(source);
|
||||||
|
assert!(
|
||||||
|
!tree.root_node().has_error(),
|
||||||
|
"{}",
|
||||||
|
tree.root_node().to_sexp()
|
||||||
|
);
|
||||||
|
|
||||||
|
let flat = tree
|
||||||
|
.root_node()
|
||||||
|
.named_child(0)
|
||||||
|
.unwrap()
|
||||||
|
.child_by_field_name("value")
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(flat.kind(), "pipeline_expression");
|
||||||
|
assert_eq!(
|
||||||
|
flat.child_by_field_name("input").unwrap().kind(),
|
||||||
|
"identifier"
|
||||||
|
);
|
||||||
|
assert_eq!(flat.named_child(1).unwrap().kind(), "direct_pipeline_stage");
|
||||||
|
assert_eq!(
|
||||||
|
flat.named_child(2).unwrap().kind(),
|
||||||
|
"continuation_pipeline_stage"
|
||||||
|
);
|
||||||
|
assert_eq!(flat.named_child_count(), 3);
|
||||||
|
|
||||||
|
let whole = tree
|
||||||
|
.root_node()
|
||||||
|
.named_child(1)
|
||||||
|
.unwrap()
|
||||||
|
.child_by_field_name("value")
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(whole.kind(), "pipeline_expression");
|
||||||
|
let head = whole.child_by_field_name("input").unwrap();
|
||||||
|
assert_eq!(head.kind(), "binary_expression");
|
||||||
|
assert_eq!(
|
||||||
|
head.child_by_field_name("right").unwrap().kind(),
|
||||||
|
"pipeline_expression"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
whole.named_child(1).unwrap().kind(),
|
||||||
|
"continuation_pipeline_stage"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn exposes_generic_binders_constraints_and_output_types() {
|
||||||
|
let source = "Show :: <>{ to_str: str; ...Display }\n\
|
||||||
|
pick: <T: Show> (T, T) -> T: @ (first, second): (T, T) { first }\n\
|
||||||
|
Card :: &{ label: Output<make_label: Show>: }\n";
|
||||||
|
let tree = parse(source);
|
||||||
|
assert!(
|
||||||
|
!tree.root_node().has_error(),
|
||||||
|
"{}",
|
||||||
|
tree.root_node().to_sexp()
|
||||||
|
);
|
||||||
|
|
||||||
|
let show = tree.root_node().named_child(0).unwrap();
|
||||||
|
let definition = show.child_by_field_name("value").unwrap();
|
||||||
|
assert_eq!(definition.kind(), "type_definition");
|
||||||
|
let constraint = definition.named_child(0).unwrap();
|
||||||
|
assert_eq!(constraint.kind(), "constraint_body");
|
||||||
|
let entry = constraint.named_child(0).unwrap();
|
||||||
|
assert_eq!(entry.kind(), "constraint_entry");
|
||||||
|
assert_eq!(
|
||||||
|
entry
|
||||||
|
.child_by_field_name("name")
|
||||||
|
.unwrap()
|
||||||
|
.utf8_text(source.as_bytes())
|
||||||
|
.unwrap(),
|
||||||
|
"to_str"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
entry.child_by_field_name("output").unwrap().kind(),
|
||||||
|
"primitive_type"
|
||||||
|
);
|
||||||
|
let spread = constraint.named_child(1).unwrap();
|
||||||
|
assert_eq!(spread.kind(), "constraint_spread");
|
||||||
|
assert_eq!(
|
||||||
|
spread
|
||||||
|
.child_by_field_name("constraint")
|
||||||
|
.unwrap()
|
||||||
|
.utf8_text(source.as_bytes())
|
||||||
|
.unwrap(),
|
||||||
|
"Display"
|
||||||
|
);
|
||||||
|
|
||||||
|
let pick = tree.root_node().named_child(1).unwrap();
|
||||||
|
let binder = pick.child_by_field_name("binder").unwrap();
|
||||||
|
assert_eq!(binder.kind(), "binder");
|
||||||
|
let parameter = binder.named_child(0).unwrap();
|
||||||
|
assert_eq!(parameter.kind(), "binder_entry");
|
||||||
|
assert_eq!(
|
||||||
|
parameter
|
||||||
|
.child_by_field_name("type")
|
||||||
|
.unwrap()
|
||||||
|
.utf8_text(source.as_bytes())
|
||||||
|
.unwrap(),
|
||||||
|
"T"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parameter
|
||||||
|
.child_by_field_name("constraint")
|
||||||
|
.unwrap()
|
||||||
|
.utf8_text(source.as_bytes())
|
||||||
|
.unwrap(),
|
||||||
|
"Show"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
pick.child_by_field_name("type").unwrap().kind(),
|
||||||
|
"function_type"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
pick.child_by_field_name("value").unwrap().kind(),
|
||||||
|
"function_literal"
|
||||||
|
);
|
||||||
|
|
||||||
|
let card = tree.root_node().named_child(2).unwrap();
|
||||||
|
let field = card
|
||||||
|
.child_by_field_name("value")
|
||||||
|
.unwrap()
|
||||||
|
.named_child(0)
|
||||||
|
.unwrap()
|
||||||
|
.named_child(0)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(field.kind(), "product_field");
|
||||||
|
let output = field.child_by_field_name("type").unwrap();
|
||||||
|
assert_eq!(output.kind(), "output_type");
|
||||||
|
assert_eq!(
|
||||||
|
output
|
||||||
|
.child_by_field_name("function")
|
||||||
|
.unwrap()
|
||||||
|
.utf8_text(source.as_bytes())
|
||||||
|
.unwrap(),
|
||||||
|
"make_label"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
output
|
||||||
|
.child_by_field_name("output")
|
||||||
|
.unwrap()
|
||||||
|
.utf8_text(source.as_bytes())
|
||||||
|
.unwrap(),
|
||||||
|
"Show"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn exposes_import_filters() {
|
||||||
|
let source = "use math.{sqrt for f64, pi}\nuse .shapes.area for Circle\npub { area for Circle; sqrt }\n";
|
||||||
|
let tree = parse(source);
|
||||||
|
assert!(
|
||||||
|
!tree.root_node().has_error(),
|
||||||
|
"{}",
|
||||||
|
tree.root_node().to_sexp()
|
||||||
|
);
|
||||||
|
|
||||||
|
let group = tree.root_node().named_child(0).unwrap();
|
||||||
|
assert_eq!(group.kind(), "use_declaration");
|
||||||
|
let member = group.named_child(1).unwrap();
|
||||||
|
assert_eq!(member.kind(), "import_member");
|
||||||
|
let filter = member.named_child(1).unwrap();
|
||||||
|
assert_eq!(filter.kind(), "import_filter");
|
||||||
|
assert_eq!(
|
||||||
|
filter.child_by_field_name("type").unwrap().kind(),
|
||||||
|
"primitive_type"
|
||||||
|
);
|
||||||
|
assert_eq!(group.named_child(2).unwrap().named_child_count(), 1);
|
||||||
|
|
||||||
|
let single = tree.root_node().named_child(1).unwrap();
|
||||||
|
assert_eq!(single.named_child(1).unwrap().kind(), "import_filter");
|
||||||
|
|
||||||
|
let publication = tree.root_node().named_child(2).unwrap();
|
||||||
|
assert_eq!(publication.kind(), "pub_declaration");
|
||||||
|
let filtered = publication.named_child(0).unwrap();
|
||||||
|
assert_eq!(filtered.kind(), "pub_entry");
|
||||||
|
assert_eq!(
|
||||||
|
filtered
|
||||||
|
.child_by_field_name("name")
|
||||||
|
.unwrap()
|
||||||
|
.utf8_text(source.as_bytes())
|
||||||
|
.unwrap(),
|
||||||
|
"area"
|
||||||
|
);
|
||||||
|
assert_eq!(filtered.named_child(1).unwrap().kind(), "import_filter");
|
||||||
|
assert_eq!(publication.named_child(1).unwrap().named_child_count(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rejects_removed_wrapper_forms_and_reserved_words() {
|
||||||
for source in [
|
for source in [
|
||||||
"old: i32?: 1->|.some\n",
|
"present: i32?: some 1\n",
|
||||||
"old :: @ value: i32 -> i32 ! str { value! }\n",
|
"old :: @ value: i32 -> i32 ! str { value! }\n",
|
||||||
"old :: @ value: str -> i32 ! str { !value }\n",
|
"old :: @ value: str -> i32 ! str { !value }\n",
|
||||||
"some := 1\n",
|
"context := 1\n",
|
||||||
] {
|
] {
|
||||||
assert!(parse(source).root_node().has_error(), "accepted {source}");
|
assert!(parse(source).root_node().has_error(), "accepted {source}");
|
||||||
}
|
}
|
||||||
|
|||||||
+58
-15
@@ -15,6 +15,7 @@ and `value_expression` rules are hidden supertypes.
|
|||||||
|
|
||||||
- `name` for a named declaration;
|
- `name` for a named declaration;
|
||||||
- `pattern` for a destructuring declaration;
|
- `pattern` for a destructuring declaration;
|
||||||
|
- `binder` for the type parameters of a generic function declaration;
|
||||||
- `type` for an explicit type;
|
- `type` for an explicit type;
|
||||||
- `value` for an initializer.
|
- `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
|
Consumers should inspect that punctuation rather than infer the form from the
|
||||||
set of fields alone.
|
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
|
## Expressions
|
||||||
|
|
||||||
Only expressions that actually contain an operator produce an operator node:
|
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
|
one inner `binary_expression`, then a `unary_expression`; it does not contain a
|
||||||
wrapper for every precedence level.
|
wrapper for every precedence level.
|
||||||
|
|
||||||
Literal leaves are named. Boolean and nil values use `boolean_literal` and
|
Pipeline stages are postfix. A same-line stage binds to the operand
|
||||||
`nil_literal`; numeric, string, character, and unit literals retain their
|
immediately to its left, tighter than every prefix and infix operator, so
|
||||||
specific nodes. `default_expression` is also named.
|
`-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
|
Literal leaves are named. Boolean values use `boolean_literal`; numeric,
|
||||||
operators, so `some value` and `ok {x->f}` appear as `unary_expression` nodes
|
string, character, and unit literals retain their specific nodes.
|
||||||
whose `operator` is the keyword. They bind like `-` and `~`, so `ok x->f`
|
`default_expression` is also named.
|
||||||
wraps `x` and then pipes the result into `f`, while `ok {x->f}` wraps the
|
|
||||||
pipeline. The older `|.some`/`|.ok`/`|.err`
|
Optionals and results are ordinary sums. `|.none` is a `sum_constructor`, and
|
||||||
constructors, postfix `value!`, and prefix `!error` are no longer accepted.
|
`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
|
`function_literal` takes one input and owns the `body` field. A pattern with
|
||||||
one annotation for the whole input, such as `@ value: i32` or
|
one annotation for the whole input, such as `@ value: i32` or
|
||||||
@@ -66,10 +93,10 @@ may also expose `effect` (`->` or `=>`) and `result`.
|
|||||||
|
|
||||||
## Patterns
|
## Patterns
|
||||||
|
|
||||||
`wrapper_pattern` matches `some`, `ok`, or `err` applied to one pattern atom.
|
`sum_pattern` matches a variant, including `|.none`, `|.some pattern`,
|
||||||
It exposes `wrapper` (the keyword) and `value` (the inner pattern). `nil` is
|
`|.ok pattern`, and `|.err pattern`. It exposes an optional `type`, the
|
||||||
still a `nil_literal` pattern. Sum patterns retain `sum_pattern` with a
|
`variant`, and an optional `payload` pattern atom. `bits_pattern` exposes the
|
||||||
`variant` field.
|
optional `type` as well.
|
||||||
|
|
||||||
## Types
|
## Types
|
||||||
|
|
||||||
@@ -84,9 +111,13 @@ Meaningful type constructors are named directly:
|
|||||||
| `map_type` | `key`, `value` |
|
| `map_type` | `key`, `value` |
|
||||||
| `grouped_type` | `value` |
|
| `grouped_type` | `value` |
|
||||||
| `type_application` | `constructor` followed by its type arguments |
|
| `type_application` | `constructor` followed by its type arguments |
|
||||||
|
| `output_type` | `constructor`, `function`, `output` |
|
||||||
|
|
||||||
Primitive, unit, tuple, product, sum, and bits types retain their corresponding
|
`output_type` is the `Output<f: U>` spelling: a type name applied to a
|
||||||
named nodes. Internal primary/container/result categories are hidden.
|
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
|
## 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
|
tokens containing their newline; this prevents a scope separator from stealing
|
||||||
a valid continuation and preserves the language's physical-line rules.
|
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
|
## Compatibility
|
||||||
|
|
||||||
Adding nodes or fields is compatible. Removing or renaming a named node or
|
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
|
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.
|
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
|
The Tree-sitter tree is designed for source tooling and error recovery; it does
|
||||||
not perform semantic validation.
|
not perform semantic validation.
|
||||||
+150
-28
@@ -17,10 +17,12 @@ const PREC = {
|
|||||||
POSTFIX: 13,
|
POSTFIX: 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Hard keywords and the primitive type names; `reserved_word` adds the
|
||||||
|
// future-reserved `context`.
|
||||||
const RESERVED_WORDS = [
|
const RESERVED_WORDS = [
|
||||||
"and", "as", "bits", "break", "continue", "default", "distinct", "else",
|
"and", "as", "bits", "break", "continue", "default", "distinct",
|
||||||
"err", "false", "for", "if", "in", "loop", "match", "nil", "not", "ok", "or",
|
"else", "false", "for", "if", "in", "loop", "match", "not", "or", "pub",
|
||||||
"pub", "return", "some", "true", "use",
|
"return", "true", "use",
|
||||||
"bit", "chr", "f32", "f64", "i8", "i16", "i32", "i64", "nvr", "str",
|
"bit", "chr", "f32", "f64", "i8", "i16", "i32", "i64", "nvr", "str",
|
||||||
"u8", "u16", "u32", "u64",
|
"u8", "u16", "u32", "u64",
|
||||||
];
|
];
|
||||||
@@ -37,7 +39,7 @@ module.exports = grammar({
|
|||||||
extras: $ => [/[ \t]/, $.comment],
|
extras: $ => [/[ \t]/, $.comment],
|
||||||
word: $ => $.identifier,
|
word: $ => $.identifier,
|
||||||
reserved: {
|
reserved: {
|
||||||
global: _ => RESERVED_WORDS,
|
global: $ => [...RESERVED_WORDS, $.reserved_word],
|
||||||
},
|
},
|
||||||
|
|
||||||
supertypes: $ => [
|
supertypes: $ => [
|
||||||
@@ -67,6 +69,7 @@ module.exports = grammar({
|
|||||||
[$.product_constructor, $._scope_separator],
|
[$.product_constructor, $._scope_separator],
|
||||||
[$.tuple_type],
|
[$.tuple_type],
|
||||||
[$.type_application],
|
[$.type_application],
|
||||||
|
[$.binder],
|
||||||
[$.tuple_pattern],
|
[$.tuple_pattern],
|
||||||
[$.product_pattern],
|
[$.product_pattern],
|
||||||
[$.array_pattern],
|
[$.array_pattern],
|
||||||
@@ -87,6 +90,7 @@ module.exports = grammar({
|
|||||||
[$.pattern_atom, $.primary_expression, $.type_name],
|
[$.pattern_atom, $.primary_expression, $.type_name],
|
||||||
[$.type_name, $.qualified_name],
|
[$.type_name, $.qualified_name],
|
||||||
[$.primary_expression, $.type_name],
|
[$.primary_expression, $.type_name],
|
||||||
|
[$._pipeline_input_primary, $.type_name],
|
||||||
[$.type_expression, $.function_type],
|
[$.type_expression, $.function_type],
|
||||||
[$.array_type, $.collection_literal],
|
[$.array_type, $.collection_literal],
|
||||||
],
|
],
|
||||||
@@ -110,22 +114,29 @@ module.exports = grammar({
|
|||||||
use_declaration: $ => seq(
|
use_declaration: $ => seq(
|
||||||
"use",
|
"use",
|
||||||
choice(
|
choice(
|
||||||
seq($.module_path, optional(seq("as", field("alias", $.identifier)))),
|
seq(
|
||||||
|
$.module_path,
|
||||||
|
optional(choice(seq("as", field("alias", $.identifier)), $.import_filter)),
|
||||||
|
),
|
||||||
seq($.module_path, ".", "{", listBody($, $.import_member), "}"),
|
seq($.module_path, ".", "{", listBody($, $.import_member), "}"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
import_member: $ => seq(
|
import_member: $ => seq(
|
||||||
field("name", $.identifier),
|
field("name", $.identifier),
|
||||||
optional(seq("as", field("alias", $.identifier))),
|
optional(choice(seq("as", field("alias", $.identifier)), $.import_filter)),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
import_filter: $ => seq("for", field("type", $.type_expression)),
|
||||||
|
|
||||||
module_path: $ => choice(
|
module_path: $ => choice(
|
||||||
$.type_name,
|
$.type_name,
|
||||||
seq(choice(".", ".."), $.type_name),
|
seq(choice(".", ".."), $.type_name),
|
||||||
),
|
),
|
||||||
|
|
||||||
pub_declaration: $ => seq("pub", "{", scopeBody($, $.identifier), "}"),
|
pub_declaration: $ => seq("pub", "{", scopeBody($, $.pub_entry), "}"),
|
||||||
|
|
||||||
|
pub_entry: $ => seq(field("name", $.identifier), optional($.import_filter)),
|
||||||
|
|
||||||
expression: $ => choice(
|
expression: $ => choice(
|
||||||
$.declaration,
|
$.declaration,
|
||||||
@@ -161,6 +172,14 @@ module.exports = grammar({
|
|||||||
optional(seq("=", field("value", $.value_expression))),
|
optional(seq("=", field("value", $.value_expression))),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
seq(
|
||||||
|
field("name", $.identifier),
|
||||||
|
":",
|
||||||
|
field("binder", $.binder),
|
||||||
|
field("type", $.type_expression),
|
||||||
|
":",
|
||||||
|
field("value", $.value_expression),
|
||||||
|
),
|
||||||
seq(
|
seq(
|
||||||
field("pattern", choice($.tuple_pattern, $.product_pattern)),
|
field("pattern", choice($.tuple_pattern, $.product_pattern)),
|
||||||
choice("::", ":="),
|
choice("::", ":="),
|
||||||
@@ -168,7 +187,33 @@ module.exports = grammar({
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
type_definition: $ => seq(optional("distinct"), $.type_expression),
|
binder: $ => seq("<", listBodyOneOrMore($, $.binder_entry), ">"),
|
||||||
|
|
||||||
|
binder_entry: $ => seq(
|
||||||
|
field("type", $.type_expression),
|
||||||
|
optional(seq(":", field("constraint", choice($.type_name, $.constraint_body)))),
|
||||||
|
),
|
||||||
|
|
||||||
|
type_definition: $ => choice(
|
||||||
|
seq(optional("distinct"), $.type_expression),
|
||||||
|
$.constraint_body,
|
||||||
|
),
|
||||||
|
|
||||||
|
constraint_body: $ => seq(
|
||||||
|
"<",
|
||||||
|
">",
|
||||||
|
"{",
|
||||||
|
scopeBody($, choice($.constraint_entry, $.constraint_spread)),
|
||||||
|
"}",
|
||||||
|
),
|
||||||
|
|
||||||
|
constraint_entry: $ => seq(
|
||||||
|
field("name", $.identifier),
|
||||||
|
":",
|
||||||
|
field("output", $.type_expression),
|
||||||
|
),
|
||||||
|
|
||||||
|
constraint_spread: $ => seq("...", field("constraint", $.type_name)),
|
||||||
|
|
||||||
type_expression: $ => choice(
|
type_expression: $ => choice(
|
||||||
$.function_type,
|
$.function_type,
|
||||||
@@ -226,6 +271,7 @@ module.exports = grammar({
|
|||||||
$.sum_type,
|
$.sum_type,
|
||||||
$.bits_type,
|
$.bits_type,
|
||||||
$.type_application,
|
$.type_application,
|
||||||
|
$.output_type,
|
||||||
$.grouped_type,
|
$.grouped_type,
|
||||||
),
|
),
|
||||||
|
|
||||||
@@ -246,6 +292,15 @@ module.exports = grammar({
|
|||||||
">",
|
">",
|
||||||
),
|
),
|
||||||
|
|
||||||
|
output_type: $ => seq(
|
||||||
|
field("constructor", $.type_name),
|
||||||
|
"<",
|
||||||
|
field("function", $.type_name),
|
||||||
|
":",
|
||||||
|
field("output", $.type_expression),
|
||||||
|
">",
|
||||||
|
),
|
||||||
|
|
||||||
product_type: $ => seq("&", "{", scopeBody($, $.product_field), "}"),
|
product_type: $ => seq("&", "{", scopeBody($, $.product_field), "}"),
|
||||||
|
|
||||||
product_field: $ => seq(
|
product_field: $ => seq(
|
||||||
@@ -383,8 +438,6 @@ module.exports = grammar({
|
|||||||
$.string_literal,
|
$.string_literal,
|
||||||
$.character_literal,
|
$.character_literal,
|
||||||
$.boolean_literal,
|
$.boolean_literal,
|
||||||
$.nil_literal,
|
|
||||||
$.wrapper_pattern,
|
|
||||||
$.sum_pattern,
|
$.sum_pattern,
|
||||||
$.bits_pattern,
|
$.bits_pattern,
|
||||||
$.unit_pattern,
|
$.unit_pattern,
|
||||||
@@ -401,20 +454,15 @@ module.exports = grammar({
|
|||||||
|
|
||||||
sum_pattern: $ => seq(
|
sum_pattern: $ => seq(
|
||||||
"|",
|
"|",
|
||||||
optional($.type_name),
|
optional(field("type", $.type_name)),
|
||||||
".",
|
".",
|
||||||
field("variant", $.identifier),
|
field("variant", $.identifier),
|
||||||
optional($.pattern_atom),
|
optional(field("payload", $.pattern_atom)),
|
||||||
),
|
|
||||||
|
|
||||||
wrapper_pattern: $ => seq(
|
|
||||||
field("wrapper", choice("some", "ok", "err")),
|
|
||||||
field("value", $.pattern_atom),
|
|
||||||
),
|
),
|
||||||
|
|
||||||
bits_pattern: $ => seq(
|
bits_pattern: $ => seq(
|
||||||
"|",
|
"|",
|
||||||
optional($.type_name),
|
optional(field("type", $.type_name)),
|
||||||
".",
|
".",
|
||||||
"{",
|
"{",
|
||||||
listBody($, $.identifier),
|
listBody($, $.identifier),
|
||||||
@@ -424,11 +472,58 @@ module.exports = grammar({
|
|||||||
array_pattern: $ => seq("[", listBody($, $.array_pattern_entry), "]"),
|
array_pattern: $ => seq("[", listBody($, $.array_pattern_entry), "]"),
|
||||||
array_pattern_entry: $ => choice($.pattern, seq("...", choice($.identifier, "_"))),
|
array_pattern_entry: $ => choice($.pattern, seq("...", choice($.identifier, "_"))),
|
||||||
|
|
||||||
pipeline_expression: $ => prec.dynamic(1, prec.left(choice(
|
// A pipeline headed by a leading-operator continuation applies to the
|
||||||
seq(field("input", choice($._prefix_expression, $.function_literal)), $.inline_pipeline_stage, repeat($.pipeline_stage)),
|
// complete ordinary expression on the preceding line. Its input excludes
|
||||||
seq(field("input", choice($._non_assignment_expression, $.function_literal)), $.continuation_pipeline_stage, repeat($.pipeline_stage)),
|
// a bare same-line pipeline, which instead absorbs the continuation
|
||||||
|
// stages itself, so every pipeline is one flat node.
|
||||||
|
pipeline_expression: $ => prec.dynamic(1, prec.left(seq(
|
||||||
|
field("input", $._pipeline_head),
|
||||||
|
$.continuation_pipeline_stage,
|
||||||
|
repeat($.pipeline_stage),
|
||||||
))),
|
))),
|
||||||
|
|
||||||
|
_pipeline_head: $ => choice(
|
||||||
|
$.range_expression,
|
||||||
|
$.binary_expression,
|
||||||
|
$.unary_expression,
|
||||||
|
$.postfix_expression,
|
||||||
|
$.primary_expression,
|
||||||
|
),
|
||||||
|
|
||||||
|
// Same-line stages are postfix: they bind to the operand immediately to
|
||||||
|
// their left, tighter than every prefix and infix operator. The static
|
||||||
|
// precedence makes a stage sequence inside an operator expression close
|
||||||
|
// before a continuation stage, which then applies to the whole
|
||||||
|
// expression. The dynamic precedence reads a category-ambiguous
|
||||||
|
// `name :: a -> b` as a pipeline rather than a function type.
|
||||||
|
_inline_pipeline_expression: $ => prec.dynamic(1, prec.left(1, seq(
|
||||||
|
field("input", choice(
|
||||||
|
$.postfix_expression,
|
||||||
|
$._pipeline_input_primary,
|
||||||
|
$.function_literal,
|
||||||
|
)),
|
||||||
|
$.inline_pipeline_stage,
|
||||||
|
repeat($.pipeline_stage),
|
||||||
|
))),
|
||||||
|
|
||||||
|
// `-3->f` negates the pipeline, so a stage input is never a negative
|
||||||
|
// literal; a bare `-3` remains one `signed_numeric_literal`.
|
||||||
|
_pipeline_input_primary: $ => choice(
|
||||||
|
$._unsigned_literal,
|
||||||
|
$.identifier,
|
||||||
|
$.block,
|
||||||
|
$.if_expression,
|
||||||
|
$.match_expression,
|
||||||
|
$.loop_expression,
|
||||||
|
$.for_expression,
|
||||||
|
$.tuple_value,
|
||||||
|
$.collection_literal,
|
||||||
|
$.product_constructor,
|
||||||
|
$.sum_constructor,
|
||||||
|
$.bits_constructor,
|
||||||
|
$.default_expression,
|
||||||
|
),
|
||||||
|
|
||||||
pipeline_stage: $ => choice($.inline_pipeline_stage, $.continuation_pipeline_stage),
|
pipeline_stage: $ => choice($.inline_pipeline_stage, $.continuation_pipeline_stage),
|
||||||
inline_pipeline_stage: $ => choice($.direct_pipeline_stage, $.aggregate_pipeline_stage),
|
inline_pipeline_stage: $ => choice($.direct_pipeline_stage, $.aggregate_pipeline_stage),
|
||||||
continuation_pipeline_stage: $ => choice(
|
continuation_pipeline_stage: $ => choice(
|
||||||
@@ -495,6 +590,7 @@ module.exports = grammar({
|
|||||||
|
|
||||||
_prefix_expression: $ => choice(
|
_prefix_expression: $ => choice(
|
||||||
$.unary_expression,
|
$.unary_expression,
|
||||||
|
alias($._inline_pipeline_expression, $.pipeline_expression),
|
||||||
$.postfix_expression,
|
$.postfix_expression,
|
||||||
$.primary_expression,
|
$.primary_expression,
|
||||||
),
|
),
|
||||||
@@ -529,7 +625,7 @@ module.exports = grammar({
|
|||||||
),
|
),
|
||||||
|
|
||||||
unary_expression: $ => prec.right(PREC.PREFIX, seq(
|
unary_expression: $ => prec.right(PREC.PREFIX, seq(
|
||||||
field("operator", choice("not", "-", "~", "some", "ok", "err")),
|
field("operator", choice("not", "-", "~")),
|
||||||
field("operand", $._prefix_expression),
|
field("operand", $._prefix_expression),
|
||||||
)),
|
)),
|
||||||
|
|
||||||
@@ -580,27 +676,49 @@ module.exports = grammar({
|
|||||||
seq("...", $.expression),
|
seq("...", $.expression),
|
||||||
),
|
),
|
||||||
|
|
||||||
sum_constructor: $ => seq("|", optional($.type_name), ".", $.identifier),
|
sum_constructor: $ => seq(
|
||||||
bits_constructor: $ => seq("|", optional($.type_name), ".", "{", listBody($, $.identifier), "}"),
|
"|",
|
||||||
|
optional(field("type", $.type_name)),
|
||||||
|
".",
|
||||||
|
field("variant", $.identifier),
|
||||||
|
),
|
||||||
|
bits_constructor: $ => seq(
|
||||||
|
"|",
|
||||||
|
optional(field("type", $.type_name)),
|
||||||
|
".",
|
||||||
|
"{",
|
||||||
|
listBody($, $.identifier),
|
||||||
|
"}",
|
||||||
|
),
|
||||||
|
|
||||||
literal: $ => choice(
|
literal: $ => choice(
|
||||||
$.signed_numeric_literal,
|
$.signed_numeric_literal,
|
||||||
$.string_literal,
|
$.string_literal,
|
||||||
$.character_literal,
|
$.character_literal,
|
||||||
$.boolean_literal,
|
$.boolean_literal,
|
||||||
$.nil_literal,
|
$.unit_literal,
|
||||||
|
),
|
||||||
|
|
||||||
|
_unsigned_literal: $ => choice(
|
||||||
|
alias($._unsigned_numeric_literal, $.signed_numeric_literal),
|
||||||
|
$.string_literal,
|
||||||
|
$.character_literal,
|
||||||
|
$.boolean_literal,
|
||||||
$.unit_literal,
|
$.unit_literal,
|
||||||
),
|
),
|
||||||
|
|
||||||
boolean_literal: _ => choice("true", "false"),
|
boolean_literal: _ => choice("true", "false"),
|
||||||
nil_literal: _ => "nil",
|
|
||||||
default_expression: _ => "default",
|
default_expression: _ => "default",
|
||||||
unit_literal: _ => seq("(", ")"),
|
unit_literal: _ => seq("(", ")"),
|
||||||
signed_numeric_literal: $ => seq(optional("-"), choice(
|
signed_numeric_literal: $ => choice(
|
||||||
|
prec.dynamic(1, seq("-", $._unsigned_numeric_literal)),
|
||||||
|
$._unsigned_numeric_literal,
|
||||||
|
),
|
||||||
|
_unsigned_numeric_literal: $ => choice(
|
||||||
$.integer_literal,
|
$.integer_literal,
|
||||||
$.float_literal,
|
$.float_literal,
|
||||||
alias($._trailing_dot_float, $.float_literal),
|
alias($._trailing_dot_float, $.float_literal),
|
||||||
)),
|
),
|
||||||
signed_integer_literal: $ => seq(optional("-"), $.integer_literal),
|
signed_integer_literal: $ => seq(optional("-"), $.integer_literal),
|
||||||
|
|
||||||
integer_literal: _ => token(choice(
|
integer_literal: _ => token(choice(
|
||||||
@@ -627,6 +745,10 @@ module.exports = grammar({
|
|||||||
_direct_pipeline_continuation: _ => token(seq(/\r?\n[ \t]*/, "->")),
|
_direct_pipeline_continuation: _ => token(seq(/\r?\n[ \t]*/, "->")),
|
||||||
_aggregate_pipeline_continuation: _ => token(seq(/\r?\n[ \t]*/, "|>")),
|
_aggregate_pipeline_continuation: _ => token(seq(/\r?\n[ \t]*/, "|>")),
|
||||||
_comparison_continuation: _ => token(seq(/\r?\n[ \t]*/, choice("<=", ">=", "==", "<", ">"))),
|
_comparison_continuation: _ => token(seq(/\r?\n[ \t]*/, choice("<=", ">=", "==", "<", ">"))),
|
||||||
|
// `context` is reserved for future language use and has no production,
|
||||||
|
// so this token exists only to keep it out of identifiers.
|
||||||
|
reserved_word: _ => "context",
|
||||||
|
|
||||||
_newline: _ => /\r?\n/,
|
_newline: _ => /\r?\n/,
|
||||||
_newlines: $ => repeat1($._newline),
|
_newlines: $ => repeat1($._newline),
|
||||||
_scope_separator: $ => choice($._newlines, ";"),
|
_scope_separator: $ => choice($._newlines, ";"),
|
||||||
|
|||||||
@@ -6,18 +6,15 @@
|
|||||||
"continue"
|
"continue"
|
||||||
"distinct"
|
"distinct"
|
||||||
"else"
|
"else"
|
||||||
"err"
|
|
||||||
"for"
|
"for"
|
||||||
"if"
|
"if"
|
||||||
"in"
|
"in"
|
||||||
"loop"
|
"loop"
|
||||||
"match"
|
"match"
|
||||||
"not"
|
"not"
|
||||||
"ok"
|
|
||||||
"or"
|
"or"
|
||||||
"pub"
|
"pub"
|
||||||
"return"
|
"return"
|
||||||
"some"
|
|
||||||
"use"
|
"use"
|
||||||
] @keyword
|
] @keyword
|
||||||
|
|
||||||
@@ -26,7 +23,6 @@
|
|||||||
(comment) @comment
|
(comment) @comment
|
||||||
(default_expression) @keyword
|
(default_expression) @keyword
|
||||||
(boolean_literal) @constant.builtin
|
(boolean_literal) @constant.builtin
|
||||||
(nil_literal) @constant.builtin
|
|
||||||
(string_literal) @string
|
(string_literal) @string
|
||||||
(character_literal) @character
|
(character_literal) @character
|
||||||
(integer_literal) @number
|
(integer_literal) @number
|
||||||
@@ -39,7 +35,12 @@
|
|||||||
(product_field name: (identifier) @property)
|
(product_field name: (identifier) @property)
|
||||||
(product_entry (identifier) @property)
|
(product_entry (identifier) @property)
|
||||||
(sum_variant name: (identifier) @constructor)
|
(sum_variant name: (identifier) @constructor)
|
||||||
|
(sum_constructor variant: (identifier) @constructor)
|
||||||
|
(sum_pattern variant: (identifier) @constructor)
|
||||||
(bits_member (identifier) @constant)
|
(bits_member (identifier) @constant)
|
||||||
|
(constraint_entry name: (identifier) @function)
|
||||||
|
(output_type function: (identifier) @function)
|
||||||
|
(output_type function: (qualified_name (identifier) @function .))
|
||||||
|
|
||||||
[
|
[
|
||||||
"=" "+=" "-=" "*=" "/=" "%=" "&=" "^=" "|="
|
"=" "+=" "-=" "*=" "/=" "%=" "&=" "^=" "|="
|
||||||
|
|||||||
+718
-205
File diff suppressed because it is too large.
Load diff
+361
-108
@@ -65,10 +65,6 @@
|
|||||||
"type": "character_literal",
|
"type": "character_literal",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "nil_literal",
|
|
||||||
"named": true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "signed_numeric_literal",
|
"type": "signed_numeric_literal",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -129,10 +125,6 @@
|
|||||||
"type": "identifier",
|
"type": "identifier",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "nil_literal",
|
|
||||||
"named": true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "product_pattern",
|
"type": "product_pattern",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -156,10 +148,6 @@
|
|||||||
{
|
{
|
||||||
"type": "unit_pattern",
|
"type": "unit_pattern",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "wrapper_pattern",
|
|
||||||
"named": true
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -263,6 +251,10 @@
|
|||||||
"type": "optional_type",
|
"type": "optional_type",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "output_type",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "primitive_type",
|
"type": "primitive_type",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -494,6 +486,10 @@
|
|||||||
"type": "map_type",
|
"type": "map_type",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "output_type",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "primitive_type",
|
"type": "primitive_type",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -538,6 +534,10 @@
|
|||||||
"type": "binary_expression",
|
"type": "binary_expression",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "pipeline_expression",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "postfix_expression",
|
"type": "postfix_expression",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -654,6 +654,10 @@
|
|||||||
"type": "binary_expression",
|
"type": "binary_expression",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "pipeline_expression",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "postfix_expression",
|
"type": "postfix_expression",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -742,6 +746,10 @@
|
|||||||
"type": "binary_expression",
|
"type": "binary_expression",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "pipeline_expression",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "postfix_expression",
|
"type": "postfix_expression",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -759,15 +767,71 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "bits_constructor",
|
"type": "binder",
|
||||||
"named": true,
|
"named": true,
|
||||||
"fields": {},
|
"fields": {},
|
||||||
|
"children": {
|
||||||
|
"multiple": true,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "binder_entry",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "binder_entry",
|
||||||
|
"named": true,
|
||||||
|
"fields": {
|
||||||
|
"constraint": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": false,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "constraint_body",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "type_name",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "type_expression",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "bits_constructor",
|
||||||
|
"named": true,
|
||||||
|
"fields": {
|
||||||
|
"type": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": false,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "type_name",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"children": {
|
"children": {
|
||||||
"multiple": true,
|
"multiple": true,
|
||||||
"required": false,
|
"required": false,
|
||||||
"types": [
|
"types": [
|
||||||
{
|
{
|
||||||
"type": "type_name",
|
"type": "identifier",
|
||||||
"named": true
|
"named": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -795,13 +859,24 @@
|
|||||||
{
|
{
|
||||||
"type": "bits_pattern",
|
"type": "bits_pattern",
|
||||||
"named": true,
|
"named": true,
|
||||||
"fields": {},
|
"fields": {
|
||||||
|
"type": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": false,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "type_name",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"children": {
|
"children": {
|
||||||
"multiple": true,
|
"multiple": true,
|
||||||
"required": false,
|
"required": false,
|
||||||
"types": [
|
"types": [
|
||||||
{
|
{
|
||||||
"type": "type_name",
|
"type": "identifier",
|
||||||
"named": true
|
"named": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -895,6 +970,67 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "constraint_body",
|
||||||
|
"named": true,
|
||||||
|
"fields": {},
|
||||||
|
"children": {
|
||||||
|
"multiple": true,
|
||||||
|
"required": false,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "constraint_entry",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "constraint_spread",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "constraint_entry",
|
||||||
|
"named": true,
|
||||||
|
"fields": {
|
||||||
|
"name": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "identifier",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "type_expression",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "constraint_spread",
|
||||||
|
"named": true,
|
||||||
|
"fields": {
|
||||||
|
"constraint": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "type_name",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "continuation_pipeline_stage",
|
"type": "continuation_pipeline_stage",
|
||||||
"named": true,
|
"named": true,
|
||||||
@@ -944,6 +1080,16 @@
|
|||||||
"type": "declaration",
|
"type": "declaration",
|
||||||
"named": true,
|
"named": true,
|
||||||
"fields": {
|
"fields": {
|
||||||
|
"binder": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": false,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "binder",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"multiple": false,
|
"multiple": false,
|
||||||
"required": false,
|
"required": false,
|
||||||
@@ -1152,6 +1298,10 @@
|
|||||||
"type": "optional_type",
|
"type": "optional_type",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "output_type",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "primitive_type",
|
"type": "primitive_type",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -1254,6 +1404,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "import_filter",
|
||||||
|
"named": true,
|
||||||
|
"fields": {
|
||||||
|
"type": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "type_expression",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "import_member",
|
"type": "import_member",
|
||||||
"named": true,
|
"named": true,
|
||||||
@@ -1278,6 +1444,16 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"children": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": false,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "import_filter",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1353,6 +1529,10 @@
|
|||||||
"type": "map_type",
|
"type": "map_type",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "output_type",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "primitive_type",
|
"type": "primitive_type",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -1486,6 +1666,10 @@
|
|||||||
"type": "map_type",
|
"type": "map_type",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "output_type",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "primitive_type",
|
"type": "primitive_type",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -1518,6 +1702,42 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "output_type",
|
||||||
|
"named": true,
|
||||||
|
"fields": {
|
||||||
|
"constructor": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "type_name",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"function": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "type_name",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "type_expression",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "pattern",
|
"type": "pattern",
|
||||||
"named": true,
|
"named": true,
|
||||||
@@ -1564,6 +1784,14 @@
|
|||||||
"type": "binary_expression",
|
"type": "binary_expression",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean_literal",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "character_literal",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "function_literal",
|
"type": "function_literal",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -1580,9 +1808,21 @@
|
|||||||
"type": "range_expression",
|
"type": "range_expression",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "signed_numeric_literal",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string_literal",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "unary_expression",
|
"type": "unary_expression",
|
||||||
"named": true
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "unit_literal",
|
||||||
|
"named": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1789,7 +2029,33 @@
|
|||||||
"required": false,
|
"required": false,
|
||||||
"types": [
|
"types": [
|
||||||
{
|
{
|
||||||
"type": "identifier",
|
"type": "pub_entry",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "pub_entry",
|
||||||
|
"named": true,
|
||||||
|
"fields": {
|
||||||
|
"name": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "identifier",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": false,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "import_filter",
|
||||||
"named": true
|
"named": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1822,6 +2088,10 @@
|
|||||||
"type": "binary_expression",
|
"type": "binary_expression",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "pipeline_expression",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "postfix_expression",
|
"type": "postfix_expression",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -1858,6 +2128,10 @@
|
|||||||
"type": "binary_expression",
|
"type": "binary_expression",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "pipeline_expression",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "postfix_expression",
|
"type": "postfix_expression",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -1898,6 +2172,10 @@
|
|||||||
"type": "map_type",
|
"type": "map_type",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "output_type",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "primitive_type",
|
"type": "primitive_type",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -1948,6 +2226,10 @@
|
|||||||
"type": "map_type",
|
"type": "map_type",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "output_type",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "primitive_type",
|
"type": "primitive_type",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -2048,22 +2330,53 @@
|
|||||||
{
|
{
|
||||||
"type": "sum_constructor",
|
"type": "sum_constructor",
|
||||||
"named": true,
|
"named": true,
|
||||||
"fields": {},
|
|
||||||
"children": {
|
|
||||||
"multiple": true,
|
|
||||||
"required": true,
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"type": "type_name",
|
|
||||||
"named": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "sum_pattern",
|
|
||||||
"named": true,
|
|
||||||
"fields": {
|
"fields": {
|
||||||
|
"type": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": false,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "type_name",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"variant": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "identifier",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "sum_pattern",
|
||||||
|
"named": true,
|
||||||
|
"fields": {
|
||||||
|
"payload": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": false,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "pattern_atom",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": false,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "type_name",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"variant": {
|
"variant": {
|
||||||
"multiple": false,
|
"multiple": false,
|
||||||
"required": true,
|
"required": true,
|
||||||
@@ -2074,20 +2387,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"children": {
|
|
||||||
"multiple": true,
|
|
||||||
"required": false,
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"type": "pattern_atom",
|
|
||||||
"named": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "type_name",
|
|
||||||
"named": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2224,6 +2523,10 @@
|
|||||||
"multiple": false,
|
"multiple": false,
|
||||||
"required": true,
|
"required": true,
|
||||||
"types": [
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "constraint_body",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "type_expression",
|
"type": "type_expression",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -2269,6 +2572,10 @@
|
|||||||
"type": "optional_type",
|
"type": "optional_type",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "output_type",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "primitive_type",
|
"type": "primitive_type",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -2354,6 +2661,10 @@
|
|||||||
"multiple": false,
|
"multiple": false,
|
||||||
"required": true,
|
"required": true,
|
||||||
"types": [
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "pipeline_expression",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "postfix_expression",
|
"type": "postfix_expression",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -2376,22 +2687,10 @@
|
|||||||
"type": "-",
|
"type": "-",
|
||||||
"named": false
|
"named": false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "err",
|
|
||||||
"named": false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "not",
|
"type": "not",
|
||||||
"named": false
|
"named": false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "ok",
|
|
||||||
"named": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "some",
|
|
||||||
"named": false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "~",
|
"type": "~",
|
||||||
"named": false
|
"named": false
|
||||||
@@ -2439,6 +2738,10 @@
|
|||||||
"multiple": true,
|
"multiple": true,
|
||||||
"required": true,
|
"required": true,
|
||||||
"types": [
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "import_filter",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "import_member",
|
"type": "import_member",
|
||||||
"named": true
|
"named": true
|
||||||
@@ -2450,40 +2753,6 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "wrapper_pattern",
|
|
||||||
"named": true,
|
|
||||||
"fields": {
|
|
||||||
"value": {
|
|
||||||
"multiple": false,
|
|
||||||
"required": true,
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"type": "pattern_atom",
|
|
||||||
"named": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"wrapper": {
|
|
||||||
"multiple": false,
|
|
||||||
"required": true,
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"type": "err",
|
|
||||||
"named": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ok",
|
|
||||||
"named": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "some",
|
|
||||||
"named": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "!",
|
"type": "!",
|
||||||
"named": false
|
"named": false
|
||||||
@@ -2697,10 +2966,6 @@
|
|||||||
"type": "else",
|
"type": "else",
|
||||||
"named": false
|
"named": false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "err",
|
|
||||||
"named": false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "f32",
|
"type": "f32",
|
||||||
"named": false
|
"named": false
|
||||||
@@ -2761,10 +3026,6 @@
|
|||||||
"type": "match",
|
"type": "match",
|
||||||
"named": false
|
"named": false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "nil_literal",
|
|
||||||
"named": true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "not",
|
"type": "not",
|
||||||
"named": false
|
"named": false
|
||||||
@@ -2773,10 +3034,6 @@
|
|||||||
"type": "nvr",
|
"type": "nvr",
|
||||||
"named": false
|
"named": false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "ok",
|
|
||||||
"named": false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "or",
|
"type": "or",
|
||||||
"named": false
|
"named": false
|
||||||
@@ -2789,10 +3046,6 @@
|
|||||||
"type": "return",
|
"type": "return",
|
||||||
"named": false
|
"named": false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "some",
|
|
||||||
"named": false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"named": false
|
"named": false
|
||||||
|
|||||||
+45540
-37130
File diff suppressed because it is too large.
Load diff
+240
-16
@@ -36,7 +36,7 @@ Point :: &{
|
|||||||
y: i32 = 0
|
y: i32 = 0
|
||||||
}
|
}
|
||||||
point := &Point.{ x: 1; y = 2 }
|
point := &Point.{ x: 1; y = 2 }
|
||||||
maybe: []{i32?}: [nil, some 1]
|
maybe: []{i32?}: [|.none, 1->|.some]
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -73,11 +73,16 @@ maybe: []{i32?}: [nil, some 1]
|
|||||||
(primitive_type))))
|
(primitive_type))))
|
||||||
(collection_literal
|
(collection_literal
|
||||||
(collection_entry
|
(collection_entry
|
||||||
(nil_literal))
|
(sum_constructor
|
||||||
|
(identifier)))
|
||||||
(collection_entry
|
(collection_entry
|
||||||
(unary_expression
|
(pipeline_expression
|
||||||
(signed_numeric_literal
|
(signed_numeric_literal
|
||||||
(integer_literal)))))))
|
(integer_literal))
|
||||||
|
(direct_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(sum_constructor
|
||||||
|
(identifier)))))))))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Control flow and patterns
|
Control flow and patterns
|
||||||
@@ -302,17 +307,17 @@ unit :: @ () -> i32 { 42 }
|
|||||||
Optional and result wrappers
|
Optional and result wrappers
|
||||||
==================
|
==================
|
||||||
|
|
||||||
wrap :: @ value: i32 -> i32 ! str { ok value }
|
wrap :: @ value: i32 -> i32 ! str { value->|.ok }
|
||||||
first :: @ items: []i32 -> i32? {
|
first :: @ items: []i32 -> i32? {
|
||||||
match items {
|
match items {
|
||||||
[] => nil
|
[] => |.none
|
||||||
[head, ...rest] => some head
|
[head, ...rest] => head->|.some
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unwrap :: @ result: i32 ! str -> i32 {
|
unwrap :: @ result: i32 ! str -> i32 {
|
||||||
match result {
|
match result {
|
||||||
ok value => value
|
|.ok value => value
|
||||||
err _ => 0
|
|.err _ => 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,8 +334,12 @@ unwrap :: @ result: i32 ! str -> i32 {
|
|||||||
(primitive_type)
|
(primitive_type)
|
||||||
(primitive_type))
|
(primitive_type))
|
||||||
(block
|
(block
|
||||||
(unary_expression
|
(pipeline_expression
|
||||||
(identifier)))))
|
(identifier)
|
||||||
|
(direct_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(sum_constructor
|
||||||
|
(identifier))))))))
|
||||||
(declaration
|
(declaration
|
||||||
(identifier)
|
(identifier)
|
||||||
(function_literal
|
(function_literal
|
||||||
@@ -346,7 +355,8 @@ unwrap :: @ result: i32 ! str -> i32 {
|
|||||||
(match_arm
|
(match_arm
|
||||||
(pattern
|
(pattern
|
||||||
(array_pattern))
|
(array_pattern))
|
||||||
(nil_literal))
|
(sum_constructor
|
||||||
|
(identifier)))
|
||||||
(match_arm
|
(match_arm
|
||||||
(pattern
|
(pattern
|
||||||
(array_pattern
|
(array_pattern
|
||||||
@@ -355,8 +365,12 @@ unwrap :: @ result: i32 ! str -> i32 {
|
|||||||
(identifier)))
|
(identifier)))
|
||||||
(array_pattern_entry
|
(array_pattern_entry
|
||||||
(identifier))))
|
(identifier))))
|
||||||
(unary_expression
|
(pipeline_expression
|
||||||
(identifier)))))))
|
(identifier)
|
||||||
|
(direct_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(sum_constructor
|
||||||
|
(identifier))))))))))
|
||||||
(declaration
|
(declaration
|
||||||
(identifier)
|
(identifier)
|
||||||
(function_literal
|
(function_literal
|
||||||
@@ -371,12 +385,14 @@ unwrap :: @ result: i32 ! str -> i32 {
|
|||||||
(identifier)
|
(identifier)
|
||||||
(match_arm
|
(match_arm
|
||||||
(pattern
|
(pattern
|
||||||
(wrapper_pattern
|
(sum_pattern
|
||||||
|
(identifier)
|
||||||
(identifier)))
|
(identifier)))
|
||||||
(identifier))
|
(identifier))
|
||||||
(match_arm
|
(match_arm
|
||||||
(pattern
|
(pattern
|
||||||
(wrapper_pattern))
|
(sum_pattern
|
||||||
|
(identifier)))
|
||||||
(signed_numeric_literal
|
(signed_numeric_literal
|
||||||
(integer_literal))))))))
|
(integer_literal))))))))
|
||||||
|
|
||||||
@@ -433,3 +449,211 @@ mixed :: @ (left: i32, right) -> i32 { left + right }
|
|||||||
(binary_expression
|
(binary_expression
|
||||||
(identifier)
|
(identifier)
|
||||||
(identifier))))))
|
(identifier))))))
|
||||||
|
|
||||||
|
==================
|
||||||
|
Postfix pipeline stages
|
||||||
|
==================
|
||||||
|
|
||||||
|
mixed :: -3->add_ten + 2 * 3->double - {1 + 1}->double
|
||||||
|
checked :: not c->is_digit
|
||||||
|
unwrapped :: input->fallible?->next
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(declaration
|
||||||
|
(identifier)
|
||||||
|
(binary_expression
|
||||||
|
(binary_expression
|
||||||
|
(unary_expression
|
||||||
|
(pipeline_expression
|
||||||
|
(signed_numeric_literal
|
||||||
|
(integer_literal))
|
||||||
|
(direct_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(identifier)))))
|
||||||
|
(binary_expression
|
||||||
|
(signed_numeric_literal
|
||||||
|
(integer_literal))
|
||||||
|
(pipeline_expression
|
||||||
|
(signed_numeric_literal
|
||||||
|
(integer_literal))
|
||||||
|
(direct_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(identifier))))))
|
||||||
|
(pipeline_expression
|
||||||
|
(block
|
||||||
|
(binary_expression
|
||||||
|
(signed_numeric_literal
|
||||||
|
(integer_literal))
|
||||||
|
(signed_numeric_literal
|
||||||
|
(integer_literal))))
|
||||||
|
(direct_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(identifier))))))
|
||||||
|
(declaration
|
||||||
|
(identifier)
|
||||||
|
(unary_expression
|
||||||
|
(pipeline_expression
|
||||||
|
(identifier)
|
||||||
|
(direct_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(identifier))))))
|
||||||
|
(declaration
|
||||||
|
(identifier)
|
||||||
|
(pipeline_expression
|
||||||
|
(identifier)
|
||||||
|
(direct_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(identifier)))
|
||||||
|
(direct_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(identifier))))))
|
||||||
|
|
||||||
|
==================
|
||||||
|
Continuations after same-line stages
|
||||||
|
==================
|
||||||
|
|
||||||
|
flat := value->first->second
|
||||||
|
->third
|
||||||
|
whole := a + b->f
|
||||||
|
->g
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(declaration
|
||||||
|
(identifier)
|
||||||
|
(pipeline_expression
|
||||||
|
(identifier)
|
||||||
|
(direct_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(identifier)))
|
||||||
|
(direct_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(identifier)))
|
||||||
|
(continuation_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(identifier)))))
|
||||||
|
(declaration
|
||||||
|
(identifier)
|
||||||
|
(pipeline_expression
|
||||||
|
(binary_expression
|
||||||
|
(identifier)
|
||||||
|
(pipeline_expression
|
||||||
|
(identifier)
|
||||||
|
(direct_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(identifier)))))
|
||||||
|
(continuation_pipeline_stage
|
||||||
|
(pipeline_callable
|
||||||
|
(identifier))))))
|
||||||
|
|
||||||
|
==================
|
||||||
|
Generic binders and constraints
|
||||||
|
==================
|
||||||
|
|
||||||
|
Show :: <>{
|
||||||
|
to_str: str
|
||||||
|
...Display
|
||||||
|
}
|
||||||
|
pick: <T: Show, (T, T): Ordered> (T, T) -> T: @ (first, second): (T, T) { first }
|
||||||
|
Card :: &{ label: Output<make_label: Show>: }
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(declaration
|
||||||
|
(identifier)
|
||||||
|
(type_definition
|
||||||
|
(constraint_body
|
||||||
|
(constraint_entry
|
||||||
|
(identifier)
|
||||||
|
(primitive_type))
|
||||||
|
(constraint_spread
|
||||||
|
(identifier)))))
|
||||||
|
(declaration
|
||||||
|
(identifier)
|
||||||
|
(binder
|
||||||
|
(binder_entry
|
||||||
|
(identifier)
|
||||||
|
(identifier))
|
||||||
|
(binder_entry
|
||||||
|
(tuple_type
|
||||||
|
(identifier)
|
||||||
|
(identifier))
|
||||||
|
(identifier)))
|
||||||
|
(function_type
|
||||||
|
(tuple_type
|
||||||
|
(identifier)
|
||||||
|
(identifier))
|
||||||
|
(identifier))
|
||||||
|
(function_literal
|
||||||
|
(typed_parameter
|
||||||
|
(tuple_pattern
|
||||||
|
(pattern
|
||||||
|
(identifier))
|
||||||
|
(pattern
|
||||||
|
(identifier)))
|
||||||
|
(tuple_type
|
||||||
|
(identifier)
|
||||||
|
(identifier)))
|
||||||
|
(block
|
||||||
|
(identifier))))
|
||||||
|
(declaration
|
||||||
|
(identifier)
|
||||||
|
(type_definition
|
||||||
|
(product_type
|
||||||
|
(product_field
|
||||||
|
(identifier)
|
||||||
|
(output_type
|
||||||
|
(identifier)
|
||||||
|
(identifier)
|
||||||
|
(identifier)))))))
|
||||||
|
|
||||||
|
==================
|
||||||
|
Import filters
|
||||||
|
==================
|
||||||
|
|
||||||
|
use math.{sqrt for f64, pi as p}
|
||||||
|
use .shapes.area for Circle
|
||||||
|
pub { area for Circle; sqrt }
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(use_declaration
|
||||||
|
(module_path
|
||||||
|
(identifier))
|
||||||
|
(import_member
|
||||||
|
(identifier)
|
||||||
|
(import_filter
|
||||||
|
(primitive_type)))
|
||||||
|
(import_member
|
||||||
|
(identifier)
|
||||||
|
(identifier)))
|
||||||
|
(use_declaration
|
||||||
|
(module_path
|
||||||
|
(qualified_name
|
||||||
|
(identifier)
|
||||||
|
(identifier)))
|
||||||
|
(import_filter
|
||||||
|
(identifier)))
|
||||||
|
(pub_declaration
|
||||||
|
(pub_entry
|
||||||
|
(identifier)
|
||||||
|
(import_filter
|
||||||
|
(identifier)))
|
||||||
|
(pub_entry
|
||||||
|
(identifier))))
|
||||||
|
|
||||||
|
==================
|
||||||
|
Reserved word
|
||||||
|
:error
|
||||||
|
==================
|
||||||
|
|
||||||
|
context := 1
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
value :: @ x: i32 -> i32 ! str { x! }
|
|
||||||
Vendored
-1
@@ -1 +0,0 @@
|
|||||||
value :: @ x: str -> i32 ! str { !x }
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
ok :: @ value { value }
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
some := 1
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
value: i32?: 1->|.some
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
value :: @ x: i32? { match x { |.some y => y; nil => 0 } }
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
value :: 1 + 2->to_str
|
|
||||||
Vendored
+2
-2
@@ -6,8 +6,8 @@ more_codes := [...codes, 'failed' => 500]
|
|||||||
|
|
||||||
empty_numbers: []i32: []
|
empty_numbers: []i32: []
|
||||||
empty_codes: [str]i32: []
|
empty_codes: [str]i32: []
|
||||||
optional_numbers: []i32?: nil
|
optional_numbers: []i32?: |.none
|
||||||
optional_elements: []{i32?}: [nil, some 1]
|
optional_elements: []{i32?}: [|.none, 1->|.some]
|
||||||
|
|
||||||
Options :: &{
|
Options :: &{
|
||||||
name: str: 'default'
|
name: str: 'default'
|
||||||
|
|||||||
Vendored
+2
-2
@@ -11,10 +11,10 @@ choose_block: (bit, i32, i32) -> i32: @ (condition: bit, when_true: i32, when_fa
|
|||||||
first_positive: []i32 -> i32?: @ values: []i32 {
|
first_positive: []i32 -> i32?: @ values: []i32 {
|
||||||
for value in values {
|
for value in values {
|
||||||
if value > 0 {
|
if value > 0 {
|
||||||
return some value
|
return value->|.some
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nil
|
|.none
|
||||||
}
|
}
|
||||||
|
|
||||||
labelled_search: []i32 -> i32: @ values: []i32 { loop `outer {
|
labelled_search: []i32 -> i32: @ values: []i32 { loop `outer {
|
||||||
|
|||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
add_ten: i32 -> i32: @ value: i32 { value + 10 }
|
||||||
|
double: i32 -> i32: @ value: i32 { value * 2 }
|
||||||
|
|
||||||
|
# Stages bind tighter than prefix and infix operators: -{3->add_ten} + 2 * {3->double}.
|
||||||
|
mixed: i32: -3->add_ten + 2 * 3->double - {1 + 1}->double
|
||||||
Vendored
+2
-2
@@ -15,9 +15,9 @@ commented := 'value' # an inline comment preserves continuation
|
|||||||
computed := 1 + 2
|
computed := 1 + 2
|
||||||
->to_str
|
->to_str
|
||||||
|
|
||||||
fallible: i32 -> i32 ! Error: @ value: i32 { ok value }
|
fallible: i32 -> i32 ! Error: @ value: i32 { value->|.ok }
|
||||||
|
|
||||||
propagate: i32 -> i32 ! Error: @ value: i32 {
|
propagate: i32 -> i32 ! Error: @ value: i32 {
|
||||||
result := {value->fallible}?
|
result := {value->fallible}?
|
||||||
ok result
|
result->|.ok
|
||||||
}
|
}
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
use math.{pi, sqrt}
|
|
||||||
use math as m
|
|
||||||
use random.{Pcg32, pcg32, draw_u32}
|
|
||||||
use time.{Duration, TimeError, duration_neg}
|
|
||||||
use time as t
|
|
||||||
|
|
||||||
circle: f64: pi
|
|
||||||
root: f64: 4.0->sqrt
|
|
||||||
# Host overloads are selected by the operand, so the literal is typed first.
|
|
||||||
nine: f32: 9.0
|
|
||||||
qualified_root: f32: nine->m.sqrt
|
|
||||||
qualified_pi: f32: m.pi
|
|
||||||
|
|
||||||
seed: u64: 42
|
|
||||||
generator: Pcg32: seed->pcg32
|
|
||||||
draw: u32: generator->draw_u32
|
|
||||||
|
|
||||||
negate: Duration => Duration ! TimeError: duration_neg
|
|
||||||
qualified_negate: t.Duration => t.Duration ! t.TimeError: t.duration_neg
|
|
||||||
Vendored
-24
@@ -1,24 +0,0 @@
|
|||||||
present: i32?: some 1
|
|
||||||
absent: i32?: nil
|
|
||||||
success: i32 ! str: ok 1
|
|
||||||
failure: i32 ! str: err 'failed'
|
|
||||||
piped: i32?: some 4->double
|
|
||||||
grouped: i32?: some {4->double}
|
|
||||||
|
|
||||||
double :: @ value { value * 2 }
|
|
||||||
describe :: @ (label: str, count) -> str { label }
|
|
||||||
|
|
||||||
unwrap_or: i32? -> i32: @ value {
|
|
||||||
match value {
|
|
||||||
some inner => inner
|
|
||||||
nil => 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handle: i32 ! str -> i32: @ result {
|
|
||||||
match result {
|
|
||||||
ok value if value > 0 => value
|
|
||||||
ok _ => 0
|
|
||||||
err message => message->length
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user