Add associative map constraints and range refinement
This commit is contained in:
@@ -8,6 +8,8 @@ It is designed around a lightweight Rust library:
|
||||
- shared host environments for production and semantic editor tooling
|
||||
- no filesystem access in the library core
|
||||
- concrete and abstract values with constraints and defaults
|
||||
- asymmetric range refinement with `narrower as wider`
|
||||
- homogeneous associative-array schemas with `{...valueSchema}`
|
||||
- deterministic expression evaluation
|
||||
- optional regex support behind a Cargo feature
|
||||
- browser playground support through WebAssembly
|
||||
|
||||
@@ -53,6 +53,9 @@ pub enum Expr {
|
||||
ArrayConstraint {
|
||||
item: ExprId,
|
||||
},
|
||||
MapConstraint {
|
||||
value: ExprId,
|
||||
},
|
||||
Let {
|
||||
bindings: Vec<Field>,
|
||||
body: ExprId,
|
||||
@@ -94,6 +97,10 @@ pub enum Expr {
|
||||
base: ExprId,
|
||||
fallback: ExprId,
|
||||
},
|
||||
As {
|
||||
narrower: ExprId,
|
||||
wider: ExprId,
|
||||
},
|
||||
CompareConstraint {
|
||||
op: CompareOp,
|
||||
value: ExprId,
|
||||
|
||||
@@ -12,6 +12,7 @@ pub fn normalize_constraints(
|
||||
) -> crate::Result<Vec<ConstraintEntry>> {
|
||||
let mut primitive: Option<(PrimitiveType, Span)> = None;
|
||||
let mut array_span: Option<Span> = None;
|
||||
let mut map_span: Option<Span> = None;
|
||||
let mut lower: Option<(Bound, Span)> = None;
|
||||
let mut upper: Option<(Bound, Span)> = None;
|
||||
let mut rest = Vec::new();
|
||||
@@ -69,6 +70,13 @@ pub fn normalize_constraints(
|
||||
span: entry.span,
|
||||
});
|
||||
}
|
||||
Constraint::MapValues(value) => {
|
||||
map_span.get_or_insert(entry.span);
|
||||
rest.push(ConstraintEntry {
|
||||
constraint: Constraint::MapValues(value),
|
||||
span: entry.span,
|
||||
});
|
||||
}
|
||||
Constraint::BuiltinPredicate(name) => rest.push(ConstraintEntry {
|
||||
constraint: Constraint::BuiltinPredicate(name),
|
||||
span: entry.span,
|
||||
@@ -86,6 +94,26 @@ pub fn normalize_constraints(
|
||||
.with_label(array_span, "array element constraint"));
|
||||
}
|
||||
|
||||
if let (Some((_, primitive_span)), Some(map_span)) = (primitive, map_span) {
|
||||
return Err(Diagnostic::new(
|
||||
DiagnosticKind::Conflict,
|
||||
span,
|
||||
"map value constraints conflict with primitive type constraints",
|
||||
)
|
||||
.with_label(primitive_span, "primitive constraint")
|
||||
.with_label(map_span, "map value constraint"));
|
||||
}
|
||||
|
||||
if let (Some(array_span), Some(map_span)) = (array_span, map_span) {
|
||||
return Err(Diagnostic::new(
|
||||
DiagnosticKind::Conflict,
|
||||
span,
|
||||
"array and map constraints conflict",
|
||||
)
|
||||
.with_label(array_span, "array element constraint")
|
||||
.with_label(map_span, "map value constraint"));
|
||||
}
|
||||
|
||||
if let Some(array_span) = array_span
|
||||
&& (lower.is_some() || upper.is_some())
|
||||
{
|
||||
@@ -104,6 +132,24 @@ pub fn normalize_constraints(
|
||||
return Err(diagnostic);
|
||||
}
|
||||
|
||||
if let Some(map_span) = map_span
|
||||
&& (lower.is_some() || upper.is_some())
|
||||
{
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
DiagnosticKind::Conflict,
|
||||
span,
|
||||
"numeric comparison constraints conflict with map value constraints",
|
||||
)
|
||||
.with_label(map_span, "map value constraint");
|
||||
if let Some((_, lower_span)) = lower {
|
||||
diagnostic = diagnostic.with_label(lower_span, "numeric comparison constraint");
|
||||
}
|
||||
if let Some((_, upper_span)) = upper {
|
||||
diagnostic = diagnostic.with_label(upper_span, "numeric comparison constraint");
|
||||
}
|
||||
return Err(diagnostic);
|
||||
}
|
||||
|
||||
if matches!(
|
||||
primitive,
|
||||
Some((PrimitiveType::String | PrimitiveType::Bool, _))
|
||||
|
||||
@@ -15,6 +15,11 @@ pub enum HostValue {
|
||||
constraints: Vec<Constraint>,
|
||||
default: Option<Box<HostValue>>,
|
||||
},
|
||||
MapConstraint {
|
||||
value: Box<HostValue>,
|
||||
constraints: Vec<Constraint>,
|
||||
default: Option<Box<HostValue>>,
|
||||
},
|
||||
Object(Vec<HostField>),
|
||||
Abstract {
|
||||
constraints: Vec<Constraint>,
|
||||
@@ -104,6 +109,14 @@ impl HostValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_of(value: HostValue) -> Self {
|
||||
Self::MapConstraint {
|
||||
value: Box::new(value),
|
||||
constraints: Vec::new(),
|
||||
default: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn builtin_predicate(name: impl Into<String>) -> Self {
|
||||
Self::abstract_with_constraint(Constraint::BuiltinPredicate(name.into()))
|
||||
}
|
||||
@@ -118,7 +131,9 @@ impl HostValue {
|
||||
pub fn with_constraint(mut self, constraint: Constraint) -> Self {
|
||||
match &mut self {
|
||||
Self::Abstract { constraints, .. } => constraints.push(constraint),
|
||||
Self::ArrayConstraint { constraints, .. } => constraints.push(constraint),
|
||||
Self::ArrayConstraint { constraints, .. } | Self::MapConstraint { constraints, .. } => {
|
||||
constraints.push(constraint)
|
||||
}
|
||||
_ => {
|
||||
self = Self::Abstract {
|
||||
constraints: alloc::vec![constraint],
|
||||
@@ -169,6 +184,22 @@ impl HostValue {
|
||||
Span::default(),
|
||||
"host value already has a default",
|
||||
)),
|
||||
Self::MapConstraint {
|
||||
value: map_value,
|
||||
constraints,
|
||||
default: None,
|
||||
} => Ok(Self::MapConstraint {
|
||||
value: map_value,
|
||||
constraints,
|
||||
default: Some(Box::new(value)),
|
||||
}),
|
||||
Self::MapConstraint {
|
||||
default: Some(_), ..
|
||||
} => Err(Diagnostic::new(
|
||||
DiagnosticKind::DefaultConflict,
|
||||
Span::default(),
|
||||
"host value already has a default",
|
||||
)),
|
||||
Self::Abstract {
|
||||
constraints,
|
||||
default: None,
|
||||
|
||||
+904
-27
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,7 @@ pub enum TokenKind {
|
||||
Match,
|
||||
Import,
|
||||
Default,
|
||||
As,
|
||||
Underscore,
|
||||
LBrace,
|
||||
RBrace,
|
||||
@@ -406,6 +407,7 @@ impl<'a> Lexer<'a> {
|
||||
"match" => TokenKind::Match,
|
||||
"import" => TokenKind::Import,
|
||||
"default" => TokenKind::Default,
|
||||
"as" => TokenKind::As,
|
||||
_ => TokenKind::Ident(String::from(text)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,6 +245,13 @@ impl Parser {
|
||||
},
|
||||
span,
|
||||
),
|
||||
InfixKind::As => self.ast.push(
|
||||
Expr::As {
|
||||
narrower: lhs,
|
||||
wider: rhs,
|
||||
},
|
||||
span,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -319,6 +326,16 @@ impl Parser {
|
||||
}
|
||||
|
||||
fn parse_object_after_lbrace(&mut self, start_span: Span) -> Result<ExprId> {
|
||||
if self.consume_kind(&TokenKind::Ellipsis).is_some() {
|
||||
let value = self.parse_expr(0)?;
|
||||
self.expect_kind(
|
||||
&TokenKind::RBrace,
|
||||
"expected '}' after map value constraint",
|
||||
)?;
|
||||
let span = start_span.join(self.previous_span());
|
||||
return Ok(self.ast.push(Expr::MapConstraint { value }, span));
|
||||
}
|
||||
|
||||
let mut fields = Vec::new();
|
||||
if self.consume_kind(&TokenKind::RBrace).is_some() {
|
||||
return Ok(self
|
||||
@@ -544,6 +561,7 @@ impl Parser {
|
||||
|
||||
fn peek_infix(&self) -> Option<(InfixKind, u8, u8)> {
|
||||
match self.peek_kind() {
|
||||
TokenKind::As => Some((InfixKind::As, 0, 1)),
|
||||
TokenKind::Default => Some((InfixKind::Default, 1, 2)),
|
||||
TokenKind::SlashSlash => Some((InfixKind::Patch, 3, 4)),
|
||||
TokenKind::Amp => Some((InfixKind::And, 5, 6)),
|
||||
@@ -652,6 +670,7 @@ impl Parser {
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum InfixKind {
|
||||
As,
|
||||
Add,
|
||||
Sub,
|
||||
Mul,
|
||||
@@ -720,4 +739,23 @@ mod tests {
|
||||
fn rejects_array_constraint_without_element_constraint() {
|
||||
assert!(parse_source("[...]").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_map_constraint() {
|
||||
let parsed = parse_source("{...String}").unwrap();
|
||||
let Expr::MapConstraint { value } = parsed.ast.get(parsed.root).expr else {
|
||||
panic!()
|
||||
};
|
||||
assert!(matches!(parsed.ast.get(value).expr, Expr::Ident(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_as_below_composition() {
|
||||
let parsed = parse_source("value & override as Schema").unwrap();
|
||||
let Expr::As { narrower, wider } = parsed.ast.get(parsed.root).expr else {
|
||||
panic!()
|
||||
};
|
||||
assert!(matches!(parsed.ast.get(narrower).expr, Expr::Binary { .. }));
|
||||
assert!(matches!(parsed.ast.get(wider).expr, Expr::Ident(_)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ pub struct ConstraintEntry {
|
||||
pub enum Constraint {
|
||||
Type(PrimitiveType),
|
||||
ArrayItems(ThunkId),
|
||||
MapValues(ThunkId),
|
||||
Compare(CompareOp, LiteralValue),
|
||||
Regex(String),
|
||||
BuiltinPredicate(String),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use alloc::{format, string::String, vec::Vec};
|
||||
use alloc::{collections::BTreeMap, format, string::String, vec::Vec};
|
||||
|
||||
use crate::{Data, HostValue};
|
||||
|
||||
@@ -225,3 +225,96 @@ impl<T: IntoHostValue> IntoHostValue for Vec<T> {
|
||||
HostValue::array(self.into_iter().map(IntoHostValue::into_host_value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DecodalSchema> DecodalSchema for BTreeMap<String, T> {
|
||||
fn decodal_schema() -> HostValue {
|
||||
HostValue::map_of(T::decodal_schema())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DecodalDecode> DecodalDecode for BTreeMap<String, T> {
|
||||
fn decodal_decode(data: &Data) -> DecodeResult<Self> {
|
||||
match data {
|
||||
Data::Object(fields) => fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
T::decodal_decode(&field.value)
|
||||
.map(|value| (field.name.clone(), value))
|
||||
.map_err(|error| prefix_error(&field.name, error))
|
||||
})
|
||||
.collect(),
|
||||
_ => Err(DecodeError::at_type("", "Object")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoHostValue> IntoHostValue for BTreeMap<String, T> {
|
||||
fn into_host_value(self) -> HostValue {
|
||||
HostValue::object(
|
||||
self.into_iter()
|
||||
.map(|(name, value)| (name, value.into_host_value())),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: DecodalSchema> DecodalSchema for std::collections::HashMap<String, T> {
|
||||
fn decodal_schema() -> HostValue {
|
||||
HostValue::map_of(T::decodal_schema())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: DecodalDecode> DecodalDecode for std::collections::HashMap<String, T> {
|
||||
fn decodal_decode(data: &Data) -> DecodeResult<Self> {
|
||||
match data {
|
||||
Data::Object(fields) => fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
T::decodal_decode(&field.value)
|
||||
.map(|value| (field.name.clone(), value))
|
||||
.map_err(|error| prefix_error(&field.name, error))
|
||||
})
|
||||
.collect(),
|
||||
_ => Err(DecodeError::at_type("", "Object")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: IntoHostValue> IntoHostValue for std::collections::HashMap<String, T> {
|
||||
fn into_host_value(self) -> HostValue {
|
||||
let mut fields: Vec<_> = self
|
||||
.into_iter()
|
||||
.map(|(name, value)| (name, value.into_host_value()))
|
||||
.collect();
|
||||
fields.sort_by(|left, right| left.0.cmp(&right.0));
|
||||
HostValue::object(fields)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::runtime::{Constraint, DataField, PrimitiveType};
|
||||
|
||||
#[test]
|
||||
fn string_maps_expose_map_schemas_and_decode_objects() {
|
||||
assert!(matches!(
|
||||
BTreeMap::<String, i64>::decodal_schema(),
|
||||
HostValue::MapConstraint { value, .. }
|
||||
if matches!(
|
||||
*value,
|
||||
HostValue::Abstract { ref constraints, .. }
|
||||
if constraints == &[Constraint::Type(PrimitiveType::Int)]
|
||||
)
|
||||
));
|
||||
|
||||
let data = Data::Object(alloc::vec![DataField {
|
||||
name: String::from("api"),
|
||||
value: Data::Int(8080),
|
||||
}]);
|
||||
let decoded = BTreeMap::<String, i64>::decodal_decode(&data).unwrap();
|
||||
assert_eq!(decoded.get("api"), Some(&8080));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,6 +222,7 @@ fn builtin_items() -> Vec<CompletionItem> {
|
||||
("match", CompletionKind::Keyword, "pattern matching", 5),
|
||||
("import", CompletionKind::Keyword, "load a module", 5),
|
||||
("default", CompletionKind::Keyword, "fallback value", 0),
|
||||
("as", CompletionKind::Keyword, "refine narrower as wider", 0),
|
||||
("true", CompletionKind::Constant, "Bool", 0),
|
||||
("false", CompletionKind::Constant, "Bool", 0),
|
||||
("String", CompletionKind::Type, "string constraint", 5),
|
||||
@@ -276,6 +277,10 @@ fn fields_from_host_value(value: &HostValue) -> FieldTree {
|
||||
default: Some(value),
|
||||
..
|
||||
}
|
||||
| HostValue::MapConstraint {
|
||||
default: Some(value),
|
||||
..
|
||||
}
|
||||
| HostValue::Abstract {
|
||||
default: Some(value),
|
||||
..
|
||||
|
||||
@@ -169,6 +169,11 @@ impl<'a> Formatter<'a> {
|
||||
self.write_expr(out, *item, indent, 0);
|
||||
out.push(']');
|
||||
}
|
||||
Expr::MapConstraint { value } => {
|
||||
out.push_str("{...");
|
||||
self.write_expr(out, *value, indent, 0);
|
||||
out.push('}');
|
||||
}
|
||||
Expr::Let { bindings, body } => self.write_let(out, node.span, bindings, *body, indent),
|
||||
Expr::Import(_) => {
|
||||
out.push_str("import ");
|
||||
@@ -219,6 +224,11 @@ impl<'a> Formatter<'a> {
|
||||
out.push_str(" default ");
|
||||
self.write_expr(out, *fallback, indent, precedence + 1);
|
||||
}
|
||||
Expr::As { narrower, wider } => {
|
||||
self.write_expr(out, *narrower, indent, precedence);
|
||||
out.push_str(" as ");
|
||||
self.write_expr(out, *wider, indent, precedence + 1);
|
||||
}
|
||||
Expr::CompareConstraint { op, value } => {
|
||||
out.push_str(compare_operator(*op));
|
||||
out.push(' ');
|
||||
@@ -461,6 +471,7 @@ impl<'a> Formatter<'a> {
|
||||
|
||||
fn precedence(&self, id: ExprId) -> u8 {
|
||||
match &self.ast.get(id).expr {
|
||||
Expr::As { .. } => 0,
|
||||
Expr::Default { .. } => 1,
|
||||
Expr::Binary { op, .. } => match op {
|
||||
BinaryOp::Patch => 3,
|
||||
@@ -508,7 +519,11 @@ impl<'a> Formatter<'a> {
|
||||
}
|
||||
Expr::Array(items) => items.iter().all(|item| self.is_inline_expr(*item)),
|
||||
Expr::ArrayConstraint { item } => self.is_inline_expr(*item),
|
||||
Expr::MapConstraint { value } => self.is_inline_expr(*value),
|
||||
Expr::Parenthesized { expr } => self.is_inline_expr(*expr),
|
||||
Expr::As { narrower, wider } => {
|
||||
self.is_inline_expr(*narrower) && self.is_inline_expr(*wider)
|
||||
}
|
||||
Expr::Object(_) | Expr::Let { .. } | Expr::Function { .. } | Expr::Match { .. } => {
|
||||
false
|
||||
}
|
||||
@@ -670,6 +685,18 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn formats_map_constraints_and_range_ascription() {
|
||||
let source =
|
||||
"config={service={port=8080;};}as{service={port=Int;};};labels={a=1;b=2;}as{...Int};";
|
||||
let formatted = format_source(source).unwrap();
|
||||
assert_eq!(
|
||||
formatted,
|
||||
"config = {\n service = {\n port = 8080;\n };\n} as {\n service = {\n port = Int;\n };\n};\nlabels = {\n a = 1;\n b = 2;\n} as {...Int};\n"
|
||||
);
|
||||
assert_eq!(format_source(&formatted).unwrap(), formatted);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn formats_let_functions_and_precedence_from_the_canonical_ast() {
|
||||
let source = "value=let x=1+2*3;in(a:Int)=>{result=(x+a)*2;};";
|
||||
@@ -743,6 +770,10 @@ mod tests {
|
||||
include_str!("../../../examples/import/schema.dcdl"),
|
||||
),
|
||||
("logical", include_str!("../../../examples/logical.dcdl")),
|
||||
(
|
||||
"map-ascription",
|
||||
include_str!("../../../examples/map-ascription.dcdl"),
|
||||
),
|
||||
(
|
||||
"regex/main",
|
||||
include_str!("../../../examples/regex/main.dcdl"),
|
||||
|
||||
@@ -84,6 +84,16 @@ fn object(fields: &Map<String, Value>) -> Result<HostValue, String> {
|
||||
default,
|
||||
})
|
||||
}
|
||||
"Map" => {
|
||||
let value = fields
|
||||
.get("value")
|
||||
.ok_or_else(|| String::from("Map descriptor requires `value`"))?;
|
||||
Ok(HostValue::MapConstraint {
|
||||
value: Box::new(from_json(value)?),
|
||||
constraints,
|
||||
default,
|
||||
})
|
||||
}
|
||||
"Abstract" => Ok(HostValue::Abstract {
|
||||
constraints,
|
||||
default,
|
||||
@@ -217,6 +227,23 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn converts_map_schema_descriptors() {
|
||||
let value = serde_json::json!({
|
||||
"$decodal": "Map",
|
||||
"value": { "$decodal": "Bool" },
|
||||
"default": {},
|
||||
});
|
||||
assert_eq!(
|
||||
from_json(&value).unwrap(),
|
||||
HostValue::MapConstraint {
|
||||
value: Box::new(HostValue::bool_type()),
|
||||
constraints: Vec::new(),
|
||||
default: Some(Box::new(HostValue::object([] as [(&str, HostValue); 0]))),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_null_values() {
|
||||
assert!(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Composition and Materialization
|
||||
|
||||
`&`、`//`、`default`、materialize は、runtime value の variant に基づいて処理する。
|
||||
`&`、`//`、`as`、`default`、materialize は、runtime value の variant に基づいて処理する。
|
||||
|
||||
## `&`
|
||||
|
||||
@@ -89,7 +89,24 @@ patch(a: RuntimeValue, b: RuntimeValue) -> RuntimeValue
|
||||
- 配列、scalar、function は右辺置換とする。
|
||||
|
||||
`//` は制約を保持するための演算子ではない。
|
||||
制約を満たす具体化には `&` を使う。
|
||||
対称な制約合成には `&` を使い、左辺が右辺より狭いことを確認しながら合成する場合は `as` を使う。
|
||||
|
||||
## `as`
|
||||
|
||||
`as` は narrower と wider の向きを固定した範囲包含確認と合成である。
|
||||
|
||||
```text
|
||||
apply_as(narrower: RuntimeValue, wider: RuntimeValue)
|
||||
-> RuntimeValue | Diagnostic
|
||||
```
|
||||
|
||||
abstract / abstract では、左辺 constraints が右辺 constraints を包含することを確認し、左辺を結果にする。
|
||||
concrete / abstract では、concrete value が右辺 constraints を満たすことを確認する。
|
||||
|
||||
object / object では右辺を field domain とする。左辺にしかない field は診断し、両側にある field は再帰的に `apply_as` し、右辺にしかない field は thunk を force せずそのまま結果へ残す。
|
||||
この扱いは default の有無に依存しない。default は包含判定の根拠でも `as` の補完値でもなく、後の materialize だけが選択する。
|
||||
|
||||
`ArrayItems(wider)` は concrete array の全要素を、`MapValues(wider)` は concrete object の全 field value を同じ関数で絞り込む。
|
||||
|
||||
## materialize
|
||||
|
||||
|
||||
@@ -41,10 +41,10 @@ engine.bind_global(
|
||||
A user source can then refer to `Service` without importing it.
|
||||
|
||||
```dcdl
|
||||
Service & {
|
||||
{
|
||||
name = "api";
|
||||
port = 9443;
|
||||
}
|
||||
} as Service
|
||||
```
|
||||
|
||||
## HostValue
|
||||
@@ -60,6 +60,7 @@ HostValue =
|
||||
Bool
|
||||
Array(Vec<HostValue>)
|
||||
ArrayConstraint { item, constraints, default }
|
||||
MapConstraint { value, constraints, default }
|
||||
Object(Vec<HostField>)
|
||||
Abstract { constraints, default }
|
||||
```
|
||||
@@ -69,6 +70,9 @@ When a host value is bound, the engine internalizes it into `RuntimeValue` and a
|
||||
`HostValue::array_of(item)` builds an array constraint with a required element schema.
|
||||
There is no host API for an unconstrained abstract array.
|
||||
|
||||
`HostValue::map_of(value)` builds a map constraint whose arbitrary object field values must satisfy `value`.
|
||||
`BTreeMap<String, T>` and, with `std`, `HashMap<String, T>` implement `DecodalSchema`, `DecodalDecode`, and `IntoHostValue` using this representation.
|
||||
|
||||
## Abstract host objects
|
||||
|
||||
A host-provided schema object is represented as a concrete object structure whose fields may contain abstract values.
|
||||
|
||||
@@ -16,7 +16,8 @@ demand-driven evaluation
|
||||
├─ load imported module on demand
|
||||
├─ evaluate expression
|
||||
├─ compose `&`
|
||||
└─ patch `//`
|
||||
├─ patch `//`
|
||||
└─ validate `as`
|
||||
↓
|
||||
materialize
|
||||
↓
|
||||
@@ -105,9 +106,16 @@ eval(A // B):
|
||||
a = eval(A)
|
||||
b = eval(B)
|
||||
patch(a, b)
|
||||
|
||||
eval(A as S):
|
||||
narrower = eval(A)
|
||||
wider = eval(S)
|
||||
apply_as(narrower, wider)
|
||||
```
|
||||
|
||||
`&` は制約を保った合成を行い、`//` は右辺優先の deep patch を行う。
|
||||
`&` は制約を保った対称な合成を行い、`//` は右辺優先の deep patch を行う。
|
||||
`as` は左辺が右辺より狭いことを再帰的に確認する。左辺で絞られた部分は左辺を使い、右辺だけの部分は abstract のまま保持する。
|
||||
default は `as` では選択せず、materialize まで遅延する。
|
||||
詳細は [Composition and Materialization](./composition-and-materialization.md) に置く。
|
||||
|
||||
## resolver / binder
|
||||
@@ -140,7 +148,7 @@ resolver / binder を追加すると、以下を早期に診断しやすくな
|
||||
- import path の一部静的解決
|
||||
- span 付き diagnostic の精度向上
|
||||
|
||||
ただし、Decodal の制約検証は独立した type checking pass ではなく、`&` の合成時や materialize 時に行う。
|
||||
ただし、Decodal の制約検証は独立した type checking pass ではなく、`&` の合成時、`as` の適用時、materialize 時に行う。
|
||||
|
||||
## materialize
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ Core に入れる機能は、基本的に deterministic な value transformation
|
||||
- arithmetic / logical / comparison operators
|
||||
- array concat
|
||||
- object / constraint composition
|
||||
- asymmetric range refinement and homogeneous map constraints
|
||||
- default materialization
|
||||
- pure function evaluation
|
||||
- host supplied import evaluation
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
## 方針
|
||||
|
||||
初期処理系は AST interpreter として実装する。
|
||||
bytecode VM や JIT ではなく、AST を demand-driven に評価することで、遅延評価、循環参照、`default`、`&`、`//` の意味論を小さく実装する。
|
||||
bytecode VM や JIT ではなく、AST を demand-driven に評価することで、遅延評価、循環参照、`default`、`&`、`//`、`as` の意味論を小さく実装する。
|
||||
|
||||
## 構成
|
||||
|
||||
|
||||
@@ -124,6 +124,7 @@ constraint は concrete value とは別の型として扱う。
|
||||
Constraint =
|
||||
Type(PrimitiveType)
|
||||
ArrayItems(ThunkId)
|
||||
MapValues(ThunkId)
|
||||
Compare(Op, Literal)
|
||||
Regex(Pattern)
|
||||
BuiltinPredicate(Symbol)
|
||||
@@ -133,6 +134,9 @@ Constraint =
|
||||
`ArrayItems` は配列そのものの型と、すべての要素へ合成する schema thunk を表す。
|
||||
配列用の primitive type は持たず、抽象配列には必ず要素制約が必要である。
|
||||
|
||||
`MapValues` は object の key 集合を制限せず、すべての field value へ適用する schema thunk を表す。
|
||||
連想配列は materialize 後も `Data::Object` になり、別の data variant は持たない。
|
||||
|
||||
初期実装では、object の形は主に `Concrete(Object)` の field に `Abstract` を置くことで表現する。
|
||||
object 全体にかかる constraint は必要になった時点で追加する。
|
||||
|
||||
|
||||
@@ -26,8 +26,9 @@ Decodal は Deferred Constraint Data Language、略称 DCDL のプロジェク
|
||||
9. [Match](./language/expression/match.md)
|
||||
10. [Import](./language/expression/import.md)
|
||||
11. [Composition](./language/expression/composition.md)
|
||||
12. [Default](./language/expression/default.md)
|
||||
13. [String Interpolation](./language/expression/string-interpolation.md)
|
||||
12. [Range Refinement](./language/expression/ascription.md)
|
||||
13. [Default](./language/expression/default.md)
|
||||
14. [String Interpolation](./language/expression/string-interpolation.md)
|
||||
4. [Constraints and Defaults](./language/constraints-and-defaults.md)
|
||||
5. [Composition Operators](./language/operators.md)
|
||||
6. [Functions](./language/functions.md)
|
||||
|
||||
@@ -133,10 +133,25 @@ Names = [...String];
|
||||
PositiveInts = [...(Int & > 0)];
|
||||
```
|
||||
|
||||
複数の配列制約を `&` で合成した場合、各 concrete 要素へすべての要素制約を合成する。
|
||||
要素が object schema の場合は、その schema に含まれる default も各要素へ適用される。
|
||||
複数の配列制約を `&` で合成した場合、各 concrete 要素をすべての要素 range で絞り込む。
|
||||
要素が object range の場合、右辺にしかない field は default の有無にかかわらず abstract のまま各要素へ残る。
|
||||
左辺にしかない field は右辺の field domain 外なのでエラーになる。
|
||||
要素制約のない `Array` primitive type は存在しない。
|
||||
|
||||
## 連想配列制約
|
||||
|
||||
連想配列制約は `{...T}` と書き、object の任意の field value を `T` に対して絞り込む。
|
||||
|
||||
```dcdl
|
||||
Services = {...{
|
||||
port = Int;
|
||||
enabled = Bool default true;
|
||||
}};
|
||||
```
|
||||
|
||||
key は schema で列挙せず、空 object も許容する。
|
||||
固定 object field と任意 key の value constraint を混在させる構文は現在サポートしない。
|
||||
|
||||
## default
|
||||
|
||||
`default` は制約ではない。
|
||||
|
||||
@@ -39,15 +39,32 @@ Services = [...{
|
||||
port = Int default 8080;
|
||||
}];
|
||||
|
||||
Services & [
|
||||
[
|
||||
{ name = "api"; },
|
||||
{ name = "worker"; port = 9000; },
|
||||
]
|
||||
] as Services
|
||||
```
|
||||
|
||||
抽象配列には要素制約が必須である。
|
||||
この例では、1 番目の要素の `port` は `8080` に materialize される。
|
||||
|
||||
## 連想配列と範囲絞り込み
|
||||
|
||||
```dcdl
|
||||
Service = {
|
||||
port = Int;
|
||||
enabled = Bool default true;
|
||||
};
|
||||
|
||||
services = {
|
||||
api = { port = 8080; };
|
||||
worker = { port = 8081; enabled = false; };
|
||||
} as {...Service};
|
||||
```
|
||||
|
||||
`api` と `worker` は任意の key であり、それぞれの value は `Service` より狭い範囲へ絞り込まれる。
|
||||
`as` の結果では `api.enabled` は abstract のまま残り、最終的に結果全体を materialize した時点で default の `true` が使われる。
|
||||
|
||||
## 関数と制約
|
||||
|
||||
```dcdl
|
||||
|
||||
@@ -30,8 +30,9 @@ Ports = [...(Int & >= 1 & <= 65535)];
|
||||
[...String] & ["api", "worker"]
|
||||
```
|
||||
|
||||
要素制約は object schema にもできる。
|
||||
要素 schema の default は、配列へ制約を合成するときに各要素へ適用される。
|
||||
要素制約は object range にもできる。
|
||||
右辺だけにある default 付き field は、配列へ制約を合成した時点では abstract のまま各要素に残る。
|
||||
その配列を後から materialize した場合にだけ default が使われる。
|
||||
|
||||
```dcdl
|
||||
Services = [...{
|
||||
@@ -42,6 +43,9 @@ Services = [...{
|
||||
Services & [{ name = "api"; }]
|
||||
```
|
||||
|
||||
配列制約を concrete array に適用すると、各要素は要素 range に対して `as` と同じ規則で絞り込まれる。
|
||||
object の要素 range では左辺にしかない field がエラーになり、右辺にしかない field は abstract のまま残る。
|
||||
|
||||
要素制約のない抽象配列型は提供しない。
|
||||
旧来の `Array` primitive type は使用できず、`[...T]` の `T` は必須である。
|
||||
`[String]` は配列制約ではなく、未解決の `String` 制約を 1 要素に持つ concrete array になる。
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
# Range Refinement
|
||||
|
||||
`narrower as wider` は、左辺が右辺より具体的で狭い範囲であることを確認し、両者を非対称に合成する演算である。
|
||||
|
||||
```dcdl
|
||||
Int & > 10 as Int & > 0
|
||||
```
|
||||
|
||||
この例は成功し、結果は左辺の狭い範囲 `Int & > 10` のままになる。逆向きの `Int as Int & > 0` は、左辺が右辺を満たすとは限らないため失敗する。
|
||||
|
||||
## Object
|
||||
|
||||
object では、右辺を field domain として左辺の field を確認する。
|
||||
|
||||
- 左辺にしかない field は、右辺の domain 外なのでエラーになる。
|
||||
- 両側にある field は、左辺が右辺より狭いかを再帰的に確認し、左辺の狭い結果を使う。
|
||||
- 右辺にしかない field は、default の有無に関係なく未評価のまま結果へ残す。
|
||||
- 結果の field order は右辺の順序に従う。
|
||||
|
||||
```dcdl
|
||||
partial = {
|
||||
port = 8080;
|
||||
} as {
|
||||
host = String;
|
||||
port = Int;
|
||||
enabled = Bool default true;
|
||||
};
|
||||
```
|
||||
|
||||
`partial.port` は `8080` に具体化される。`partial.host` と `partial.enabled` は右辺由来の abstract field のままであり、`as` は `enabled` の default を選択も force もしない。
|
||||
|
||||
その後 `partial` 全体を materialize すれば、通常の materialize 規則が適用される。この例では unresolved な `host` がエラーになり、`host` も具体化されていれば `enabled` の default がその時点で利用される。
|
||||
|
||||
## Default
|
||||
|
||||
default は範囲包含の根拠ではない。両側に同じ field がある場合、結果には左辺を使うため、右辺の default を左辺へ注入しない。
|
||||
|
||||
```dcdl
|
||||
Int & > 0 as (Int default 1)
|
||||
```
|
||||
|
||||
結果は default のない `Int & > 0` である。一方、右辺だけに残る object field は field 全体を保持するため、その abstract value が元から持つ default も保持される。
|
||||
|
||||
## Map and array ranges
|
||||
|
||||
`{...T}` は任意の object key を許可し、各 value が `T` より狭いことを確認する。
|
||||
|
||||
```dcdl
|
||||
ports = {
|
||||
http = 80;
|
||||
https = 443;
|
||||
} as {...(Int & >= 1 & <= 65535)};
|
||||
```
|
||||
|
||||
`[...T]` を右辺に使う場合も、すべての array element を `T` に対して絞り込む。
|
||||
|
||||
## Concrete right-hand ranges
|
||||
|
||||
primitive constraint や合成 constraint は通常どおり値を検証する。
|
||||
右辺が concrete scalar または array literal の場合は、左辺も同じ値または同じ長さ・要素構造である必要がある。
|
||||
function は右辺の範囲として使用できない。
|
||||
|
||||
左辺は concrete value に限らない。処理系が包含を確認できる constraint 同士であれば abstract value も使用できる。primitive type、numeric bound、同一 regex / predicate、array/map の要素範囲は包含確認の対象になる。
|
||||
|
||||
関数 parameter の `name: range` も、引数が force された時点で `as` と同じ絞り込み規則を使う。
|
||||
|
||||
## Precedence
|
||||
|
||||
`as` は `default` より低い、最も低い優先順位を持ち、左結合である。
|
||||
|
||||
```dcdl
|
||||
narrow & overrides as Wider
|
||||
```
|
||||
|
||||
これは `(narrow & overrides) as Wider` と解釈される。
|
||||
@@ -11,6 +11,9 @@ Port = Int & >= 1 & <= 65535;
|
||||
Config = MyConfig & { port = 8000; };
|
||||
```
|
||||
|
||||
object 同士では片側だけにある field も保持するため、`&` は方向を持たない。
|
||||
左辺が右辺より狭いことを確認し、右辺を field domain として合成したい場合は [`as`](./ascription.md) を使う。
|
||||
|
||||
## `//`
|
||||
|
||||
`//` は右辺優先の構造的 patch を行う。
|
||||
|
||||
@@ -10,6 +10,8 @@ increment(41)
|
||||
|
||||
引数は thunk として渡せる。
|
||||
関数本体内で引数が参照されたときに評価する。
|
||||
parameter に range が指定されている場合、引数は `narrower as wider` と同じ規則で絞り込まれる。
|
||||
parameter 側だけにある field は abstract のまま残り、default はこの時点では選択されない。
|
||||
|
||||
関数呼び出し結果そのものはグローバルには memoize しない。
|
||||
フィールドに束縛された呼び出し結果は、そのフィールド thunk の評価結果として memoize される。
|
||||
|
||||
@@ -10,6 +10,7 @@ Expr
|
||||
├─ identifier
|
||||
├─ path reference
|
||||
├─ object
|
||||
├─ map constraint
|
||||
├─ array
|
||||
├─ array constraint
|
||||
├─ function
|
||||
@@ -18,6 +19,7 @@ Expr
|
||||
├─ match
|
||||
├─ import
|
||||
├─ composition
|
||||
├─ range refinement (`as`)
|
||||
├─ default
|
||||
└─ string interpolation
|
||||
```
|
||||
|
||||
@@ -37,3 +37,30 @@ MyConfig = {
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Map constraint
|
||||
|
||||
連想配列の制約は、object の任意の field value に同じ schema を適用する。
|
||||
|
||||
```dcdl
|
||||
Services = {...{
|
||||
port = Int;
|
||||
enabled = Bool default true;
|
||||
}};
|
||||
```
|
||||
|
||||
`{...T}` は key の集合を固定せず、すべての value が `T` を満たす object を表す。
|
||||
空 object も許容される。runtime と materialize 後の表現は通常の object と共通であり、別の map value variant は持たない。
|
||||
|
||||
```dcdl
|
||||
services = {
|
||||
api = { port = 8080; };
|
||||
worker = { port = 8081; enabled = false; };
|
||||
} as Services;
|
||||
```
|
||||
|
||||
各 entry は `as` によって右辺の field domain 内へ絞り込まれるため、左辺に `port` や `enabled` 以外の field があればエラーになる。
|
||||
右辺にしかない field は default の有無にかかわらず abstract のまま残る。
|
||||
host から渡した object は識別子構文に収まらない文字列 key も保持できるが、DCDL source の object field name は通常の識別子に限られる。
|
||||
|
||||
固定 field と任意 key を一つの object schema に混在させる rest-field 構文は、現在サポートしない。
|
||||
|
||||
@@ -43,6 +43,7 @@ in
|
||||
- 関数はレキシカルスコープを持つ。
|
||||
- 関数は定義時の環境を参照として保持する。
|
||||
- 引数は thunk として渡され、必要になるまで評価されない。
|
||||
- parameter range がある引数は、force 時に `as` と同じ範囲包含・絞り込み規則で合成される。
|
||||
- 関数呼び出し結果そのものはグローバルには memoize しない。
|
||||
- フィールドに束縛された関数呼び出し結果は、そのフィールド thunk の評価結果として memoize される。
|
||||
- 再帰的な依存は thunk cycle として diagnostic になる。
|
||||
|
||||
@@ -35,8 +35,9 @@ module = { statement } ;
|
||||
statement = field_definition , [ ";" ]
|
||||
| expression , [ ";" ] ;
|
||||
|
||||
expression = default_expression ;
|
||||
expression = as_expression ;
|
||||
|
||||
as_expression = default_expression , { "as" , default_expression } ;
|
||||
default_expression = patch_expression , [ "default" , default_expression ] ;
|
||||
patch_expression = compose_expression , { "//" , compose_expression } ;
|
||||
compose_expression = logical_or_expression , { "&" , logical_or_expression } ;
|
||||
@@ -56,6 +57,7 @@ path_suffix = "." , identifier ;
|
||||
primary_expression = literal
|
||||
| identifier
|
||||
| comparison_constraint
|
||||
| map_constraint
|
||||
| object
|
||||
| array_constraint
|
||||
| array
|
||||
@@ -70,6 +72,7 @@ comparison_operator = "==" | "!=" | "<" | "<=" | ">" | ">=" ;
|
||||
comparison_constraint = ( "<" | "<=" | ">" | ">=" ) , expression ;
|
||||
|
||||
object = "{" , [ field_definition , { ";" , field_definition } , [ ";" ] ] , "}" ;
|
||||
map_constraint = "{" , "..." , expression , "}" ;
|
||||
field_definition = field_path , "=" , expression ;
|
||||
field_path = identifier , { "." , identifier } ;
|
||||
|
||||
@@ -104,6 +107,7 @@ Precedence is highest first.
|
||||
9. `&`
|
||||
10. `//`
|
||||
11. `default`
|
||||
12. `as`
|
||||
|
||||
Binary operators are left-associative except `default`, which is right-associative.
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
| `&` | `lhs & rhs` | composition | value / constraint / object | constraint-preserving composition |
|
||||
| `//` | `lhs // rhs` | patch | object / value | right-biased structural patch |
|
||||
| `default` | `base default fallback` | default | abstract value | materialization fallback |
|
||||
| `as` | `narrower as wider` | range refinement | value / constraint / structure | narrower result plus untouched right-only ranges |
|
||||
|
||||
`concrete scalar` は `String`、`Bool`、`Int`、`Float` を指す。
|
||||
|
||||
@@ -48,6 +49,7 @@
|
||||
9. `&`
|
||||
10. `//`
|
||||
11. `default`
|
||||
12. `as`
|
||||
|
||||
同じ優先順位の二項演算子は左結合である。
|
||||
`default` は右結合である。
|
||||
@@ -91,6 +93,7 @@ A & B
|
||||
- 両方が異なる具体値なら conflict になる。
|
||||
- 両方が object なら、フィールドごとに合成する。
|
||||
- 同じフィールドが両方にある場合、そのフィールド値を `&` で合成する。
|
||||
- 片方にしかないフィールドは、そのまま結果に保持する。
|
||||
- 矛盾が発生した場合はエラーになる。
|
||||
|
||||
例:
|
||||
@@ -188,12 +191,44 @@ object field 全体を特別に置き換えるための `replace(...)` 構文や
|
||||
|
||||
object 全体を別構造にしたい場合は、patch 対象より外側で値を作り直す。
|
||||
|
||||
## `&` と `//` の使い分け
|
||||
## `as`: range refinement
|
||||
|
||||
`&` は制約を満たす具体化に使う。
|
||||
`as` は左辺が右辺より具体的で狭い範囲であることを確認する、非対称な絞り込み演算子である。
|
||||
|
||||
```dcdl
|
||||
ValidConfig = MyConfig & {
|
||||
Refined = {
|
||||
port = 8000;
|
||||
} as {
|
||||
port = Int & >= 1 & <= 65535;
|
||||
host = String;
|
||||
enabled = Bool default true;
|
||||
};
|
||||
```
|
||||
|
||||
`port` は左辺の `8000` に具体化される。
|
||||
右辺にしかない `host` と `enabled` は abstract のまま結果へ残る。default の有無は、右辺だけの field を保持するかどうかに影響しない。
|
||||
`as` 自体は default を選択せず、後から結果を materialize した場合だけ通常の default 規則が働く。
|
||||
|
||||
左辺にしかない object field は右辺の field domain 外なのでエラーになる。
|
||||
両側にある nested object、array constraint、map constraint は同じ規則で再帰的に絞り込む。
|
||||
|
||||
abstract range 同士も包含を確認できる。
|
||||
|
||||
```dcdl
|
||||
Int & > 10 as Int & > 0 # 成功し、Int & > 10 を返す
|
||||
Int as Int & > 0 # 失敗
|
||||
```
|
||||
|
||||
`&` は対称な合成であり、片方だけにある object field を保持する。
|
||||
したがって、左右に方向を持つ絞り込みを `&` で代用しない。
|
||||
詳細は [Range Refinement](./expression/ascription.md) を参照する。
|
||||
|
||||
## `&`、`//`、`as` の使い分け
|
||||
|
||||
`&` は制約や部分構造を失わず、対称に合成する。
|
||||
|
||||
```dcdl
|
||||
Combined = MyConfig & {
|
||||
port = 8000;
|
||||
};
|
||||
```
|
||||
@@ -208,3 +243,9 @@ ModifiedSchema = MyConfig // {
|
||||
|
||||
`//` は右辺優先の patch であり、左辺の制約を常に保持するとは限らない。
|
||||
制約を保持したい場合は `&` を使う。
|
||||
|
||||
左辺が右辺より狭いことを検証しながら合成する場合は `as` を使う。
|
||||
|
||||
```dcdl
|
||||
RefinedConfig = NarrowConfig as WideConfig;
|
||||
```
|
||||
|
||||
@@ -103,6 +103,7 @@ in
|
||||
match
|
||||
import
|
||||
default
|
||||
as
|
||||
true
|
||||
false
|
||||
```
|
||||
@@ -119,9 +120,10 @@ false
|
||||
& 制約合成
|
||||
// patch 合成
|
||||
default fallback 指定
|
||||
as 左辺から右辺への範囲包含確認と絞り込み
|
||||
=> 関数
|
||||
. フィールド参照 / ドットパス定義
|
||||
... 配列の要素制約
|
||||
... 配列または連想配列の値制約
|
||||
```
|
||||
|
||||
演算子の優先順位は [合成演算子](./operators.md) で定義する。
|
||||
|
||||
@@ -5,7 +5,12 @@ Statement {
|
||||
Expression Semicolon?
|
||||
}
|
||||
|
||||
Expression { DefaultExpression }
|
||||
Expression { AsExpression }
|
||||
|
||||
AsExpression {
|
||||
DefaultExpression |
|
||||
AsExpression !as As DefaultExpression
|
||||
}
|
||||
|
||||
DefaultExpression {
|
||||
PatchExpression |
|
||||
@@ -70,6 +75,7 @@ PrimaryExpression {
|
||||
Literal |
|
||||
Identifier |
|
||||
ComparisonConstraint |
|
||||
MapConstraint |
|
||||
Object |
|
||||
ArrayConstraint |
|
||||
Array |
|
||||
@@ -85,6 +91,7 @@ CompareOperator { EqualEqual | BangEqual | Lt | Lte | Gt | Gte }
|
||||
ComparisonConstraint { (Lt | Lte | Gt | Gte) Expression }
|
||||
|
||||
Object { LBrace (FieldDefinition (Semicolon FieldDefinition)* Semicolon?)? RBrace }
|
||||
MapConstraint { LBrace Ellipsis Expression RBrace }
|
||||
FieldDefinition { FieldPath Equal Expression }
|
||||
FieldPath { Identifier !fieldPath (Dot Identifier)* }
|
||||
|
||||
@@ -104,8 +111,11 @@ Pattern { Underscore | Expression }
|
||||
|
||||
ImportExpression { Import String }
|
||||
|
||||
As { @specialize<Identifier, "as"> }
|
||||
|
||||
@precedence {
|
||||
fieldPath @left,
|
||||
as @left,
|
||||
default @right,
|
||||
patch @left,
|
||||
compose @left,
|
||||
|
||||
@@ -182,3 +182,31 @@ Array constraints
|
||||
left: (identifier)
|
||||
right: (comparison_constraint
|
||||
value: (integer))))))))
|
||||
|
||||
==================
|
||||
Map constraint and ascription
|
||||
==================
|
||||
{
|
||||
services = {
|
||||
api = { port = 8080; };
|
||||
} as {...{ port = Int; }};
|
||||
}
|
||||
---
|
||||
|
||||
(source_file
|
||||
(object
|
||||
(field_definition
|
||||
path: (field_path (identifier))
|
||||
value: (as_expression
|
||||
narrower: (object
|
||||
(field_definition
|
||||
path: (field_path (identifier))
|
||||
value: (object
|
||||
(field_definition
|
||||
path: (field_path (identifier))
|
||||
value: (literal (integer))))))
|
||||
wider: (map_constraint
|
||||
value: (object
|
||||
(field_definition
|
||||
path: (field_path (identifier))
|
||||
value: (identifier))))))))
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// doc/manual/souce/language/grammar.md.
|
||||
|
||||
const PREC = {
|
||||
AS: 0,
|
||||
DEFAULT: 1,
|
||||
PATCH: 2,
|
||||
COMPOSE: 3,
|
||||
@@ -53,6 +54,7 @@ module.exports = grammar({
|
||||
$.identifier,
|
||||
$.regex_literal,
|
||||
$.comparison_constraint,
|
||||
$.map_constraint,
|
||||
$.object,
|
||||
$.array_constraint,
|
||||
$.array,
|
||||
@@ -66,6 +68,7 @@ module.exports = grammar({
|
||||
$.unary_expression,
|
||||
$.binary_expression,
|
||||
$.default_expression,
|
||||
$.as_expression,
|
||||
),
|
||||
|
||||
literal: $ => choice(
|
||||
@@ -100,6 +103,13 @@ module.exports = grammar({
|
||||
'}',
|
||||
),
|
||||
|
||||
map_constraint: $ => seq(
|
||||
'{',
|
||||
'...',
|
||||
field('value', $._expression),
|
||||
'}',
|
||||
),
|
||||
|
||||
field_definition: $ => seq(
|
||||
field('path', $.field_path),
|
||||
'=',
|
||||
@@ -125,12 +135,12 @@ module.exports = grammar({
|
||||
']',
|
||||
),
|
||||
|
||||
let_expression: $ => seq(
|
||||
let_expression: $ => prec.right(seq(
|
||||
'let',
|
||||
repeat(seq($.field_definition, ';')),
|
||||
'in',
|
||||
field('body', $._expression),
|
||||
),
|
||||
)),
|
||||
|
||||
function_expression: $ => prec.right(seq(
|
||||
'(',
|
||||
@@ -237,5 +247,11 @@ module.exports = grammar({
|
||||
'default',
|
||||
field('fallback', $._expression),
|
||||
)),
|
||||
|
||||
as_expression: $ => prec.left(PREC.AS, seq(
|
||||
field('narrower', $._expression),
|
||||
'as',
|
||||
field('wider', $._expression),
|
||||
)),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"match"
|
||||
"import"
|
||||
"default"
|
||||
"as"
|
||||
] @keyword
|
||||
|
||||
[
|
||||
|
||||
+66
@@ -91,6 +91,10 @@
|
||||
"type": "SYMBOL",
|
||||
"name": "comparison_constraint"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "map_constraint"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "object"
|
||||
@@ -142,6 +146,10 @@
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "default_expression"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "as_expression"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -319,6 +327,31 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"map_constraint": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "{"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "..."
|
||||
},
|
||||
{
|
||||
"type": "FIELD",
|
||||
"name": "value",
|
||||
"content": {
|
||||
"type": "SYMBOL",
|
||||
"name": "_expression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"field_definition": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
@@ -469,6 +502,9 @@
|
||||
]
|
||||
},
|
||||
"let_expression": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
@@ -504,6 +540,7 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"function_expression": {
|
||||
"type": "PREC_RIGHT",
|
||||
@@ -1298,6 +1335,35 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"as_expression": {
|
||||
"type": "PREC_LEFT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "FIELD",
|
||||
"name": "narrower",
|
||||
"content": {
|
||||
"type": "SYMBOL",
|
||||
"name": "_expression"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "as"
|
||||
},
|
||||
{
|
||||
"type": "FIELD",
|
||||
"name": "wider",
|
||||
"content": {
|
||||
"type": "SYMBOL",
|
||||
"name": "_expression"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"extras": [
|
||||
|
||||
+424
-2
@@ -15,6 +15,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -51,6 +55,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -94,6 +102,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -130,6 +142,180 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "parenthesized_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "path_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "regex_literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "unary_expression",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true,
|
||||
"fields": {
|
||||
"narrower": {
|
||||
"multiple": false,
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "array",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "call_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "comparison_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "default_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "function_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "identifier",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "import_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "let_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "parenthesized_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "path_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "regex_literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "unary_expression",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"wider": {
|
||||
"multiple": false,
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "array",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "call_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "comparison_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "default_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "function_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "identifier",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "import_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "let_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -174,6 +360,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -210,6 +400,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -314,6 +508,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -350,6 +548,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -399,6 +601,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -435,6 +641,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -474,6 +684,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -510,6 +724,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -575,6 +793,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -611,6 +833,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -655,6 +881,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -691,6 +921,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -729,6 +963,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -765,6 +1003,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -819,6 +1061,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -855,6 +1101,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -914,6 +1164,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -950,6 +1204,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -1020,6 +1278,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -1056,6 +1318,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -1122,10 +1388,10 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "match_arm",
|
||||
"type": "map_constraint",
|
||||
"named": true,
|
||||
"fields": {
|
||||
"body": {
|
||||
"value": {
|
||||
"multiple": false,
|
||||
"required": true,
|
||||
"types": [
|
||||
@@ -1137,6 +1403,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -1173,6 +1443,98 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "parenthesized_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "path_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "regex_literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "unary_expression",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "match_arm",
|
||||
"named": true,
|
||||
"fields": {
|
||||
"body": {
|
||||
"multiple": false,
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "array",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "call_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "comparison_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "default_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "function_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "identifier",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "import_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "let_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -1215,6 +1577,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -1251,6 +1617,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -1295,6 +1665,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -1331,6 +1705,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -1400,6 +1778,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -1436,6 +1818,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -1490,6 +1876,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -1526,6 +1916,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -1579,6 +1973,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -1615,6 +2013,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -1659,6 +2061,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -1699,6 +2105,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -1742,6 +2152,10 @@
|
||||
"type": "array_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "as_expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_expression",
|
||||
"named": true
|
||||
@@ -1778,6 +2192,10 @@
|
||||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "map_constraint",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "match_expression",
|
||||
"named": true
|
||||
@@ -1928,6 +2346,10 @@
|
||||
"type": "_",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "as",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "comment",
|
||||
"named": true
|
||||
|
||||
Generated
+6764
-6735
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,15 @@
|
||||
let
|
||||
Service = {
|
||||
port = Int & >= 1 & <= 65535;
|
||||
enabled = Bool default true;
|
||||
};
|
||||
in
|
||||
{
|
||||
api = {
|
||||
port = 8080;
|
||||
};
|
||||
worker = {
|
||||
port = 8081;
|
||||
enabled = false;
|
||||
};
|
||||
} as {...Service}
|
||||
@@ -1,16 +1,18 @@
|
||||
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
||||
import {LRParser} from "npm:@lezer/lr@^1.4.10"
|
||||
const spec_Identifier = {__proto__:null,as:182}
|
||||
export const parser = LRParser.deserialize({
|
||||
version: 14,
|
||||
states: "8fQYQPOOO#nQPO'#CaOOQO'#Cr'#CrO$wQPO'#CyO&UQPO'#DOO&^QQO'#DXO&hQPO'#DYO&pQPO'#CqO$wQPO'#DeO&zQPO'#DjOOQO'#Cq'#CqOOQO'#Cp'#CpO'PQPO'#CoO$wQPO'#CoOOQO'#Cn'#CnO)iQPO'#CmO.[QPO'#ClO0`QPO'#CkOOQO'#Cj'#CjO2WQPO'#CiO3{QPO'#ChO5mQPO'#CgO7XQPO'#CfOOQO'#Ce'#CeO7cQPO'#C`O7hQPO'#C_OOQO'#D|'#D|QYQPOOO8{QPO'#D}O9QQPO,58{OOQO,59e,59eO9YQPO'#CaOOQO,59j,59jO9bQPO,59jO$wQPO,59nOOQO,59s,59sO9jQPO,59sO9rQPO'#EQO9wQPO'#D[O:PQPO,59tO:UQPO'#CqO:cQPO'#D`O:kQQO,59xO:pQPO,59xO:uQPO,59]O:zQPO,5:POOQO,5:U,5:UO;PQPO'#DlOOQO,59[,59[O;WQPO,59[OOQO,59Z,59ZO$wQPO,59YO$wQPO,59XO$wQPO,59WOOQO'#Dt'#DtO$wQPO,59VO$wQPO,59UO$wQPO,59TO$wQPO,59SO$wQPO,59RO$wQPO,59QO$wQPO,58zOOQO,58y,58yOOQO-E7z-E7zOOQO,5:i,5:iOOQO-E7{-E7{O;]QPO1G/UO;eQPO1G/UOOQO1G/U1G/UO;mQPO1G/YO;uQPO1G/_O;|QPO1G/_OOQO1G/_1G/_OOQO,5:l,5:lOOQO-E8O-E8OO$wQPO1G/`O$wQPO,59{O<UQPO,59zO<^QPO,59zO$wQPO1G/dO<fQQO1G/dOOQO1G.w1G.wO<kQPO1G/kO<uQPO'#DmOOQO,5:W,5:WO<}QPO,5:WOOQO1G.v1G.vOOQO1G.t1G.tO=SQPO1G.sO@jQPO1G.rOBUQPO1G.qOOQO1G.p1G.pOC|QPO1G.oOEqQPO1G.nOGTQPO1G.mOOQO1G.l1G.lOOQO1G.f1G.fOOQO1G.s1G.sOOQO1G.r1G.rOOQO1G.q1G.qOOQO1G.o1G.oOOQO1G.n1G.nOOQO1G.m1G.mOOQO,5:j,5:jOOQO7+$p7+$pOHqQPO7+$pOOQO-E7|-E7|OOQO7+$t7+$tOHyQPO7+$tOOQO,5:k,5:kOOQO7+$y7+$yOIOQPO7+$yOOQO-E7}-E7}OOQO7+$z7+$zOOQO1G/g1G/gOIVQPO'#DaOOQO,5:m,5:mOI[QPO1G/fOOQO-E8P-E8POOQO7+%O7+%OO$wQPO7+%OOOQO'#Dh'#DhOIdQPO'#DgOOQO7+%V7+%VOIiQPO7+%VOIqQPO,5:XOIxQPO,5:XOOQO1G/r1G/rOOQO<<H[<<H[PJQQPO'#EOOOQO<<H`<<H`OOQO<<He<<HeP$wQPO'#EPPJVQPO'#EROOQO<<Hj<<HjO$wQPO,5:ROJ[QPO<<HqOJfQPO<<HqOOQO<<Hq<<HqOJnQPO1G/sOOQO1G/m1G/mOOQO,5:n,5:nOOQOAN>]AN>]OJuQPOAN>]OOQO-E8Q-E8QOOQOG23wG23wP<nQPO'#ESO$wQPO,59XO$wQPO,59WO$wQPO,59VO$wQPO,59TO$wQPO,59SO$wQPO,59ROKPQPO1G.rOKgQPO'#ClOKzQPO'#CkOLnQPO'#ChOMnQPO'#CgONqQPO'#CfO$wQPO,59WO$wQPO,59UO$wQPO,59QO! zQPO1G.qO!!bQPO'#CkO!#oQPO'#CiO$wQPO,59VO$wQPO,59UO$wQPO,59TO$wQPO,59SO$wQPO,59RO$wQPO,59QO$wQPO,58zO!$lQPO1G.oO!%SQPO1G.nO!%jQPO1G.mO!&[QPO'#CiO!'SQPO'#ChO!'wQPO'#CgO!(iQPO'#CfO!)WQPO'#C`",
|
||||
stateData: "!)j~O!yOSPOS~OUPOgQOhQOiQOjQOkQOlQOnROoROpROqROsSOwTO}UO!RVO!YWO!_XO!b]O!c]O~OneXoeXpeXqeX!ReX!ceX!deX!eeX!feX!geX!ieX!jeX!keX!leX!meX!neX!oeX~OVlOUeXWTXgeXheXieXjeXkeXleXseXteXweX}eX!YeX!_eX!beX!weX~P!gOUYOgQOhQOiQOjQOkQOlQOnROoROpROqROsSOwTO}UO!RVO!YWO!_XO!b]O!c]O~OUoOupO~OxrOzsO~P$wOUoO!P!OP~OUxO!VzO~P]Og!OO~OV!RO!R!POUcXgcXhcXicXjcXkcXlcXncXocXpcXqcXscXtcXwcX}cX!YcX!_cX!bcX!ccX!dcX!ecX!fcX!gcX!icX!jcX!kcX!lcX!mcX!ncX!ocX!wcXycXzcX!VcXucX!UcX~O!d!TO!e!TOUaXgaXhaXiaXjaXkaXlaXnaXoaXpaXqaXsaXtaXwaX}aX!RaX!YaX!_aX!baX!caX!faX!gaX!iaX!jaX!kaX!laX!maX!naX!oaX!waXVaXyaXzaX!VaXuaX!UaX~OU`Xg`Xh`Xi`Xj`Xk`Xl`Xn`Xo`Xp`Xq`Xs`Xt`Xw`X}`X!R`X!Y`X!_`X!b`X!g`X!i`X!j`X!k`X!l`X!m`X!n`X!o`X!w`Xy`Xz`X!V`Xu`X!U`X~O!c!UO!f!UO~P,ROn!WOo!WOp!WOq!WO!i!WO!j!WOU_Xg_Xh_Xi_Xj_Xk_Xl_Xs_Xt_Xw_X}_X!R_X!Y_X!__X!b_X!c_X!k_X!l_X!m_X!n_X!o_X!w_X~O!g!VO~P.fOU]Xg]Xh]Xi]Xj]Xk]Xl]Xn]Xo]Xp]Xq]Xs]Xt]Xw]X}]X!R]X!Y]X!_]X!b]X!c]X!l]X!m]X!n]X!o]X!w]X~O!k!YO~P0gOU[Xg[Xh[Xi[Xj[Xk[Xl[Xn[Xo[Xp[Xq[Xs[Xt[Xw[X}[X!R[X!Y[X!_[X!b[X!c[X!m[X!n[X!o[X!w[X~O!l!ZO~P2_OUZXgZXhZXiZXjZXkZXlZXnZXoZXpZXqZXsZXtZXwZX}ZX!RZX!YZX!_ZX!bZX!cZX!nZX!oZX!wZX~O!m![O~P4SOUYXgYXhYXiYXjYXkYXlYXnYXoYXpYXqYXsYXtYXwYX}YX!RYX!YYX!_YX!bYX!cYX!wYX~O!n!]O!o!^O~P5tOW!_O~Ot!`OURXgRXhRXiRXjRXkRXlRXnRXoRXpRXqRXsRXwRX}RX!RRX!YRX!_RX!bRX!cRX!wRX~OU!bO~OVlOWTa~OVlOWTX~Ot!dOu!fO~Oy!hOz!jO~Ot!kO~OUoO!P!OX~O!P!mO~O!U!nOVeX!VeX~P!gOy!oO!V!SX~O!W!qO~O!V!rO~O!V!sO~Os!tO~O!V!vO~P$wOU!xO~OUoOu#[O~Ot#]Ou#[O~Oy#`Oz#_O~Oz#bO~P$wOy#cOz#bO~OU#gO!V!Sa~Oy#iO!V!Sa~O!W#lO~Ou#oO!]#mO~P$wOy#qO!V!aX~O!V#sO~O!d!TO!e!TOUaigaihaiiaijaikailainaioaipaiqaisaitaiwai}ai!Rai!Yai!_ai!bai!cai!fai!gai!iai!jai!kai!lai!mai!nai!oai!waiyaizai!Vaiuai!Uai~O!f!UOn`io`ip`iq`is`it`i!g`i!i`i!j`i!k`i!l`i!m`i!n`i!o`i~OU`ig`ih`ii`ij`ik`il`iw`i}`i!R`i!Y`i!_`i!b`i!c`i!w`i~P?iOs_it_i!k_i!l_i!m_i!n_i!o_i~O!g!VOU_ig_ih_ii_ij_ik_il_in_io_ip_iq_iw_i}_i!R_i!Y_i!__i!b_i!c_i!w_i~PAmOs]it]i!l]i!m]i!n]i!o]i~O!k!YOU]ig]ih]ii]ij]ik]il]in]io]ip]iq]iw]i}]i!R]i!Y]i!_]i!b]i!c]i!w]i~PChOs[it[i!m[i!n[i!o[i~O!l!ZOU[ig[ih[ii[ij[ik[il[in[io[ip[iq[iw[i}[i!R[i!Y[i!_[i!b[i!c[i!w[i~PE`O!m![OUZigZihZiiZijZikZilZinZioZipZiqZisZitZiwZi}Zi!RZi!YZi!_Zi!bZi!cZi!nZi!oZi!wZi~OUoOu#tO~Oz#vO~Oz#wO~P$wO!U!nO~OU#gO!V!Si~O!U#{O~Ot#|Ou$OO~O!V!aa~P$wOy$PO!V!aa~OUoO~OU#gO~Ou$SO!]#mO~P$wOt$TOu$SO~O!V!ai~P$wOu$VO!]#mO~P$wO!c!UOy`iz`i!V`iu`i!U`i~P?iO!c$XO!f$XOV`X!d`X!e`X~P,RO!g$YOV_X!d_X!e_X!f_Xy_Xz_X!V_Xu_X!U_X~P.fO!l$[OV[X!d[X!e[X!f[X!g[X!i[X!j[X!k[Xy[Xz[X!V[Xu[X!U[X~P2_O!m$]OVZX!dZX!eZX!fZX!gZX!iZX!jZX!kZX!lZXyZXzZX!VZXuZX!UZX~P4SO!n$^O!o$gOVYX!dYX!eYX!fYX!gYX!iYX!jYX!kYX!lYX!mYXyYXzYX!VYXuYX!UYX~P5tO!g$eOy_iz_i!V_iu_i!U_i~PAmOn!WOo!WOp!WOq!WO!g$eO!i!WO!j!WOy_Xz_X!k_X!l_X!m_X!n_X!o_X!V_Xs_Xt_Xu_X!U_X~O!k$fOV]X!d]X!e]X!f]X!g]X!i]X!j]Xy]Xz]X!V]Xu]X!U]X~P0gO!k$lOy]iz]i!V]iu]i!U]i~PChO!l$mOy[iz[i!V[iu[i!U[i~PE`O!m$nOyZizZi!nZi!oZi!VZisZitZiuZi!UZi~O!k$lOy]Xz]X!l]X!m]X!n]X!o]X!V]Xs]Xt]Xu]X!U]X~O!l$mOy[Xz[X!m[X!n[X!o[X!V[Xs[Xt[Xu[X!U[X~O!m$nOyZXzZX!nZX!oZX!VZXsZXtZXuZX!UZX~O!n$oO!o$pOyYXzYX!VYXsYXtYXuYX!UYX~OW$qO~O}!P!Y!_!ojkih!]Uj~",
|
||||
goto: "4O!wPPP!x!|#^PPP#j$r%c&U'Q(P)R*O+W,a-h.q/v0{PPPPPP0{PPPP0{PPP0{PPPP0{0{P2QP0{P2T2WPPP0{P2`2hP0{P2n2qPPPPPP2tPPPPPPP2}3T3[3b3l3r3xTjOkSiOkQqSSuUvV#Z!d#]#uShOk]$ySUv!d#]#uSiOkQnRQtTQ|VQ}WQ!grQ!u!PS#S!_$qY#a!h#c#q#x$PQ#e!mQ#f!nQ#k!qW#m!t#|$T$WQ#z#lR$Q#{!QgORTVWkr!P!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$qV#R!^$g$pWfOk!^!_Y$dR!m!q#l$gu$xTVWr!P!h!n!t#c#q#x#{#|$P$T$W$p$qWeOk!^!_Q#Q!]Q#Y$^Y$cR!m!q#l$gQ$t$ou$wTVWr!P!h!n!t#c#q#x#{#|$P$T$W$p$qYdOk!]!^!_Q#P![Q#X$][$bR!m!q#l$^$gQ$s$nw$vTVWr!P!h!n!t#c#q#x#{#|$P$T$W$o$p$q[cOk![!]!^!_Q#O!ZQ#W$[^$jR!m!q#l$]$^$gQ$r$my$uTVWr!P!h!n!t#c#q#x#{#|$P$T$W$n$o$p$q!jbORTVWkr!P!Z![!]!^!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$[$]$^$g$m$n$o$p$qV!}!Y$f$l`aOk!Y!Z![!]!^!_Q!|!XQ#V$Zb$aR!m!q#l$[$]$^$f$gQ$h$k}$iTVWr!P!h!n!t#c#q#x#{#|$P$T$W$l$m$n$o$p$q!b`OTVWkr!P!X!Y!Z![!]!^!_!h!n!t#c#q#x#{#|$P$T$W$k$l$m$n$o$p$qQ!{!VQ#U$YQ$_$ee$`R!m!q#l$Z$[$]$^$f$g!|_ORTVWkr!P!V!X!Y!Z![!]!^!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$Y$Z$[$]$^$e$f$g$k$l$m$n$o$p$qQ!z!UR#T$X#Q^ORTVWkr!P!U!V!X!Y!Z![!]!^!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$X$Y$Z$[$]$^$e$f$g$k$l$m$n$o$p$qQ!S]R!y!T#V[ORTVW]kr!P!T!U!V!X!Y!Z![!]!^!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$X$Y$Z$[$]$^$e$f$g$k$l$m$n$o$p$q#VZORTVW]kr!P!T!U!V!X!Y!Z![!]!^!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$X$Y$Z$[$]$^$e$f$g$k$l$m$n$o$p$q#VYORTVW]kr!P!T!U!V!X!Y!Z![!]!^!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$X$Y$Z$[$]$^$e$f$g$k$l$m$n$o$p$qRwUR{VQyVV#h!o#i#yQ#p!tV$R#|$T$WX#n!t#|$T$WR!Q[R!w!PQ!XaQ$Z$aR$k$iQkOR!akSmPoR!cmQ!eqR#^!eQ!itS#d!i#rR#r!uQvUR!lvQ!pyR#j!pQ#}#pR$U#}",
|
||||
nodeNames: "⚠ Comment Source Statement FieldDefinition FieldPath Identifier Dot Equal Expression DefaultExpression PatchExpression ComposeExpression LogicalOrExpression LogicalAndExpression ComparisonExpression ConcatExpression AdditiveExpression MultiplicativeExpression UnaryExpression PostfixExpression PrimaryExpression Literal String Integer Float True False Regex ComparisonConstraint Lt Lte Gt Gte Object LBrace Semicolon RBrace ArrayConstraint LBracket Ellipsis Comma RBracket Array LetExpression Let FieldDefinitionList In FunctionExpression LParen ParameterList Parameter Colon RParen Arrow MatchExpression Match MatchArm Pattern Underscore ImportExpression Import CallSuffix ArgumentList Bang Minus Star Slash Plus PlusPlus CompareOperator EqualEqual BangEqual AmpAmp PipePipe Amp SlashSlash Default",
|
||||
maxTerm: 87,
|
||||
states: "9zQYQPOOO#qQPO'#CaOOQO'#Cs'#CsO$zQPO'#CzO&XQQO'#DTO&dQQO'#DZO&nQPO'#D[O&vQPO'#CrO$zQPO'#DgO'QQPO'#DlOOQO'#Cr'#CrOOQO'#Cq'#CqO'VQPO'#CpO$zQPO'#CpOOQO'#Co'#CoO)rQPO'#CnO.kQPO'#CmO0rQPO'#ClOOQO'#Ck'#CkO2mQPO'#CjO4eQPO'#CiO6YQPO'#ChO7wQPO'#CgOOQO'#Cf'#CfO8RQPO'#CeO9iQPO'#C`O9nQPO'#C_OOQO'#EP'#EPQYQPOOO;RQPO'#EQO;WQPO,58{OOQO,59f,59fO;`QPO'#CaO$zQPO,59kOOQO,59o,59oO;hQPO,59oO$zQPO,59qOOQO,59u,59uO;pQPO,59uO;xQPO'#ETO;}QPO'#D^O<VQPO,59vO<[QPO'#CrO<iQPO'#DbO<qQQO,59zO<vQPO,59zO<{QPO,59^O=QQPO,5:ROOQO,5:W,5:WO=VQPO'#DnOOQO,59],59]O=^QPO,59]OOQO,59[,59[O$zQPO,59ZO$zQPO,59YO$zQPO,59XOOQO'#Dv'#DvO$zQPO,59WO$zQPO,59VO$zQPO,59UO$zQPO,59TO$zQPO,59SO$zQPO,59ROOQO'#EO'#EOO$zQPO,59QO$zQPO,58zOOQO,58y,58yOOQO-E7}-E7}OOQO,5:l,5:lOOQO-E8O-E8OO=cQPO1G/VO=hQPO1G/ZO=pQPO1G/ZOOQO1G/Z1G/ZO=xQPO1G/]O>QQPO1G/aO>XQPO1G/aOOQO1G/a1G/aOOQO,5:o,5:oOOQO-E8R-E8RO$zQPO1G/bO$zQPO,59}O>aQPO,59|O>iQPO,59|O$zQPO1G/fO>qQQO1G/fOOQO1G.x1G.xO>vQPO1G/mO?QQPO'#DoOOQO,5:Y,5:YO?YQPO,5:YOOQO1G.w1G.wOOQO1G.u1G.uO?_QPO1G.tOB{QPO1G.sODjQPO1G.rOOQO1G.q1G.qOFeQPO1G.pOH]QPO1G.oOJQQPO1G.nOOQO1G.m1G.mOOQO1G.l1G.lOOQO1G.f1G.fOOQO1G.t1G.tOOQO1G.s1G.sOOQO1G.r1G.rOOQO1G.p1G.pOOQO1G.o1G.oOOQO1G.n1G.nOOQO7+$q7+$qOOQO,5:m,5:mOOQO7+$u7+$uOKdQPO7+$uOOQO-E8P-E8POOQO7+$w7+$wOKlQPO7+$wOOQO,5:n,5:nOOQO7+${7+${OKqQPO7+${OOQO-E8Q-E8QOOQO7+$|7+$|OOQO1G/i1G/iOKxQPO'#DcOOQO,5:p,5:pOK}QPO1G/hOOQO-E8S-E8SOOQO7+%Q7+%QO$zQPO7+%QOOQO'#Dj'#DjOLVQPO'#DiOOQO7+%X7+%XOL[QPO7+%XOLdQPO,5:ZOLkQPO,5:ZOOQO1G/t1G/tOOQO<<Ha<<HaPLsQPO'#EROOQO<<Hc<<HcOOQO<<Hg<<HgP$zQPO'#ESPLxQPO'#EUOOQO<<Hl<<HlO$zQPO,5:TOL}QPO<<HsOMXQPO<<HsOOQO<<Hs<<HsOMaQPO1G/uOOQO1G/o1G/oOOQO,5:q,5:qOOQOAN>_AN>_OMhQPOAN>_OOQO-E8T-E8TOOQOG23yG23yP>yQPO'#EVO$zQPO,59YO$zQPO,59XO$zQPO,59WO$zQPO,59UO$zQPO,59TO$zQPO,59SOMrQPO1G.sONYQPO'#CmONmQPO'#ClO! aQPO'#CiO!!aQPO'#ChO!#dQPO'#CgO$zQPO,59XO$zQPO,59VO$zQPO,59RO$zQPO,59QO!$mQPO1G.rO!%TQPO'#ClO!&eQPO'#CjO!'bQPO'#CeO$zQPO,59WO$zQPO,59VO$zQPO,59UO$zQPO,59TO$zQPO,59SO$zQPO,59RO$zQPO,59QO$zQPO,58zO!(kQPO1G.pO!)RQPO1G.oO!)iQPO1G.nO!*PQPO'#CjO!*zQPO'#CiO!+rQPO'#ChO!,gQPO'#CgO!-XQPO'#CeO!-sQPO'#C`",
|
||||
stateData: "!.V~O!|OSPOS~OUPOhQOiQOjQOkQOlQOmQOoROpROqROrROtSOzTO!PUO!TVO![WO!aXO!d]O!e]O~OofXpfXqfXrfX!TfX!efX!ffX!gfX!hfX!ifX!kfX!lfX!mfX!nfX!ofX!pfX!qfX!}fX~OVmOUfXWTXhfXifXjfXkfXlfXmfXtfXxfXzfX!PfX![fX!afX!dfX!zfX~P!gOUYOhQOiQOjQOkQOlQOmQOoROpROqROrROtSOzTO!PUO!TVO![WO!aXO!d]O!e]O~OUpOuqOvrO~OutO|uO~P$zOUpO!R!QP~OUzO!X|O~P]Oh!QO~OV!TO!T!ROUdXhdXidXjdXkdXldXmdXodXpdXqdXrdXtdXxdXzdX!PdX![dX!adX!ddX!edX!fdX!gdX!hdX!idX!kdX!ldX!mdX!ndX!odX!pdX!qdX!zdX!}dX{dX|dX!XdXvdX!WdX~O!f!VO!g!VOUbXhbXibXjbXkbXlbXmbXobXpbXqbXrbXtbXxbXzbX!PbX!TbX![bX!abX!dbX!ebX!hbX!ibX!kbX!lbX!mbX!nbX!obX!pbX!qbX!zbX!}bXVbX{bX|bX!XbXvbX!WbX~OUaXhaXiaXjaXkaXlaXmaXoaXpaXqaXraXtaXxaXzaX!PaX!TaX![aX!aaX!daX!iaX!kaX!laX!maX!naX!oaX!paX!qaX!zaX!}aX{aX|aX!XaXvaX!WaX~O!e!WO!h!WO~P,_Oo!YOp!YOq!YOr!YO!k!YO!l!YOU`Xh`Xi`Xj`Xk`Xl`Xm`Xt`Xx`Xz`X!P`X!T`X![`X!a`X!d`X!e`X!m`X!n`X!o`X!p`X!q`X!z`X!}`X~O!i!XO~P.uOU^Xh^Xi^Xj^Xk^Xl^Xm^Xo^Xp^Xq^Xr^Xt^Xx^Xz^X!P^X!T^X![^X!a^X!d^X!e^X!n^X!o^X!p^X!q^X!z^X!}^X~O!m![O~P0yOU]Xh]Xi]Xj]Xk]Xl]Xm]Xo]Xp]Xq]Xr]Xt]Xx]Xz]X!P]X!T]X![]X!a]X!d]X!e]X!o]X!p]X!q]X!z]X!}]X~O!n!]O~P2tOU[Xh[Xi[Xj[Xk[Xl[Xm[Xo[Xp[Xq[Xr[Xt[Xx[Xz[X!P[X!T[X![[X!a[X!d[X!e[X!p[X!q[X!z[X!}[X~O!o!^O~P4lOUZXhZXiZXjZXkZXlZXmZXoZXpZXqZXrZXtZXxZXzZX!PZX!TZX![ZX!aZX!dZX!eZX!zZX!}ZX~O!p!_O!q!`O~P6aO!}!aOUXXhXXiXXjXXkXXlXXmXXoXXpXXqXXrXXtXXxXXzXX!PXX!TXX![XX!aXX!dXX!eXX!zXX~OW!cO~Ox!dOURXhRXiRXjRXkRXlRXmRXoRXpRXqRXrRXtRXzRX!PRX!TRX![RX!aRX!dRX!eRX!zRX~OU!fO~OVmOWTa~OVmOWTX~Ov!kOx!iO~O{!mO|!oO~Ox!pO~OUpO!R!QX~O!R!rO~O!W!sOVfX!XfX~P!gO{!tO!X!UX~O!Y!vO~O!X!wO~O!X!xO~Ot!yO~O!X!{O~P$zOU!}O~Ov#aO~OUpOv#cO~Ov#cOx#dO~O{#gO|#fO~O|#iO~P$zO{#jO|#iO~OU#nO!X!Ua~O{#pO!X!Ua~O!Y#sO~Ov#vO!_#tO~P$zO{#xO!X!cX~O!X#zO~O!f!VO!g!VOUbihbiibijbikbilbimbiobipbiqbirbitbixbizbi!Pbi!Tbi![bi!abi!dbi!ebi!hbi!ibi!kbi!lbi!mbi!nbi!obi!pbi!qbi!zbi!}bi{bi|bi!Xbivbi!Wbi~O!h!WOoaipaiqairaitaixai!iai!kai!lai!mai!nai!oai!pai!qai!}ai~OUaihaiiaijaikailaimaizai!Pai!Tai![ai!aai!dai!eai!zai~PAwOt`ix`i!m`i!n`i!o`i!p`i!q`i!}`i~O!i!XOU`ih`ii`ij`ik`il`im`io`ip`iq`ir`iz`i!P`i!T`i![`i!a`i!d`i!e`i!z`i~PDOOt^ix^i!n^i!o^i!p^i!q^i!}^i~O!m![OU^ih^ii^ij^ik^il^im^io^ip^iq^ir^iz^i!P^i!T^i![^i!a^i!d^i!e^i!z^i~PE|Ot]ix]i!o]i!p]i!q]i!}]i~O!n!]OU]ih]ii]ij]ik]il]im]io]ip]iq]ir]iz]i!P]i!T]i![]i!a]i!d]i!e]i!z]i~PGwOt[ix[i!p[i!q[i!}[i~O!o!^OU[ih[ii[ij[ik[il[im[io[ip[iq[ir[iz[i!P[i!T[i![[i!a[i!d[i!e[i!z[i~PIoOUpOv#{O~O|#}O~O|$OO~P$zO!W!sO~OU#nO!X!Ui~O!W$SO~Ov$VOx$TO~O!X!ca~P$zO{$WO!X!ca~OUpO~OU#nO~Ov$ZO!_#tO~P$zOv$ZOx$[O~O!X!ci~P$zOv$^O!_#tO~P$zO!e!WO{ai|ai!Xaivai!Wai~PAwO!e$`O!h$`OVaX!faX!gaX~P,_O!i$aOV`X!f`X!g`X!h`X{`X|`X!X`Xv`X!W`X~P.uO!n$cOV]X!f]X!g]X!h]X!i]X!k]X!l]X!m]X{]X|]X!X]Xv]X!W]X~P2tO!o$dOV[X!f[X!g[X!h[X!i[X!k[X!l[X!m[X!n[X{[X|[X!X[Xv[X!W[X~P4lO!p$eO!q$nOVZX!fZX!gZX!hZX!iZX!kZX!lZX!mZX!nZX!oZX{ZX|ZX!XZXvZX!WZX~P6aO!i$lO{`i|`i!X`iv`i!W`i~PDOOo!YOp!YOq!YOr!YO!i$lO!k!YO!l!YO{`X|`X!m`X!n`X!o`X!p`X!q`X!}`X!X`Xt`Xv`Xx`X!W`X~O!m$mOV^X!f^X!g^X!h^X!i^X!k^X!l^X{^X|^X!X^Xv^X!W^X~P0yOVXX!fXX!gXX!hXX!iXX!kXX!lXX!mXX!nXX!oXX!pXX!qXX{XX|XX!XXXvXX!WXX~P8RO!m$uO{^i|^i!X^iv^i!W^i~PE|O!n$vO{]i|]i!X]iv]i!W]i~PGwO!o$wO{[i|[i!X[iv[i!W[i~PIoO!m$uO{^X|^X!n^X!o^X!p^X!q^X!}^X!X^Xt^Xv^Xx^X!W^X~O!n$vO{]X|]X!o]X!p]X!q]X!}]X!X]Xt]Xv]Xx]X!W]X~O!o$wO{[X|[X!p[X!q[X!}[X!X[Xt[Xv[Xx[X!W[X~O!p$xO!q$yO{ZX|ZX!}ZX!XZXtZXvZXxZX!WZX~O!}!aO{XX|XX!XXXtXXvXXxXX!WXX~OW${O~O!P!R![!a!qklji!_Uk~",
|
||||
goto: "6W!zPPP!{#P#aPPP#m$x%i&`'V(V)Y*`+a,m-z/V0d1m2vPPPPPP2vPPPP2vPPP2vP2vPPP2v2vP4PP2vP4S4VPPP2vP4_4gP2vP4m4pPPPPPP4sPPPPPPP4|5V5]5d5j5t5z6QTkOlSjOlQsSSwUxV#b!i#d#|SiOl]%USUx!i#d#|SjOlQoRQvTQ!OVQ!PWQ!hqQ!ltQ!z!RS#Y!c${Y#h!m#j#x$P$WQ#l!rQ#m!sQ#r!vW#t!y$T$[$_Q$R#sR$X$SUhOl!cW$sR!r!v#su%TTVWqt!R!m!s!y#j#x$P$S$T$W$[$_${!SgORTVWlqt!R!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_${U#W!`$n$yV#X!b$o$zYfOl!`!b!c[$kR!r!v#s$n$oy%STVWqt!R!m!s!y#j#x$P$S$T$W$[$_$y$z${YeOl!`!b!cQ#V!_Q#`$e[$jR!r!v#s$n$oQ%O$xy%RTVWqt!R!m!s!y#j#x$P$S$T$W$[$_$y$z${[dOl!_!`!b!cQ#U!^Q#_$d^$iR!r!v#s$e$n$oQ$}$w{%QTVWqt!R!m!s!y#j#x$P$S$T$W$[$_$x$y$z${^cOl!^!_!`!b!cQ#T!]Q#^$c`$rR!r!v#s$d$e$n$oQ$|$v}%PTVWqt!R!m!s!y#j#x$P$S$T$W$[$_$w$x$y$z${!rbORTVWlqt!R!]!^!_!`!b!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_$c$d$e$n$o$v$w$x$y$z${V#S![$m$ubaOl![!]!^!_!`!b!cQ#R!ZQ#]$bd$hR!r!v#s$c$d$e$m$n$oQ$p$t!R$qTVWqt!R!m!s!y#j#x$P$S$T$W$[$_$u$v$w$x$y$z${!h`OTVWlqt!R!Z![!]!^!_!`!b!c!m!s!y#j#x$P$S$T$W$[$_$t$u$v$w$x$y$z${Q#Q!XQ#[$aQ$f$lg$gR!r!v#s$b$c$d$e$m$n$o#U_ORTVWlqt!R!X!Z![!]!^!_!`!b!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_$a$b$c$d$e$l$m$n$o$t$u$v$w$x$y$z${Q#P!WR#Z$`#Y^ORTVWlqt!R!W!X!Z![!]!^!_!`!b!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_$`$a$b$c$d$e$l$m$n$o$t$u$v$w$x$y$z${Q!U]R#O!V#_[ORTVW]lqt!R!V!W!X!Z![!]!^!_!`!b!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_$`$a$b$c$d$e$l$m$n$o$t$u$v$w$x$y$z${#_ZORTVW]lqt!R!V!W!X!Z![!]!^!_!`!b!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_$`$a$b$c$d$e$l$m$n$o$t$u$v$w$x$y$z${#_YORTVW]lqt!R!V!W!X!Z![!]!^!_!`!b!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_$`$a$b$c$d$e$l$m$n$o$t$u$v$w$x$y$z${RyUR}VQ{VV#o!t#p$QQ#w!yV$Y$T$[$_X#u!y$T$[$_R!S[R!|!RQ!ZaQ$b$hR$t$qQ!bhQ$o$sR$z%TQlOR!elSnPpR!gnQ!jsR#e!jQ!nvS#k!n#yR#y!zQxUR!qxQ!u{R#q!uQ$U#wR$]$U",
|
||||
nodeNames: "⚠ Comment Source Statement FieldDefinition FieldPath Identifier Dot Equal Expression AsExpression DefaultExpression PatchExpression ComposeExpression LogicalOrExpression LogicalAndExpression ComparisonExpression ConcatExpression AdditiveExpression MultiplicativeExpression UnaryExpression PostfixExpression PrimaryExpression Literal String Integer Float True False Regex ComparisonConstraint Lt Lte Gt Gte MapConstraint LBrace Ellipsis RBrace Object Semicolon ArrayConstraint LBracket Comma RBracket Array LetExpression Let FieldDefinitionList In FunctionExpression LParen ParameterList Parameter Colon RParen Arrow MatchExpression Match MatchArm Pattern Underscore ImportExpression Import CallSuffix ArgumentList Bang Minus Star Slash Plus PlusPlus CompareOperator EqualEqual BangEqual AmpAmp PipePipe Amp SlashSlash Default As",
|
||||
maxTerm: 91,
|
||||
skippedNodes: [0,1],
|
||||
repeatNodeCount: 7,
|
||||
tokenData: "=c~R!PX^$Upq$Uqr$yrs%Wst&zvw'cxy'pyz'uz{'z{|(P|}(^}!O(c!O!P(h!P!Q({!Q![+c![!]+|!]!^,R!^!_,W!_!`,e!`!a,z!c!}-X!}#O-j#P#Q-o#R#S-t#T#W-X#W#X.X#X#Y-X#Y#Z1i#Z#]-X#]#^3y#^#`-X#`#a7]#a#b8p#b#h-X#h#i;Q#i#o-X#o#p<|#p#q=R#q#r=^#y#z$U$f$g$U#BY#BZ$U$IS$I_$U$I|$JO$U$JT$JU$U$KV$KW$U&FU&FV$U~$ZY!y~X^$Upq$U#y#z$U$f$g$U#BY#BZ$U$IS$I_$U$I|$JO$U$JT$JU$U$KV$KW$U&FU&FV$U~%OP!b~!_!`%R~%WO!j~~%ZWOY%WZr%Wrs%ss#O%W#O#P%x#P;'S%W;'S;=`&t<%lO%W~%xOg~~%{RO;'S%W;'S;=`&U;=`O%W~&XXOY%WZr%Wrs%ss#O%W#O#P%x#P;'S%W;'S;=`&t;=`<%l%W<%lO%W~&wP;=`<%l%W~'PSP~OY&zZ;'S&z;'S;=`']<%lO&z~'`P;=`<%l&z~'hP!m~vw'k~'pO!k~~'uO!R~~'zO!V~~(PO!d~~(UP!f~{|(X~(^O!g~~(cOy~~(hO!c~R(mPVP!O!P(pQ(sP!O!P(vQ({OxQ~)QW!e~OY)jZ!P)j!P!Q+^!Q#O)j#O#P*[#P;'S)j;'S;=`+W<%lO)j~)mWOY)jZ!P)j!P!Q*V!Q#O)j#O#P*[#P;'S)j;'S;=`+W<%lO)j~*[Ol~~*_RO;'S)j;'S;=`*h;=`O)j~*kXOY)jZ!P)j!P!Q*V!Q#O)j#O#P*[#P;'S)j;'S;=`+W;=`<%l)j<%lO)j~+ZP;=`<%l)j~+cO!n~~+hQh~!O!P+n!Q![+c~+qP!Q![+t~+yPi~!Q![+t~,RO!U~~,WOt~~,]Pn~!_!`,`~,eOo~~,jQWP!_!`,p!`!a,u~,uO!i~Q,zO!WQ~-PPp~!_!`-S~-XOq~~-^SU~!Q![-X!c!}-X#R#S-X#T#o-X~-oOw~~-tOz~~-{S!]~U~!Q![-X!c!}-X#R#S-X#T#o-X~.^UU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y.p#Y#o-X~.uUU~!Q![-X!c!}-X#R#S-X#T#Y-X#Y#Z/X#Z#o-X~/^TU~!Q![-X!c!}-X#R#S-X#T#U/m#U#o-X~/rUU~!Q![-X!c!}-X#R#S-X#T#i-X#i#j0U#j#o-X~0ZUU~!Q![-X!c!}-X#R#S-X#T#`-X#`#a0m#a#o-X~0rUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i1U#i#o-X~1]S!o~U~!Q![-X!c!}-X#R#S-X#T#o-X~1nTU~!Q![-X!c!}-X#R#S-X#T#U1}#U#o-X~2SUU~!Q![-X!c!}-X#R#S-X#T#`-X#`#a2f#a#o-X~2kUU~!Q![-X!c!}-X#R#S-X#T#g-X#g#h2}#h#o-X~3SUU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y3f#Y#o-X~3mSk~U~!Q![-X!c!}-X#R#S-X#T#o-X~4OVU~!Q![-X!c!}-X#R#S-X#T#a-X#a#b4e#b#c6x#c#o-X~4jUU~!Q![-X!c!}-X#R#S-X#T#d-X#d#e4|#e#o-X~5RUU~!Q![-X!c!}-X#R#S-X#T#c-X#c#d5e#d#o-X~5jUU~!Q![-X!c!}-X#R#S-X#T#f-X#f#g5|#g#o-X~6RUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i6e#i#o-X~6lS!_~U~!Q![-X!c!}-X#R#S-X#T#o-X~7PS!P~U~!Q![-X!c!}-X#R#S-X#T#o-X~7bUU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y7t#Y#o-X~7yUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i8]#i#o-X~8dS}~U~!Q![-X!c!}-X#R#S-X#T#o-X~8uTU~!Q![-X!c!}-X#R#S-X#T#U9U#U#o-X~9ZUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i9m#i#o-X~9rUU~!Q![-X!c!}-X#R#S-X#T#V-X#V#W:U#W#o-X~:ZUU~!Q![-X!c!}-X#R#S-X#T#[-X#[#]:m#]#o-X~:tS!Y~U~!Q![-X!c!}-X#R#S-X#T#o-X~;VUU~!Q![-X!c!}-X#R#S-X#T#f-X#f#g;i#g#o-X~;nUU~!Q![-X!c!}-X#R#S-X#T#i-X#i#j<Q#j#o-X~<VUU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y<i#Y#o-X~<pSj~U~!Q![-X!c!}-X#R#S-X#T#o-X~=ROs~~=UP#p#q=X~=^O!l~~=cOu~",
|
||||
tokenData: "=c~R!PX^$Upq$Uqr$yrs%Wst&zvw'cxy'pyz'uz{'z{|(P|}(^}!O(c!O!P(h!P!Q({!Q![+c![!]+|!]!^,R!^!_,W!_!`,e!`!a,z!c!}-X!}#O-j#P#Q-o#R#S-t#T#W-X#W#X.X#X#Y-X#Y#Z1i#Z#]-X#]#^3y#^#`-X#`#a7]#a#b8p#b#h-X#h#i;Q#i#o-X#o#p<|#p#q=R#q#r=^#y#z$U$f$g$U#BY#BZ$U$IS$I_$U$I|$JO$U$JT$JU$U$KV$KW$U&FU&FV$U~$ZY!|~X^$Upq$U#y#z$U$f$g$U#BY#BZ$U$IS$I_$U$I|$JO$U$JT$JU$U$KV$KW$U&FU&FV$U~%OP!d~!_!`%R~%WO!l~~%ZWOY%WZr%Wrs%ss#O%W#O#P%x#P;'S%W;'S;=`&t<%lO%W~%xOh~~%{RO;'S%W;'S;=`&U;=`O%W~&XXOY%WZr%Wrs%ss#O%W#O#P%x#P;'S%W;'S;=`&t;=`<%l%W<%lO%W~&wP;=`<%l%W~'PSP~OY&zZ;'S&z;'S;=`']<%lO&z~'`P;=`<%l&z~'hP!o~vw'k~'pO!m~~'uO!T~~'zO!X~~(PO!f~~(UP!h~{|(X~(^O!i~~(cO{~~(hO!e~R(mPVP!O!P(pQ(sP!O!P(vQ({OuQ~)QW!g~OY)jZ!P)j!P!Q+^!Q#O)j#O#P*[#P;'S)j;'S;=`+W<%lO)j~)mWOY)jZ!P)j!P!Q*V!Q#O)j#O#P*[#P;'S)j;'S;=`+W<%lO)j~*[Om~~*_RO;'S)j;'S;=`*h;=`O)j~*kXOY)jZ!P)j!P!Q*V!Q#O)j#O#P*[#P;'S)j;'S;=`+W;=`<%l)j<%lO)j~+ZP;=`<%l)j~+cO!p~~+hQi~!O!P+n!Q![+c~+qP!Q![+t~+yPj~!Q![+t~,RO!W~~,WOx~~,]Po~!_!`,`~,eOp~~,jQWP!_!`,p!`!a,u~,uO!k~Q,zO!YQ~-PPq~!_!`-S~-XOr~~-^SU~!Q![-X!c!}-X#R#S-X#T#o-X~-oOz~~-tO|~~-{S!_~U~!Q![-X!c!}-X#R#S-X#T#o-X~.^UU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y.p#Y#o-X~.uUU~!Q![-X!c!}-X#R#S-X#T#Y-X#Y#Z/X#Z#o-X~/^TU~!Q![-X!c!}-X#R#S-X#T#U/m#U#o-X~/rUU~!Q![-X!c!}-X#R#S-X#T#i-X#i#j0U#j#o-X~0ZUU~!Q![-X!c!}-X#R#S-X#T#`-X#`#a0m#a#o-X~0rUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i1U#i#o-X~1]S!q~U~!Q![-X!c!}-X#R#S-X#T#o-X~1nTU~!Q![-X!c!}-X#R#S-X#T#U1}#U#o-X~2SUU~!Q![-X!c!}-X#R#S-X#T#`-X#`#a2f#a#o-X~2kUU~!Q![-X!c!}-X#R#S-X#T#g-X#g#h2}#h#o-X~3SUU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y3f#Y#o-X~3mSl~U~!Q![-X!c!}-X#R#S-X#T#o-X~4OVU~!Q![-X!c!}-X#R#S-X#T#a-X#a#b4e#b#c6x#c#o-X~4jUU~!Q![-X!c!}-X#R#S-X#T#d-X#d#e4|#e#o-X~5RUU~!Q![-X!c!}-X#R#S-X#T#c-X#c#d5e#d#o-X~5jUU~!Q![-X!c!}-X#R#S-X#T#f-X#f#g5|#g#o-X~6RUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i6e#i#o-X~6lS!a~U~!Q![-X!c!}-X#R#S-X#T#o-X~7PS!R~U~!Q![-X!c!}-X#R#S-X#T#o-X~7bUU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y7t#Y#o-X~7yUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i8]#i#o-X~8dS!P~U~!Q![-X!c!}-X#R#S-X#T#o-X~8uTU~!Q![-X!c!}-X#R#S-X#T#U9U#U#o-X~9ZUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i9m#i#o-X~9rUU~!Q![-X!c!}-X#R#S-X#T#V-X#V#W:U#W#o-X~:ZUU~!Q![-X!c!}-X#R#S-X#T#[-X#[#]:m#]#o-X~:tS![~U~!Q![-X!c!}-X#R#S-X#T#o-X~;VUU~!Q![-X!c!}-X#R#S-X#T#f-X#f#g;i#g#o-X~;nUU~!Q![-X!c!}-X#R#S-X#T#i-X#i#j<Q#j#o-X~<VUU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y<i#Y#o-X~<pSk~U~!Q![-X!c!}-X#R#S-X#T#o-X~=ROt~~=UP#p#q=X~=^O!n~~=cOv~",
|
||||
tokenizers: [0, 1],
|
||||
topRules: {"Source":[0,2]},
|
||||
tokenPrec: 2497
|
||||
specialized: [{term: 6, get: (value) => spec_Identifier[value] || -1}],
|
||||
tokenPrec: 2708
|
||||
})
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
||||
import {LRParser} from "@lezer/lr"
|
||||
const spec_Identifier = {__proto__:null,as:182}
|
||||
export const parser = LRParser.deserialize({
|
||||
version: 14,
|
||||
states: "8fQYQPOOO#nQPO'#CaOOQO'#Cr'#CrO$wQPO'#CyO&UQPO'#DOO&^QQO'#DXO&hQPO'#DYO&pQPO'#CqO$wQPO'#DeO&zQPO'#DjOOQO'#Cq'#CqOOQO'#Cp'#CpO'PQPO'#CoO$wQPO'#CoOOQO'#Cn'#CnO)iQPO'#CmO.[QPO'#ClO0`QPO'#CkOOQO'#Cj'#CjO2WQPO'#CiO3{QPO'#ChO5mQPO'#CgO7XQPO'#CfOOQO'#Ce'#CeO7cQPO'#C`O7hQPO'#C_OOQO'#D|'#D|QYQPOOO8{QPO'#D}O9QQPO,58{OOQO,59e,59eO9YQPO'#CaOOQO,59j,59jO9bQPO,59jO$wQPO,59nOOQO,59s,59sO9jQPO,59sO9rQPO'#EQO9wQPO'#D[O:PQPO,59tO:UQPO'#CqO:cQPO'#D`O:kQQO,59xO:pQPO,59xO:uQPO,59]O:zQPO,5:POOQO,5:U,5:UO;PQPO'#DlOOQO,59[,59[O;WQPO,59[OOQO,59Z,59ZO$wQPO,59YO$wQPO,59XO$wQPO,59WOOQO'#Dt'#DtO$wQPO,59VO$wQPO,59UO$wQPO,59TO$wQPO,59SO$wQPO,59RO$wQPO,59QO$wQPO,58zOOQO,58y,58yOOQO-E7z-E7zOOQO,5:i,5:iOOQO-E7{-E7{O;]QPO1G/UO;eQPO1G/UOOQO1G/U1G/UO;mQPO1G/YO;uQPO1G/_O;|QPO1G/_OOQO1G/_1G/_OOQO,5:l,5:lOOQO-E8O-E8OO$wQPO1G/`O$wQPO,59{O<UQPO,59zO<^QPO,59zO$wQPO1G/dO<fQQO1G/dOOQO1G.w1G.wO<kQPO1G/kO<uQPO'#DmOOQO,5:W,5:WO<}QPO,5:WOOQO1G.v1G.vOOQO1G.t1G.tO=SQPO1G.sO@jQPO1G.rOBUQPO1G.qOOQO1G.p1G.pOC|QPO1G.oOEqQPO1G.nOGTQPO1G.mOOQO1G.l1G.lOOQO1G.f1G.fOOQO1G.s1G.sOOQO1G.r1G.rOOQO1G.q1G.qOOQO1G.o1G.oOOQO1G.n1G.nOOQO1G.m1G.mOOQO,5:j,5:jOOQO7+$p7+$pOHqQPO7+$pOOQO-E7|-E7|OOQO7+$t7+$tOHyQPO7+$tOOQO,5:k,5:kOOQO7+$y7+$yOIOQPO7+$yOOQO-E7}-E7}OOQO7+$z7+$zOOQO1G/g1G/gOIVQPO'#DaOOQO,5:m,5:mOI[QPO1G/fOOQO-E8P-E8POOQO7+%O7+%OO$wQPO7+%OOOQO'#Dh'#DhOIdQPO'#DgOOQO7+%V7+%VOIiQPO7+%VOIqQPO,5:XOIxQPO,5:XOOQO1G/r1G/rOOQO<<H[<<H[PJQQPO'#EOOOQO<<H`<<H`OOQO<<He<<HeP$wQPO'#EPPJVQPO'#EROOQO<<Hj<<HjO$wQPO,5:ROJ[QPO<<HqOJfQPO<<HqOOQO<<Hq<<HqOJnQPO1G/sOOQO1G/m1G/mOOQO,5:n,5:nOOQOAN>]AN>]OJuQPOAN>]OOQO-E8Q-E8QOOQOG23wG23wP<nQPO'#ESO$wQPO,59XO$wQPO,59WO$wQPO,59VO$wQPO,59TO$wQPO,59SO$wQPO,59ROKPQPO1G.rOKgQPO'#ClOKzQPO'#CkOLnQPO'#ChOMnQPO'#CgONqQPO'#CfO$wQPO,59WO$wQPO,59UO$wQPO,59QO! zQPO1G.qO!!bQPO'#CkO!#oQPO'#CiO$wQPO,59VO$wQPO,59UO$wQPO,59TO$wQPO,59SO$wQPO,59RO$wQPO,59QO$wQPO,58zO!$lQPO1G.oO!%SQPO1G.nO!%jQPO1G.mO!&[QPO'#CiO!'SQPO'#ChO!'wQPO'#CgO!(iQPO'#CfO!)WQPO'#C`",
|
||||
stateData: "!)j~O!yOSPOS~OUPOgQOhQOiQOjQOkQOlQOnROoROpROqROsSOwTO}UO!RVO!YWO!_XO!b]O!c]O~OneXoeXpeXqeX!ReX!ceX!deX!eeX!feX!geX!ieX!jeX!keX!leX!meX!neX!oeX~OVlOUeXWTXgeXheXieXjeXkeXleXseXteXweX}eX!YeX!_eX!beX!weX~P!gOUYOgQOhQOiQOjQOkQOlQOnROoROpROqROsSOwTO}UO!RVO!YWO!_XO!b]O!c]O~OUoOupO~OxrOzsO~P$wOUoO!P!OP~OUxO!VzO~P]Og!OO~OV!RO!R!POUcXgcXhcXicXjcXkcXlcXncXocXpcXqcXscXtcXwcX}cX!YcX!_cX!bcX!ccX!dcX!ecX!fcX!gcX!icX!jcX!kcX!lcX!mcX!ncX!ocX!wcXycXzcX!VcXucX!UcX~O!d!TO!e!TOUaXgaXhaXiaXjaXkaXlaXnaXoaXpaXqaXsaXtaXwaX}aX!RaX!YaX!_aX!baX!caX!faX!gaX!iaX!jaX!kaX!laX!maX!naX!oaX!waXVaXyaXzaX!VaXuaX!UaX~OU`Xg`Xh`Xi`Xj`Xk`Xl`Xn`Xo`Xp`Xq`Xs`Xt`Xw`X}`X!R`X!Y`X!_`X!b`X!g`X!i`X!j`X!k`X!l`X!m`X!n`X!o`X!w`Xy`Xz`X!V`Xu`X!U`X~O!c!UO!f!UO~P,ROn!WOo!WOp!WOq!WO!i!WO!j!WOU_Xg_Xh_Xi_Xj_Xk_Xl_Xs_Xt_Xw_X}_X!R_X!Y_X!__X!b_X!c_X!k_X!l_X!m_X!n_X!o_X!w_X~O!g!VO~P.fOU]Xg]Xh]Xi]Xj]Xk]Xl]Xn]Xo]Xp]Xq]Xs]Xt]Xw]X}]X!R]X!Y]X!_]X!b]X!c]X!l]X!m]X!n]X!o]X!w]X~O!k!YO~P0gOU[Xg[Xh[Xi[Xj[Xk[Xl[Xn[Xo[Xp[Xq[Xs[Xt[Xw[X}[X!R[X!Y[X!_[X!b[X!c[X!m[X!n[X!o[X!w[X~O!l!ZO~P2_OUZXgZXhZXiZXjZXkZXlZXnZXoZXpZXqZXsZXtZXwZX}ZX!RZX!YZX!_ZX!bZX!cZX!nZX!oZX!wZX~O!m![O~P4SOUYXgYXhYXiYXjYXkYXlYXnYXoYXpYXqYXsYXtYXwYX}YX!RYX!YYX!_YX!bYX!cYX!wYX~O!n!]O!o!^O~P5tOW!_O~Ot!`OURXgRXhRXiRXjRXkRXlRXnRXoRXpRXqRXsRXwRX}RX!RRX!YRX!_RX!bRX!cRX!wRX~OU!bO~OVlOWTa~OVlOWTX~Ot!dOu!fO~Oy!hOz!jO~Ot!kO~OUoO!P!OX~O!P!mO~O!U!nOVeX!VeX~P!gOy!oO!V!SX~O!W!qO~O!V!rO~O!V!sO~Os!tO~O!V!vO~P$wOU!xO~OUoOu#[O~Ot#]Ou#[O~Oy#`Oz#_O~Oz#bO~P$wOy#cOz#bO~OU#gO!V!Sa~Oy#iO!V!Sa~O!W#lO~Ou#oO!]#mO~P$wOy#qO!V!aX~O!V#sO~O!d!TO!e!TOUaigaihaiiaijaikailainaioaipaiqaisaitaiwai}ai!Rai!Yai!_ai!bai!cai!fai!gai!iai!jai!kai!lai!mai!nai!oai!waiyaizai!Vaiuai!Uai~O!f!UOn`io`ip`iq`is`it`i!g`i!i`i!j`i!k`i!l`i!m`i!n`i!o`i~OU`ig`ih`ii`ij`ik`il`iw`i}`i!R`i!Y`i!_`i!b`i!c`i!w`i~P?iOs_it_i!k_i!l_i!m_i!n_i!o_i~O!g!VOU_ig_ih_ii_ij_ik_il_in_io_ip_iq_iw_i}_i!R_i!Y_i!__i!b_i!c_i!w_i~PAmOs]it]i!l]i!m]i!n]i!o]i~O!k!YOU]ig]ih]ii]ij]ik]il]in]io]ip]iq]iw]i}]i!R]i!Y]i!_]i!b]i!c]i!w]i~PChOs[it[i!m[i!n[i!o[i~O!l!ZOU[ig[ih[ii[ij[ik[il[in[io[ip[iq[iw[i}[i!R[i!Y[i!_[i!b[i!c[i!w[i~PE`O!m![OUZigZihZiiZijZikZilZinZioZipZiqZisZitZiwZi}Zi!RZi!YZi!_Zi!bZi!cZi!nZi!oZi!wZi~OUoOu#tO~Oz#vO~Oz#wO~P$wO!U!nO~OU#gO!V!Si~O!U#{O~Ot#|Ou$OO~O!V!aa~P$wOy$PO!V!aa~OUoO~OU#gO~Ou$SO!]#mO~P$wOt$TOu$SO~O!V!ai~P$wOu$VO!]#mO~P$wO!c!UOy`iz`i!V`iu`i!U`i~P?iO!c$XO!f$XOV`X!d`X!e`X~P,RO!g$YOV_X!d_X!e_X!f_Xy_Xz_X!V_Xu_X!U_X~P.fO!l$[OV[X!d[X!e[X!f[X!g[X!i[X!j[X!k[Xy[Xz[X!V[Xu[X!U[X~P2_O!m$]OVZX!dZX!eZX!fZX!gZX!iZX!jZX!kZX!lZXyZXzZX!VZXuZX!UZX~P4SO!n$^O!o$gOVYX!dYX!eYX!fYX!gYX!iYX!jYX!kYX!lYX!mYXyYXzYX!VYXuYX!UYX~P5tO!g$eOy_iz_i!V_iu_i!U_i~PAmOn!WOo!WOp!WOq!WO!g$eO!i!WO!j!WOy_Xz_X!k_X!l_X!m_X!n_X!o_X!V_Xs_Xt_Xu_X!U_X~O!k$fOV]X!d]X!e]X!f]X!g]X!i]X!j]Xy]Xz]X!V]Xu]X!U]X~P0gO!k$lOy]iz]i!V]iu]i!U]i~PChO!l$mOy[iz[i!V[iu[i!U[i~PE`O!m$nOyZizZi!nZi!oZi!VZisZitZiuZi!UZi~O!k$lOy]Xz]X!l]X!m]X!n]X!o]X!V]Xs]Xt]Xu]X!U]X~O!l$mOy[Xz[X!m[X!n[X!o[X!V[Xs[Xt[Xu[X!U[X~O!m$nOyZXzZX!nZX!oZX!VZXsZXtZXuZX!UZX~O!n$oO!o$pOyYXzYX!VYXsYXtYXuYX!UYX~OW$qO~O}!P!Y!_!ojkih!]Uj~",
|
||||
goto: "4O!wPPP!x!|#^PPP#j$r%c&U'Q(P)R*O+W,a-h.q/v0{PPPPPP0{PPPP0{PPP0{PPPP0{0{P2QP0{P2T2WPPP0{P2`2hP0{P2n2qPPPPPP2tPPPPPPP2}3T3[3b3l3r3xTjOkSiOkQqSSuUvV#Z!d#]#uShOk]$ySUv!d#]#uSiOkQnRQtTQ|VQ}WQ!grQ!u!PS#S!_$qY#a!h#c#q#x$PQ#e!mQ#f!nQ#k!qW#m!t#|$T$WQ#z#lR$Q#{!QgORTVWkr!P!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$qV#R!^$g$pWfOk!^!_Y$dR!m!q#l$gu$xTVWr!P!h!n!t#c#q#x#{#|$P$T$W$p$qWeOk!^!_Q#Q!]Q#Y$^Y$cR!m!q#l$gQ$t$ou$wTVWr!P!h!n!t#c#q#x#{#|$P$T$W$p$qYdOk!]!^!_Q#P![Q#X$][$bR!m!q#l$^$gQ$s$nw$vTVWr!P!h!n!t#c#q#x#{#|$P$T$W$o$p$q[cOk![!]!^!_Q#O!ZQ#W$[^$jR!m!q#l$]$^$gQ$r$my$uTVWr!P!h!n!t#c#q#x#{#|$P$T$W$n$o$p$q!jbORTVWkr!P!Z![!]!^!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$[$]$^$g$m$n$o$p$qV!}!Y$f$l`aOk!Y!Z![!]!^!_Q!|!XQ#V$Zb$aR!m!q#l$[$]$^$f$gQ$h$k}$iTVWr!P!h!n!t#c#q#x#{#|$P$T$W$l$m$n$o$p$q!b`OTVWkr!P!X!Y!Z![!]!^!_!h!n!t#c#q#x#{#|$P$T$W$k$l$m$n$o$p$qQ!{!VQ#U$YQ$_$ee$`R!m!q#l$Z$[$]$^$f$g!|_ORTVWkr!P!V!X!Y!Z![!]!^!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$Y$Z$[$]$^$e$f$g$k$l$m$n$o$p$qQ!z!UR#T$X#Q^ORTVWkr!P!U!V!X!Y!Z![!]!^!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$X$Y$Z$[$]$^$e$f$g$k$l$m$n$o$p$qQ!S]R!y!T#V[ORTVW]kr!P!T!U!V!X!Y!Z![!]!^!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$X$Y$Z$[$]$^$e$f$g$k$l$m$n$o$p$q#VZORTVW]kr!P!T!U!V!X!Y!Z![!]!^!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$X$Y$Z$[$]$^$e$f$g$k$l$m$n$o$p$q#VYORTVW]kr!P!T!U!V!X!Y!Z![!]!^!_!h!m!n!q!t#c#l#q#x#{#|$P$T$W$X$Y$Z$[$]$^$e$f$g$k$l$m$n$o$p$qRwUR{VQyVV#h!o#i#yQ#p!tV$R#|$T$WX#n!t#|$T$WR!Q[R!w!PQ!XaQ$Z$aR$k$iQkOR!akSmPoR!cmQ!eqR#^!eQ!itS#d!i#rR#r!uQvUR!lvQ!pyR#j!pQ#}#pR$U#}",
|
||||
nodeNames: "⚠ Comment Source Statement FieldDefinition FieldPath Identifier Dot Equal Expression DefaultExpression PatchExpression ComposeExpression LogicalOrExpression LogicalAndExpression ComparisonExpression ConcatExpression AdditiveExpression MultiplicativeExpression UnaryExpression PostfixExpression PrimaryExpression Literal String Integer Float True False Regex ComparisonConstraint Lt Lte Gt Gte Object LBrace Semicolon RBrace ArrayConstraint LBracket Ellipsis Comma RBracket Array LetExpression Let FieldDefinitionList In FunctionExpression LParen ParameterList Parameter Colon RParen Arrow MatchExpression Match MatchArm Pattern Underscore ImportExpression Import CallSuffix ArgumentList Bang Minus Star Slash Plus PlusPlus CompareOperator EqualEqual BangEqual AmpAmp PipePipe Amp SlashSlash Default",
|
||||
maxTerm: 87,
|
||||
states: "9zQYQPOOO#qQPO'#CaOOQO'#Cs'#CsO$zQPO'#CzO&XQQO'#DTO&dQQO'#DZO&nQPO'#D[O&vQPO'#CrO$zQPO'#DgO'QQPO'#DlOOQO'#Cr'#CrOOQO'#Cq'#CqO'VQPO'#CpO$zQPO'#CpOOQO'#Co'#CoO)rQPO'#CnO.kQPO'#CmO0rQPO'#ClOOQO'#Ck'#CkO2mQPO'#CjO4eQPO'#CiO6YQPO'#ChO7wQPO'#CgOOQO'#Cf'#CfO8RQPO'#CeO9iQPO'#C`O9nQPO'#C_OOQO'#EP'#EPQYQPOOO;RQPO'#EQO;WQPO,58{OOQO,59f,59fO;`QPO'#CaO$zQPO,59kOOQO,59o,59oO;hQPO,59oO$zQPO,59qOOQO,59u,59uO;pQPO,59uO;xQPO'#ETO;}QPO'#D^O<VQPO,59vO<[QPO'#CrO<iQPO'#DbO<qQQO,59zO<vQPO,59zO<{QPO,59^O=QQPO,5:ROOQO,5:W,5:WO=VQPO'#DnOOQO,59],59]O=^QPO,59]OOQO,59[,59[O$zQPO,59ZO$zQPO,59YO$zQPO,59XOOQO'#Dv'#DvO$zQPO,59WO$zQPO,59VO$zQPO,59UO$zQPO,59TO$zQPO,59SO$zQPO,59ROOQO'#EO'#EOO$zQPO,59QO$zQPO,58zOOQO,58y,58yOOQO-E7}-E7}OOQO,5:l,5:lOOQO-E8O-E8OO=cQPO1G/VO=hQPO1G/ZO=pQPO1G/ZOOQO1G/Z1G/ZO=xQPO1G/]O>QQPO1G/aO>XQPO1G/aOOQO1G/a1G/aOOQO,5:o,5:oOOQO-E8R-E8RO$zQPO1G/bO$zQPO,59}O>aQPO,59|O>iQPO,59|O$zQPO1G/fO>qQQO1G/fOOQO1G.x1G.xO>vQPO1G/mO?QQPO'#DoOOQO,5:Y,5:YO?YQPO,5:YOOQO1G.w1G.wOOQO1G.u1G.uO?_QPO1G.tOB{QPO1G.sODjQPO1G.rOOQO1G.q1G.qOFeQPO1G.pOH]QPO1G.oOJQQPO1G.nOOQO1G.m1G.mOOQO1G.l1G.lOOQO1G.f1G.fOOQO1G.t1G.tOOQO1G.s1G.sOOQO1G.r1G.rOOQO1G.p1G.pOOQO1G.o1G.oOOQO1G.n1G.nOOQO7+$q7+$qOOQO,5:m,5:mOOQO7+$u7+$uOKdQPO7+$uOOQO-E8P-E8POOQO7+$w7+$wOKlQPO7+$wOOQO,5:n,5:nOOQO7+${7+${OKqQPO7+${OOQO-E8Q-E8QOOQO7+$|7+$|OOQO1G/i1G/iOKxQPO'#DcOOQO,5:p,5:pOK}QPO1G/hOOQO-E8S-E8SOOQO7+%Q7+%QO$zQPO7+%QOOQO'#Dj'#DjOLVQPO'#DiOOQO7+%X7+%XOL[QPO7+%XOLdQPO,5:ZOLkQPO,5:ZOOQO1G/t1G/tOOQO<<Ha<<HaPLsQPO'#EROOQO<<Hc<<HcOOQO<<Hg<<HgP$zQPO'#ESPLxQPO'#EUOOQO<<Hl<<HlO$zQPO,5:TOL}QPO<<HsOMXQPO<<HsOOQO<<Hs<<HsOMaQPO1G/uOOQO1G/o1G/oOOQO,5:q,5:qOOQOAN>_AN>_OMhQPOAN>_OOQO-E8T-E8TOOQOG23yG23yP>yQPO'#EVO$zQPO,59YO$zQPO,59XO$zQPO,59WO$zQPO,59UO$zQPO,59TO$zQPO,59SOMrQPO1G.sONYQPO'#CmONmQPO'#ClO! aQPO'#CiO!!aQPO'#ChO!#dQPO'#CgO$zQPO,59XO$zQPO,59VO$zQPO,59RO$zQPO,59QO!$mQPO1G.rO!%TQPO'#ClO!&eQPO'#CjO!'bQPO'#CeO$zQPO,59WO$zQPO,59VO$zQPO,59UO$zQPO,59TO$zQPO,59SO$zQPO,59RO$zQPO,59QO$zQPO,58zO!(kQPO1G.pO!)RQPO1G.oO!)iQPO1G.nO!*PQPO'#CjO!*zQPO'#CiO!+rQPO'#ChO!,gQPO'#CgO!-XQPO'#CeO!-sQPO'#C`",
|
||||
stateData: "!.V~O!|OSPOS~OUPOhQOiQOjQOkQOlQOmQOoROpROqROrROtSOzTO!PUO!TVO![WO!aXO!d]O!e]O~OofXpfXqfXrfX!TfX!efX!ffX!gfX!hfX!ifX!kfX!lfX!mfX!nfX!ofX!pfX!qfX!}fX~OVmOUfXWTXhfXifXjfXkfXlfXmfXtfXxfXzfX!PfX![fX!afX!dfX!zfX~P!gOUYOhQOiQOjQOkQOlQOmQOoROpROqROrROtSOzTO!PUO!TVO![WO!aXO!d]O!e]O~OUpOuqOvrO~OutO|uO~P$zOUpO!R!QP~OUzO!X|O~P]Oh!QO~OV!TO!T!ROUdXhdXidXjdXkdXldXmdXodXpdXqdXrdXtdXxdXzdX!PdX![dX!adX!ddX!edX!fdX!gdX!hdX!idX!kdX!ldX!mdX!ndX!odX!pdX!qdX!zdX!}dX{dX|dX!XdXvdX!WdX~O!f!VO!g!VOUbXhbXibXjbXkbXlbXmbXobXpbXqbXrbXtbXxbXzbX!PbX!TbX![bX!abX!dbX!ebX!hbX!ibX!kbX!lbX!mbX!nbX!obX!pbX!qbX!zbX!}bXVbX{bX|bX!XbXvbX!WbX~OUaXhaXiaXjaXkaXlaXmaXoaXpaXqaXraXtaXxaXzaX!PaX!TaX![aX!aaX!daX!iaX!kaX!laX!maX!naX!oaX!paX!qaX!zaX!}aX{aX|aX!XaXvaX!WaX~O!e!WO!h!WO~P,_Oo!YOp!YOq!YOr!YO!k!YO!l!YOU`Xh`Xi`Xj`Xk`Xl`Xm`Xt`Xx`Xz`X!P`X!T`X![`X!a`X!d`X!e`X!m`X!n`X!o`X!p`X!q`X!z`X!}`X~O!i!XO~P.uOU^Xh^Xi^Xj^Xk^Xl^Xm^Xo^Xp^Xq^Xr^Xt^Xx^Xz^X!P^X!T^X![^X!a^X!d^X!e^X!n^X!o^X!p^X!q^X!z^X!}^X~O!m![O~P0yOU]Xh]Xi]Xj]Xk]Xl]Xm]Xo]Xp]Xq]Xr]Xt]Xx]Xz]X!P]X!T]X![]X!a]X!d]X!e]X!o]X!p]X!q]X!z]X!}]X~O!n!]O~P2tOU[Xh[Xi[Xj[Xk[Xl[Xm[Xo[Xp[Xq[Xr[Xt[Xx[Xz[X!P[X!T[X![[X!a[X!d[X!e[X!p[X!q[X!z[X!}[X~O!o!^O~P4lOUZXhZXiZXjZXkZXlZXmZXoZXpZXqZXrZXtZXxZXzZX!PZX!TZX![ZX!aZX!dZX!eZX!zZX!}ZX~O!p!_O!q!`O~P6aO!}!aOUXXhXXiXXjXXkXXlXXmXXoXXpXXqXXrXXtXXxXXzXX!PXX!TXX![XX!aXX!dXX!eXX!zXX~OW!cO~Ox!dOURXhRXiRXjRXkRXlRXmRXoRXpRXqRXrRXtRXzRX!PRX!TRX![RX!aRX!dRX!eRX!zRX~OU!fO~OVmOWTa~OVmOWTX~Ov!kOx!iO~O{!mO|!oO~Ox!pO~OUpO!R!QX~O!R!rO~O!W!sOVfX!XfX~P!gO{!tO!X!UX~O!Y!vO~O!X!wO~O!X!xO~Ot!yO~O!X!{O~P$zOU!}O~Ov#aO~OUpOv#cO~Ov#cOx#dO~O{#gO|#fO~O|#iO~P$zO{#jO|#iO~OU#nO!X!Ua~O{#pO!X!Ua~O!Y#sO~Ov#vO!_#tO~P$zO{#xO!X!cX~O!X#zO~O!f!VO!g!VOUbihbiibijbikbilbimbiobipbiqbirbitbixbizbi!Pbi!Tbi![bi!abi!dbi!ebi!hbi!ibi!kbi!lbi!mbi!nbi!obi!pbi!qbi!zbi!}bi{bi|bi!Xbivbi!Wbi~O!h!WOoaipaiqairaitaixai!iai!kai!lai!mai!nai!oai!pai!qai!}ai~OUaihaiiaijaikailaimaizai!Pai!Tai![ai!aai!dai!eai!zai~PAwOt`ix`i!m`i!n`i!o`i!p`i!q`i!}`i~O!i!XOU`ih`ii`ij`ik`il`im`io`ip`iq`ir`iz`i!P`i!T`i![`i!a`i!d`i!e`i!z`i~PDOOt^ix^i!n^i!o^i!p^i!q^i!}^i~O!m![OU^ih^ii^ij^ik^il^im^io^ip^iq^ir^iz^i!P^i!T^i![^i!a^i!d^i!e^i!z^i~PE|Ot]ix]i!o]i!p]i!q]i!}]i~O!n!]OU]ih]ii]ij]ik]il]im]io]ip]iq]ir]iz]i!P]i!T]i![]i!a]i!d]i!e]i!z]i~PGwOt[ix[i!p[i!q[i!}[i~O!o!^OU[ih[ii[ij[ik[il[im[io[ip[iq[ir[iz[i!P[i!T[i![[i!a[i!d[i!e[i!z[i~PIoOUpOv#{O~O|#}O~O|$OO~P$zO!W!sO~OU#nO!X!Ui~O!W$SO~Ov$VOx$TO~O!X!ca~P$zO{$WO!X!ca~OUpO~OU#nO~Ov$ZO!_#tO~P$zOv$ZOx$[O~O!X!ci~P$zOv$^O!_#tO~P$zO!e!WO{ai|ai!Xaivai!Wai~PAwO!e$`O!h$`OVaX!faX!gaX~P,_O!i$aOV`X!f`X!g`X!h`X{`X|`X!X`Xv`X!W`X~P.uO!n$cOV]X!f]X!g]X!h]X!i]X!k]X!l]X!m]X{]X|]X!X]Xv]X!W]X~P2tO!o$dOV[X!f[X!g[X!h[X!i[X!k[X!l[X!m[X!n[X{[X|[X!X[Xv[X!W[X~P4lO!p$eO!q$nOVZX!fZX!gZX!hZX!iZX!kZX!lZX!mZX!nZX!oZX{ZX|ZX!XZXvZX!WZX~P6aO!i$lO{`i|`i!X`iv`i!W`i~PDOOo!YOp!YOq!YOr!YO!i$lO!k!YO!l!YO{`X|`X!m`X!n`X!o`X!p`X!q`X!}`X!X`Xt`Xv`Xx`X!W`X~O!m$mOV^X!f^X!g^X!h^X!i^X!k^X!l^X{^X|^X!X^Xv^X!W^X~P0yOVXX!fXX!gXX!hXX!iXX!kXX!lXX!mXX!nXX!oXX!pXX!qXX{XX|XX!XXXvXX!WXX~P8RO!m$uO{^i|^i!X^iv^i!W^i~PE|O!n$vO{]i|]i!X]iv]i!W]i~PGwO!o$wO{[i|[i!X[iv[i!W[i~PIoO!m$uO{^X|^X!n^X!o^X!p^X!q^X!}^X!X^Xt^Xv^Xx^X!W^X~O!n$vO{]X|]X!o]X!p]X!q]X!}]X!X]Xt]Xv]Xx]X!W]X~O!o$wO{[X|[X!p[X!q[X!}[X!X[Xt[Xv[Xx[X!W[X~O!p$xO!q$yO{ZX|ZX!}ZX!XZXtZXvZXxZX!WZX~O!}!aO{XX|XX!XXXtXXvXXxXX!WXX~OW${O~O!P!R![!a!qklji!_Uk~",
|
||||
goto: "6W!zPPP!{#P#aPPP#m$x%i&`'V(V)Y*`+a,m-z/V0d1m2vPPPPPP2vPPPP2vPPP2vP2vPPP2v2vP4PP2vP4S4VPPP2vP4_4gP2vP4m4pPPPPPP4sPPPPPPP4|5V5]5d5j5t5z6QTkOlSjOlQsSSwUxV#b!i#d#|SiOl]%USUx!i#d#|SjOlQoRQvTQ!OVQ!PWQ!hqQ!ltQ!z!RS#Y!c${Y#h!m#j#x$P$WQ#l!rQ#m!sQ#r!vW#t!y$T$[$_Q$R#sR$X$SUhOl!cW$sR!r!v#su%TTVWqt!R!m!s!y#j#x$P$S$T$W$[$_${!SgORTVWlqt!R!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_${U#W!`$n$yV#X!b$o$zYfOl!`!b!c[$kR!r!v#s$n$oy%STVWqt!R!m!s!y#j#x$P$S$T$W$[$_$y$z${YeOl!`!b!cQ#V!_Q#`$e[$jR!r!v#s$n$oQ%O$xy%RTVWqt!R!m!s!y#j#x$P$S$T$W$[$_$y$z${[dOl!_!`!b!cQ#U!^Q#_$d^$iR!r!v#s$e$n$oQ$}$w{%QTVWqt!R!m!s!y#j#x$P$S$T$W$[$_$x$y$z${^cOl!^!_!`!b!cQ#T!]Q#^$c`$rR!r!v#s$d$e$n$oQ$|$v}%PTVWqt!R!m!s!y#j#x$P$S$T$W$[$_$w$x$y$z${!rbORTVWlqt!R!]!^!_!`!b!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_$c$d$e$n$o$v$w$x$y$z${V#S![$m$ubaOl![!]!^!_!`!b!cQ#R!ZQ#]$bd$hR!r!v#s$c$d$e$m$n$oQ$p$t!R$qTVWqt!R!m!s!y#j#x$P$S$T$W$[$_$u$v$w$x$y$z${!h`OTVWlqt!R!Z![!]!^!_!`!b!c!m!s!y#j#x$P$S$T$W$[$_$t$u$v$w$x$y$z${Q#Q!XQ#[$aQ$f$lg$gR!r!v#s$b$c$d$e$m$n$o#U_ORTVWlqt!R!X!Z![!]!^!_!`!b!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_$a$b$c$d$e$l$m$n$o$t$u$v$w$x$y$z${Q#P!WR#Z$`#Y^ORTVWlqt!R!W!X!Z![!]!^!_!`!b!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_$`$a$b$c$d$e$l$m$n$o$t$u$v$w$x$y$z${Q!U]R#O!V#_[ORTVW]lqt!R!V!W!X!Z![!]!^!_!`!b!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_$`$a$b$c$d$e$l$m$n$o$t$u$v$w$x$y$z${#_ZORTVW]lqt!R!V!W!X!Z![!]!^!_!`!b!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_$`$a$b$c$d$e$l$m$n$o$t$u$v$w$x$y$z${#_YORTVW]lqt!R!V!W!X!Z![!]!^!_!`!b!c!m!r!s!v!y#j#s#x$P$S$T$W$[$_$`$a$b$c$d$e$l$m$n$o$t$u$v$w$x$y$z${RyUR}VQ{VV#o!t#p$QQ#w!yV$Y$T$[$_X#u!y$T$[$_R!S[R!|!RQ!ZaQ$b$hR$t$qQ!bhQ$o$sR$z%TQlOR!elSnPpR!gnQ!jsR#e!jQ!nvS#k!n#yR#y!zQxUR!qxQ!u{R#q!uQ$U#wR$]$U",
|
||||
nodeNames: "⚠ Comment Source Statement FieldDefinition FieldPath Identifier Dot Equal Expression AsExpression DefaultExpression PatchExpression ComposeExpression LogicalOrExpression LogicalAndExpression ComparisonExpression ConcatExpression AdditiveExpression MultiplicativeExpression UnaryExpression PostfixExpression PrimaryExpression Literal String Integer Float True False Regex ComparisonConstraint Lt Lte Gt Gte MapConstraint LBrace Ellipsis RBrace Object Semicolon ArrayConstraint LBracket Comma RBracket Array LetExpression Let FieldDefinitionList In FunctionExpression LParen ParameterList Parameter Colon RParen Arrow MatchExpression Match MatchArm Pattern Underscore ImportExpression Import CallSuffix ArgumentList Bang Minus Star Slash Plus PlusPlus CompareOperator EqualEqual BangEqual AmpAmp PipePipe Amp SlashSlash Default As",
|
||||
maxTerm: 91,
|
||||
skippedNodes: [0,1],
|
||||
repeatNodeCount: 7,
|
||||
tokenData: "=c~R!PX^$Upq$Uqr$yrs%Wst&zvw'cxy'pyz'uz{'z{|(P|}(^}!O(c!O!P(h!P!Q({!Q![+c![!]+|!]!^,R!^!_,W!_!`,e!`!a,z!c!}-X!}#O-j#P#Q-o#R#S-t#T#W-X#W#X.X#X#Y-X#Y#Z1i#Z#]-X#]#^3y#^#`-X#`#a7]#a#b8p#b#h-X#h#i;Q#i#o-X#o#p<|#p#q=R#q#r=^#y#z$U$f$g$U#BY#BZ$U$IS$I_$U$I|$JO$U$JT$JU$U$KV$KW$U&FU&FV$U~$ZY!y~X^$Upq$U#y#z$U$f$g$U#BY#BZ$U$IS$I_$U$I|$JO$U$JT$JU$U$KV$KW$U&FU&FV$U~%OP!b~!_!`%R~%WO!j~~%ZWOY%WZr%Wrs%ss#O%W#O#P%x#P;'S%W;'S;=`&t<%lO%W~%xOg~~%{RO;'S%W;'S;=`&U;=`O%W~&XXOY%WZr%Wrs%ss#O%W#O#P%x#P;'S%W;'S;=`&t;=`<%l%W<%lO%W~&wP;=`<%l%W~'PSP~OY&zZ;'S&z;'S;=`']<%lO&z~'`P;=`<%l&z~'hP!m~vw'k~'pO!k~~'uO!R~~'zO!V~~(PO!d~~(UP!f~{|(X~(^O!g~~(cOy~~(hO!c~R(mPVP!O!P(pQ(sP!O!P(vQ({OxQ~)QW!e~OY)jZ!P)j!P!Q+^!Q#O)j#O#P*[#P;'S)j;'S;=`+W<%lO)j~)mWOY)jZ!P)j!P!Q*V!Q#O)j#O#P*[#P;'S)j;'S;=`+W<%lO)j~*[Ol~~*_RO;'S)j;'S;=`*h;=`O)j~*kXOY)jZ!P)j!P!Q*V!Q#O)j#O#P*[#P;'S)j;'S;=`+W;=`<%l)j<%lO)j~+ZP;=`<%l)j~+cO!n~~+hQh~!O!P+n!Q![+c~+qP!Q![+t~+yPi~!Q![+t~,RO!U~~,WOt~~,]Pn~!_!`,`~,eOo~~,jQWP!_!`,p!`!a,u~,uO!i~Q,zO!WQ~-PPp~!_!`-S~-XOq~~-^SU~!Q![-X!c!}-X#R#S-X#T#o-X~-oOw~~-tOz~~-{S!]~U~!Q![-X!c!}-X#R#S-X#T#o-X~.^UU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y.p#Y#o-X~.uUU~!Q![-X!c!}-X#R#S-X#T#Y-X#Y#Z/X#Z#o-X~/^TU~!Q![-X!c!}-X#R#S-X#T#U/m#U#o-X~/rUU~!Q![-X!c!}-X#R#S-X#T#i-X#i#j0U#j#o-X~0ZUU~!Q![-X!c!}-X#R#S-X#T#`-X#`#a0m#a#o-X~0rUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i1U#i#o-X~1]S!o~U~!Q![-X!c!}-X#R#S-X#T#o-X~1nTU~!Q![-X!c!}-X#R#S-X#T#U1}#U#o-X~2SUU~!Q![-X!c!}-X#R#S-X#T#`-X#`#a2f#a#o-X~2kUU~!Q![-X!c!}-X#R#S-X#T#g-X#g#h2}#h#o-X~3SUU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y3f#Y#o-X~3mSk~U~!Q![-X!c!}-X#R#S-X#T#o-X~4OVU~!Q![-X!c!}-X#R#S-X#T#a-X#a#b4e#b#c6x#c#o-X~4jUU~!Q![-X!c!}-X#R#S-X#T#d-X#d#e4|#e#o-X~5RUU~!Q![-X!c!}-X#R#S-X#T#c-X#c#d5e#d#o-X~5jUU~!Q![-X!c!}-X#R#S-X#T#f-X#f#g5|#g#o-X~6RUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i6e#i#o-X~6lS!_~U~!Q![-X!c!}-X#R#S-X#T#o-X~7PS!P~U~!Q![-X!c!}-X#R#S-X#T#o-X~7bUU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y7t#Y#o-X~7yUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i8]#i#o-X~8dS}~U~!Q![-X!c!}-X#R#S-X#T#o-X~8uTU~!Q![-X!c!}-X#R#S-X#T#U9U#U#o-X~9ZUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i9m#i#o-X~9rUU~!Q![-X!c!}-X#R#S-X#T#V-X#V#W:U#W#o-X~:ZUU~!Q![-X!c!}-X#R#S-X#T#[-X#[#]:m#]#o-X~:tS!Y~U~!Q![-X!c!}-X#R#S-X#T#o-X~;VUU~!Q![-X!c!}-X#R#S-X#T#f-X#f#g;i#g#o-X~;nUU~!Q![-X!c!}-X#R#S-X#T#i-X#i#j<Q#j#o-X~<VUU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y<i#Y#o-X~<pSj~U~!Q![-X!c!}-X#R#S-X#T#o-X~=ROs~~=UP#p#q=X~=^O!l~~=cOu~",
|
||||
tokenData: "=c~R!PX^$Upq$Uqr$yrs%Wst&zvw'cxy'pyz'uz{'z{|(P|}(^}!O(c!O!P(h!P!Q({!Q![+c![!]+|!]!^,R!^!_,W!_!`,e!`!a,z!c!}-X!}#O-j#P#Q-o#R#S-t#T#W-X#W#X.X#X#Y-X#Y#Z1i#Z#]-X#]#^3y#^#`-X#`#a7]#a#b8p#b#h-X#h#i;Q#i#o-X#o#p<|#p#q=R#q#r=^#y#z$U$f$g$U#BY#BZ$U$IS$I_$U$I|$JO$U$JT$JU$U$KV$KW$U&FU&FV$U~$ZY!|~X^$Upq$U#y#z$U$f$g$U#BY#BZ$U$IS$I_$U$I|$JO$U$JT$JU$U$KV$KW$U&FU&FV$U~%OP!d~!_!`%R~%WO!l~~%ZWOY%WZr%Wrs%ss#O%W#O#P%x#P;'S%W;'S;=`&t<%lO%W~%xOh~~%{RO;'S%W;'S;=`&U;=`O%W~&XXOY%WZr%Wrs%ss#O%W#O#P%x#P;'S%W;'S;=`&t;=`<%l%W<%lO%W~&wP;=`<%l%W~'PSP~OY&zZ;'S&z;'S;=`']<%lO&z~'`P;=`<%l&z~'hP!o~vw'k~'pO!m~~'uO!T~~'zO!X~~(PO!f~~(UP!h~{|(X~(^O!i~~(cO{~~(hO!e~R(mPVP!O!P(pQ(sP!O!P(vQ({OuQ~)QW!g~OY)jZ!P)j!P!Q+^!Q#O)j#O#P*[#P;'S)j;'S;=`+W<%lO)j~)mWOY)jZ!P)j!P!Q*V!Q#O)j#O#P*[#P;'S)j;'S;=`+W<%lO)j~*[Om~~*_RO;'S)j;'S;=`*h;=`O)j~*kXOY)jZ!P)j!P!Q*V!Q#O)j#O#P*[#P;'S)j;'S;=`+W;=`<%l)j<%lO)j~+ZP;=`<%l)j~+cO!p~~+hQi~!O!P+n!Q![+c~+qP!Q![+t~+yPj~!Q![+t~,RO!W~~,WOx~~,]Po~!_!`,`~,eOp~~,jQWP!_!`,p!`!a,u~,uO!k~Q,zO!YQ~-PPq~!_!`-S~-XOr~~-^SU~!Q![-X!c!}-X#R#S-X#T#o-X~-oOz~~-tO|~~-{S!_~U~!Q![-X!c!}-X#R#S-X#T#o-X~.^UU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y.p#Y#o-X~.uUU~!Q![-X!c!}-X#R#S-X#T#Y-X#Y#Z/X#Z#o-X~/^TU~!Q![-X!c!}-X#R#S-X#T#U/m#U#o-X~/rUU~!Q![-X!c!}-X#R#S-X#T#i-X#i#j0U#j#o-X~0ZUU~!Q![-X!c!}-X#R#S-X#T#`-X#`#a0m#a#o-X~0rUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i1U#i#o-X~1]S!q~U~!Q![-X!c!}-X#R#S-X#T#o-X~1nTU~!Q![-X!c!}-X#R#S-X#T#U1}#U#o-X~2SUU~!Q![-X!c!}-X#R#S-X#T#`-X#`#a2f#a#o-X~2kUU~!Q![-X!c!}-X#R#S-X#T#g-X#g#h2}#h#o-X~3SUU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y3f#Y#o-X~3mSl~U~!Q![-X!c!}-X#R#S-X#T#o-X~4OVU~!Q![-X!c!}-X#R#S-X#T#a-X#a#b4e#b#c6x#c#o-X~4jUU~!Q![-X!c!}-X#R#S-X#T#d-X#d#e4|#e#o-X~5RUU~!Q![-X!c!}-X#R#S-X#T#c-X#c#d5e#d#o-X~5jUU~!Q![-X!c!}-X#R#S-X#T#f-X#f#g5|#g#o-X~6RUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i6e#i#o-X~6lS!a~U~!Q![-X!c!}-X#R#S-X#T#o-X~7PS!R~U~!Q![-X!c!}-X#R#S-X#T#o-X~7bUU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y7t#Y#o-X~7yUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i8]#i#o-X~8dS!P~U~!Q![-X!c!}-X#R#S-X#T#o-X~8uTU~!Q![-X!c!}-X#R#S-X#T#U9U#U#o-X~9ZUU~!Q![-X!c!}-X#R#S-X#T#h-X#h#i9m#i#o-X~9rUU~!Q![-X!c!}-X#R#S-X#T#V-X#V#W:U#W#o-X~:ZUU~!Q![-X!c!}-X#R#S-X#T#[-X#[#]:m#]#o-X~:tS![~U~!Q![-X!c!}-X#R#S-X#T#o-X~;VUU~!Q![-X!c!}-X#R#S-X#T#f-X#f#g;i#g#o-X~;nUU~!Q![-X!c!}-X#R#S-X#T#i-X#i#j<Q#j#o-X~<VUU~!Q![-X!c!}-X#R#S-X#T#X-X#X#Y<i#Y#o-X~<pSk~U~!Q![-X!c!}-X#R#S-X#T#o-X~=ROt~~=UP#p#q=X~=^O!n~~=cOv~",
|
||||
tokenizers: [0, 1],
|
||||
topRules: {"Source":[0,2]},
|
||||
tokenPrec: 2497
|
||||
specialized: [{term: 6, get: (value) => spec_Identifier[value] || -1}],
|
||||
tokenPrec: 2708
|
||||
})
|
||||
|
||||
@@ -9,71 +9,74 @@ export const
|
||||
Dot = 7,
|
||||
Equal = 8,
|
||||
Expression = 9,
|
||||
DefaultExpression = 10,
|
||||
PatchExpression = 11,
|
||||
ComposeExpression = 12,
|
||||
LogicalOrExpression = 13,
|
||||
LogicalAndExpression = 14,
|
||||
ComparisonExpression = 15,
|
||||
ConcatExpression = 16,
|
||||
AdditiveExpression = 17,
|
||||
MultiplicativeExpression = 18,
|
||||
UnaryExpression = 19,
|
||||
PostfixExpression = 20,
|
||||
PrimaryExpression = 21,
|
||||
Literal = 22,
|
||||
String = 23,
|
||||
Integer = 24,
|
||||
Float = 25,
|
||||
True = 26,
|
||||
False = 27,
|
||||
Regex = 28,
|
||||
ComparisonConstraint = 29,
|
||||
Lt = 30,
|
||||
Lte = 31,
|
||||
Gt = 32,
|
||||
Gte = 33,
|
||||
Object = 34,
|
||||
LBrace = 35,
|
||||
Semicolon = 36,
|
||||
RBrace = 37,
|
||||
ArrayConstraint = 38,
|
||||
LBracket = 39,
|
||||
Ellipsis = 40,
|
||||
Comma = 41,
|
||||
RBracket = 42,
|
||||
Array = 43,
|
||||
LetExpression = 44,
|
||||
Let = 45,
|
||||
FieldDefinitionList = 46,
|
||||
In = 47,
|
||||
FunctionExpression = 48,
|
||||
LParen = 49,
|
||||
ParameterList = 50,
|
||||
Parameter = 51,
|
||||
Colon = 52,
|
||||
RParen = 53,
|
||||
Arrow = 54,
|
||||
MatchExpression = 55,
|
||||
Match = 56,
|
||||
MatchArm = 57,
|
||||
Pattern = 58,
|
||||
Underscore = 59,
|
||||
ImportExpression = 60,
|
||||
Import = 61,
|
||||
CallSuffix = 62,
|
||||
ArgumentList = 63,
|
||||
Bang = 64,
|
||||
Minus = 65,
|
||||
Star = 66,
|
||||
Slash = 67,
|
||||
Plus = 68,
|
||||
PlusPlus = 69,
|
||||
CompareOperator = 70,
|
||||
EqualEqual = 71,
|
||||
BangEqual = 72,
|
||||
AmpAmp = 73,
|
||||
PipePipe = 74,
|
||||
Amp = 75,
|
||||
SlashSlash = 76,
|
||||
Default = 77
|
||||
AsExpression = 10,
|
||||
DefaultExpression = 11,
|
||||
PatchExpression = 12,
|
||||
ComposeExpression = 13,
|
||||
LogicalOrExpression = 14,
|
||||
LogicalAndExpression = 15,
|
||||
ComparisonExpression = 16,
|
||||
ConcatExpression = 17,
|
||||
AdditiveExpression = 18,
|
||||
MultiplicativeExpression = 19,
|
||||
UnaryExpression = 20,
|
||||
PostfixExpression = 21,
|
||||
PrimaryExpression = 22,
|
||||
Literal = 23,
|
||||
String = 24,
|
||||
Integer = 25,
|
||||
Float = 26,
|
||||
True = 27,
|
||||
False = 28,
|
||||
Regex = 29,
|
||||
ComparisonConstraint = 30,
|
||||
Lt = 31,
|
||||
Lte = 32,
|
||||
Gt = 33,
|
||||
Gte = 34,
|
||||
MapConstraint = 35,
|
||||
LBrace = 36,
|
||||
Ellipsis = 37,
|
||||
RBrace = 38,
|
||||
Object = 39,
|
||||
Semicolon = 40,
|
||||
ArrayConstraint = 41,
|
||||
LBracket = 42,
|
||||
Comma = 43,
|
||||
RBracket = 44,
|
||||
Array = 45,
|
||||
LetExpression = 46,
|
||||
Let = 47,
|
||||
FieldDefinitionList = 48,
|
||||
In = 49,
|
||||
FunctionExpression = 50,
|
||||
LParen = 51,
|
||||
ParameterList = 52,
|
||||
Parameter = 53,
|
||||
Colon = 54,
|
||||
RParen = 55,
|
||||
Arrow = 56,
|
||||
MatchExpression = 57,
|
||||
Match = 58,
|
||||
MatchArm = 59,
|
||||
Pattern = 60,
|
||||
Underscore = 61,
|
||||
ImportExpression = 62,
|
||||
Import = 63,
|
||||
CallSuffix = 64,
|
||||
ArgumentList = 65,
|
||||
Bang = 66,
|
||||
Minus = 67,
|
||||
Star = 68,
|
||||
Slash = 69,
|
||||
Plus = 70,
|
||||
PlusPlus = 71,
|
||||
CompareOperator = 72,
|
||||
EqualEqual = 73,
|
||||
BangEqual = 74,
|
||||
AmpAmp = 75,
|
||||
PipePipe = 76,
|
||||
Amp = 77,
|
||||
SlashSlash = 78,
|
||||
Default = 79,
|
||||
As = 80
|
||||
|
||||
@@ -5,7 +5,7 @@ import { parser } from './decodal-parser.js';
|
||||
const parserWithMetadata = parser.configure({
|
||||
props: [
|
||||
styleTags({
|
||||
'Let In Match Import Default': t.keyword,
|
||||
'Let In Match Import Default As': t.keyword,
|
||||
'True False': t.bool,
|
||||
Identifier: t.variableName,
|
||||
String: t.string,
|
||||
@@ -20,6 +20,7 @@ const parserWithMetadata = parser.configure({
|
||||
}),
|
||||
indentNodeProp.add({
|
||||
Object: delimitedIndent({ closing: '}', align: false }),
|
||||
MapConstraint: delimitedIndent({ closing: '}', align: false }),
|
||||
Array: delimitedIndent({ closing: ']', align: false }),
|
||||
ArrayConstraint: delimitedIndent({ closing: ']', align: false }),
|
||||
MatchExpression: delimitedIndent({ closing: '}', align: false }),
|
||||
@@ -27,6 +28,7 @@ const parserWithMetadata = parser.configure({
|
||||
}),
|
||||
foldNodeProp.add({
|
||||
Object: foldDelimited('{', '}'),
|
||||
MapConstraint: foldDelimited('{', '}'),
|
||||
Array: foldDelimited('[', ']'),
|
||||
ArrayConstraint: foldDelimited('[', ']'),
|
||||
MatchExpression: foldDelimited('{', '}'),
|
||||
|
||||
@@ -5,6 +5,16 @@ import { getIndentation, indentUnit } from '@codemirror/language';
|
||||
import { EditorState } from '@codemirror/state';
|
||||
|
||||
import { decodal } from './decodal.js';
|
||||
import { parser } from './decodal-parser.js';
|
||||
|
||||
function parseErrors(source) {
|
||||
const errors = [];
|
||||
const cursor = parser.parse(source).cursor();
|
||||
do {
|
||||
if (cursor.type.isError) errors.push({ from: cursor.from, to: cursor.to });
|
||||
} while (cursor.next());
|
||||
return errors;
|
||||
}
|
||||
|
||||
function indentationAt(doc, lineNumber) {
|
||||
const state = EditorState.create({
|
||||
@@ -33,3 +43,15 @@ test('preserves the surrounding indentation for a nested inline object', () => {
|
||||
assert.equal(indentationAt(doc, 3), 4);
|
||||
assert.equal(indentationAt(doc, 4), 2);
|
||||
});
|
||||
|
||||
test('parses map constraints and range refinement', () => {
|
||||
const source = `services = {
|
||||
api = { port = 8080; };
|
||||
} as {...{ port = Int; }};`;
|
||||
|
||||
assert.deepEqual(parseErrors(source), []);
|
||||
});
|
||||
|
||||
test('only treats the exact as keyword as an operator', () => {
|
||||
assert.deepEqual(parseErrors('asset = 1; value = asset as Int;'), []);
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@ import { parser } from './decodal-parser-jsr.js';
|
||||
const parserWithMetadata = parser.configure({
|
||||
props: [
|
||||
styleTags({
|
||||
'Let In Match Import Default': t.keyword,
|
||||
'Let In Match Import Default As': t.keyword,
|
||||
'True False': t.bool,
|
||||
Identifier: t.variableName,
|
||||
String: t.string,
|
||||
@@ -30,6 +30,7 @@ const parserWithMetadata = parser.configure({
|
||||
}),
|
||||
indentNodeProp.add({
|
||||
Object: delimitedIndent({ closing: '}', align: false }),
|
||||
MapConstraint: delimitedIndent({ closing: '}', align: false }),
|
||||
Array: delimitedIndent({ closing: ']', align: false }),
|
||||
ArrayConstraint: delimitedIndent({ closing: ']', align: false }),
|
||||
MatchExpression: delimitedIndent({ closing: '}', align: false }),
|
||||
@@ -37,6 +38,7 @@ const parserWithMetadata = parser.configure({
|
||||
}),
|
||||
foldNodeProp.add({
|
||||
Object: foldDelimited('{', '}'),
|
||||
MapConstraint: foldDelimited('{', '}'),
|
||||
Array: foldDelimited('[', ']'),
|
||||
ArrayConstraint: foldDelimited('[', ']'),
|
||||
MatchExpression: foldDelimited('{', '}'),
|
||||
|
||||
Binary file not shown.
@@ -28,7 +28,7 @@ await init();
|
||||
|
||||
const files = {
|
||||
'main.dcdl': 'let schema = import "./schema.dcdl"; in schema.Server',
|
||||
'schema.dcdl': 'Server = App.Server & { port = 8080; };',
|
||||
'schema.dcdl': 'Server = { port = 8080; } as App.Server;',
|
||||
};
|
||||
|
||||
const service = new DecodalLanguageService({
|
||||
@@ -64,6 +64,6 @@ console.log(JSON.parse(completion));
|
||||
|
||||
`globals`, `loadImport`, and `completeImport` are host-owned. The package does not assume a filesystem or virtual project model. Import callbacks are synchronous; preload or cache remote content before evaluation.
|
||||
|
||||
Plain strings, numbers, booleans, arrays, and objects are concrete host values. Use `{ $decodal: 'String' | 'Int' | 'Float' | 'Bool' }` for primitive schemas and `{ $decodal: 'Array', item: value }` for array schemas. Descriptors also accept `constraints` and `default`.
|
||||
Plain strings, numbers, booleans, arrays, and objects are concrete host values. Use `{ $decodal: 'String' | 'Int' | 'Float' | 'Bool' }` for primitive schemas, `{ $decodal: 'Array', item: value }` for array schemas, and `{ $decodal: 'Map', value: value }` for associative-array schemas. Descriptors also accept `constraints` and `default`.
|
||||
|
||||
Methods return JSON strings so callers can handle diagnostics and successful results without depending on Rust data structures.
|
||||
|
||||
+8
@@ -10,6 +10,7 @@ export type DecodalHostValue =
|
||||
| { [field: string]: DecodalHostValue }
|
||||
| DecodalPrimitiveDescriptor
|
||||
| DecodalArrayDescriptor
|
||||
| DecodalMapDescriptor
|
||||
| DecodalAbstractDescriptor;
|
||||
|
||||
export type DecodalPrimitiveType = 'String' | 'Int' | 'Float' | 'Bool';
|
||||
@@ -33,6 +34,13 @@ export interface DecodalArrayDescriptor {
|
||||
default?: DecodalHostValue;
|
||||
}
|
||||
|
||||
export interface DecodalMapDescriptor {
|
||||
$decodal: 'Map';
|
||||
value: DecodalHostValue;
|
||||
constraints?: DecodalConstraint[];
|
||||
default?: DecodalHostValue;
|
||||
}
|
||||
|
||||
export interface DecodalAbstractDescriptor {
|
||||
$decodal: 'Abstract';
|
||||
constraints?: DecodalConstraint[];
|
||||
|
||||
Binary file not shown.
@@ -13,6 +13,7 @@ export {
|
||||
export type {
|
||||
DecodalAbstractDescriptor,
|
||||
DecodalArrayDescriptor,
|
||||
DecodalMapDescriptor,
|
||||
DecodalConstraint,
|
||||
DecodalEnvironment,
|
||||
DecodalHostValue,
|
||||
|
||||
@@ -18,6 +18,7 @@ export type DecodalHostValue =
|
||||
| { [field: string]: DecodalHostValue }
|
||||
| DecodalPrimitiveDescriptor
|
||||
| DecodalArrayDescriptor
|
||||
| DecodalMapDescriptor
|
||||
| DecodalAbstractDescriptor;
|
||||
|
||||
export type DecodalPrimitiveType = 'String' | 'Int' | 'Float' | 'Bool';
|
||||
@@ -41,6 +42,13 @@ export interface DecodalArrayDescriptor {
|
||||
default?: DecodalHostValue;
|
||||
}
|
||||
|
||||
export interface DecodalMapDescriptor {
|
||||
$decodal: 'Map';
|
||||
value: DecodalHostValue;
|
||||
constraints?: DecodalConstraint[];
|
||||
default?: DecodalHostValue;
|
||||
}
|
||||
|
||||
export interface DecodalAbstractDescriptor {
|
||||
$decodal: 'Abstract';
|
||||
constraints?: DecodalConstraint[];
|
||||
@@ -131,7 +139,7 @@ await init();
|
||||
|
||||
const files = {
|
||||
'main.dcdl': 'let schema = import "./schema.dcdl"; in schema.Server',
|
||||
'schema.dcdl': 'Server = App.Server & { port = 8080; };',
|
||||
'schema.dcdl': 'Server = { port = 8080; } as App.Server;',
|
||||
};
|
||||
|
||||
const service = new DecodalLanguageService({
|
||||
@@ -167,7 +175,7 @@ console.log(JSON.parse(completion));
|
||||
|
||||
\`globals\`, \`loadImport\`, and \`completeImport\` are host-owned. The package does not assume a filesystem or virtual project model. Import callbacks are synchronous; preload or cache remote content before evaluation.
|
||||
|
||||
Plain strings, numbers, booleans, arrays, and objects are concrete host values. Use \`{ $decodal: 'String' | 'Int' | 'Float' | 'Bool' }\` for primitive schemas and \`{ $decodal: 'Array', item: value }\` for array schemas. Descriptors also accept \`constraints\` and \`default\`.
|
||||
Plain strings, numbers, booleans, arrays, and objects are concrete host values. Use \`{ $decodal: 'String' | 'Int' | 'Float' | 'Bool' }\` for primitive schemas, \`{ $decodal: 'Array', item: value }\` for array schemas, and \`{ $decodal: 'Map', value: value }\` for associative-array schemas. Descriptors also accept \`constraints\` and \`default\`.
|
||||
|
||||
Methods return JSON strings so callers can handle diagnostics and successful results without depending on Rust data structures.
|
||||
`,
|
||||
|
||||
@@ -15,6 +15,13 @@ test('injects one JavaScript host environment into evaluation and completion', a
|
||||
globals: {
|
||||
App: {
|
||||
enabled: { $decodal: 'Bool', default: true },
|
||||
Services: {
|
||||
$decodal: 'Map',
|
||||
value: {
|
||||
port: { $decodal: 'Int' },
|
||||
active: { $decodal: 'Bool', default: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
loadImport(_currentKey, specifier) {
|
||||
@@ -39,10 +46,11 @@ test('injects one JavaScript host environment into evaluation and completion', a
|
||||
const evaluated = JSON.parse(service.evaluate(
|
||||
'main.dcdl',
|
||||
'main.dcdl',
|
||||
'let s = import "./schema.dcdl"; in { server = s.Server & { port = 8080; }; enabled = App.enabled; post = import "./post.md"; }',
|
||||
'let s = import "./schema.dcdl"; in { server = { port = 8080; } as s.Server; services = { api = { port = 8081; }; } as App.Services; enabled = App.enabled; post = import "./post.md" as { frontmatter = { draft = Bool; }; body = String; }; }',
|
||||
));
|
||||
assert.equal(evaluated.ok, true, evaluated.error);
|
||||
assert.match(evaluated.output, /"port": 8080/);
|
||||
assert.match(evaluated.output, /"active": true/);
|
||||
assert.match(evaluated.output, /"body": "# Hello"/);
|
||||
|
||||
const member = JSON.parse(service.complete('main.dcdl', 'App.en', 6, false));
|
||||
|
||||
Reference in New Issue
Block a user