From dfc47a63aff853a71d92b515b211cd21f5d1ac80 Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Mon, 20 Jun 2022 12:21:24 +0000 Subject: [PATCH] refactor: parser and grammar compatibility --- --- /dev/null +++ b/cmds/jrsonnet-fmt/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "jrsonnet-fmt" +version = "0.1.0" +edition = "2021" + +[dependencies] +dprint-core = "0.58.2" +jrsonnet-rowan-parser = { path = "../../crates/jrsonnet-rowan-parser" } --- /dev/null +++ b/cmds/jrsonnet-fmt/src/main.rs @@ -0,0 +1,513 @@ +use std::any::type_name; + +use dprint_core::formatting::{PrintItems, PrintOptions, Signal}; +use jrsonnet_rowan_parser::{ + nodes::{ + ArgsDesc, Assertion, BinaryOperator, Bind, CompSpec, Destruct, DestructArrayPart, + DestructRest, Expr, Field, FieldName, ForSpec, IfSpec, ImportKind, LhsExpr, Literal, + Member, Name, Number, ObjBody, ObjLocal, ParamsDesc, SliceDesc, SourceFile, String, + UnaryOperator, + }, + AstToken, SyntaxToken, +}; + +pub trait Printable { + fn print(&self) -> PrintItems; +} + +macro_rules! pi { + (@i; $($t:tt)*) => {{ + #[allow(unused_mut)] + let mut o = PrintItems::new(); + pi!(@s; o: $($t)*); + o + }}; + (@s; $o:ident: str($e:expr $(,)?) $($t:tt)*) => {{ + $o.push_str($e); + pi!(@s; $o: $($t)*); + }}; + (@s; $o:ident: nl $($t:tt)*) => {{ + $o.push_signal(Signal::NewLine); + pi!(@s; $o: $($t)*); + }}; + (@s; $o:ident: >i $($t:tt)*) => {{ + $o.push_signal(Signal::StartIndent); + pi!(@s; $o: $($t)*); + }}; + (@s; $o:ident: {{ + $o.push_signal(Signal::FinishIndent); + pi!(@s; $o: $($t)*); + }}; + (@s; $o:ident: {$expr:expr} $($t:tt)*) => {{ + $o.extend($expr.print()); + pi!(@s; $o: $($t)*); + }}; + (@s; $o:ident: if ($e:expr)($($then:tt)*) $($t:tt)*) => {{ + if $e { + pi!(@s; $o: $($then)*); + } + pi!(@s; $o: $($t)*); + }}; + (@s; $o:ident: ifelse ($e:expr)($($then:tt)*)($($else:tt)*) $($t:tt)*) => {{ + if $e { + pi!(@s; $o: $($then)*); + } else { + pi!(@s; $o: $($else)*); + } + pi!(@s; $o: $($t)*); + }}; + (@s; $i:ident:) => {} +} +macro_rules! p { + (new: $($t:tt)*) => { + pi!(@i; $($t)*) + }; + ($o:ident: $($t:tt)*) => { + pi!(@s; $o: $($t)*) + }; +} + +impl

Printable for Option

+where + P: Printable, +{ + fn print(&self) -> PrintItems { + if let Some(v) = self { + v.print() + } else { + p!(new: str( + &format!( + "/*missing {}*/", + type_name::

().replace("jrsonnet_rowan_parser::generated::nodes::", "") + ), + )) + } + } +} + +impl Printable for SyntaxToken { + fn print(&self) -> PrintItems { + p!(new: str(&self.to_string())) + } +} + +impl Printable for String { + fn print(&self) -> PrintItems { + p!(new: str(&format!("{}", self))) + } +} +impl Printable for Number { + fn print(&self) -> PrintItems { + p!(new: str(&format!("{}", self))) + } +} + +impl Printable for Name { + fn print(&self) -> PrintItems { + p!(new: {self.ident_lit()}) + } +} + +impl Printable for DestructRest { + fn print(&self) -> PrintItems { + let mut pi = p!(new: str("...")); + if let Some(name) = self.into() { + p!(pi: {name}); + } + pi + } +} + +impl Printable for Destruct { + fn print(&self) -> PrintItems { + let mut pi = p!(new:); + match self { + Destruct::DestructFull(f) => { + p!(pi: {f.name()}) + } + Destruct::DestructSkip(_) => p!(pi: str("?")), + Destruct::DestructArray(a) => { + p!(pi: str("[") >i nl); + for el in a.destruct_array_parts() { + match el { + DestructArrayPart::DestructArrayElement(e) => { + p!(pi: {e.destruct()} str(",") nl) + } + DestructArrayPart::DestructRest(d) => { + p!(pi: {d} str(",") nl) + } + } + } + p!(pi: { + p!(pi: str("{") >i nl); + for item in o.destruct_object_fields() { + p!(pi: {item.field()}); + if let Some(des) = item.destruct() { + p!(pi: str(": ") {des}) + } + if let Some(def) = item.expr() { + p!(pi: str(" = ") {def}); + } + p!(pi: str(",") nl); + } + if let Some(rest) = o.destruct_rest() { + p!(pi: {rest} nl) + } + p!(pi: PrintItems { + match self { + FieldName::FieldNameFixed(f) => { + if let Some(id) = f.id() { + p!(new: {id}) + } else if let Some(str) = f.string() { + p!(new: {str}) + } else { + p!(new: str("/*missing FieldName*/")) + } + } + FieldName::FieldNameDynamic(d) => { + p!(new: str("[") {d.expr()} str("]")) + } + } + } +} +impl Printable for Field { + fn print(&self) -> PrintItems { + let mut pi = p!(new:); + match self { + Field::FieldNormal(n) => { + p!(pi: {n.field_name()}); + if n.plus_token().is_some() { + p!(pi: str("+")); + } + p!(pi: str(": ") {n.expr()}); + } + Field::FieldMethod(m) => { + p!(pi: {m.field_name()} {m.params_desc()} str(": ") {m.expr()}); + } + } + pi + } +} + +impl Printable for ObjLocal { + fn print(&self) -> PrintItems { + p!(new: str("local ") {self.bind()}) + } +} + +impl Printable for Assertion { + fn print(&self) -> PrintItems { + let mut pi = p!(new: str("assert ") {self.condition()}); + if self.colon_token().is_some() || self.message().is_some() { + p!(pi: str(": ") {self.message()}) + } + pi + } +} + +impl Printable for ParamsDesc { + fn print(&self) -> PrintItems { + let mut pi = p!(new: str("(") >i nl); + for param in self.params() { + p!(pi: {param.destruct()}); + if param.assign_token().is_some() || param.expr().is_some() { + p!(pi: str(" = ") {param.expr()}) + } + p!(pi: str(",") nl) + } + p!(pi: PrintItems { + let mut pi = p!(new: str("(") >i nl); + for arg in self.args() { + if arg.name().is_some() || arg.assign_token().is_some() { + p!(pi: {arg.name()} str(" = ")); + } + p!(pi: {arg.expr()} str(",") nl) + } + p!(pi: PrintItems { + let mut pi = p!(new: str("[")); + if self.from().is_some() { + p!(pi: {self.from()}); + } + p!(pi: str(":")); + if self.end().is_some() { + p!(pi: {self.end().map(|e|e.expr())}) + } + // Keep only one : in case if we don't need step + if self.step().is_some() { + p!(pi: str(":") {self.step().map(|e|e.expr())}); + } + p!(pi: str("]")); + pi + } +} + +impl Printable for ObjBody { + fn print(&self) -> PrintItems { + match self { + ObjBody::ObjBodyComp(_) => todo!(), + ObjBody::ObjBodyMemberList(l) => { + let mut pi = p!(new:); + for mem in l.members() { + match mem { + Member::MemberBindStmt(b) => { + p!(pi: {b.obj_local()}) + } + Member::MemberAssertStmt(ass) => { + p!(pi: {ass.assertion()}) + } + Member::MemberField(f) => { + p!(pi: {f.field()}) + } + } + p!(pi: str(",") nl) + } + pi + } + } + } +} +impl Printable for UnaryOperator { + fn print(&self) -> PrintItems { + p!(new: str(self.text())) + } +} +impl Printable for BinaryOperator { + fn print(&self) -> PrintItems { + p!(new: str(self.text())) + } +} +impl Printable for Bind { + fn print(&self) -> PrintItems { + match self { + Bind::BindDestruct(d) => { + p!(new: {d.into()} str(" = ") {d.value()}) + } + Bind::BindFunction(f) => { + p!(new: str("function") {f.params()} str(" = ") {f.value()}) + } + } + } +} +impl Printable for Literal { + fn print(&self) -> PrintItems { + p!(new: str(&self.syntax().to_string())) + } +} +impl Printable for ImportKind { + fn print(&self) -> PrintItems { + p!(new: str(&self.syntax().to_string())) + } +} +impl Printable for LhsExpr { + fn print(&self) -> PrintItems { + p!(new: {self.expr()}) + } +} +impl Printable for ForSpec { + fn print(&self) -> PrintItems { + p!(new: str("for ") {self.bind()} str(" in ") {self.expr()}) + } +} +impl Printable for IfSpec { + fn print(&self) -> PrintItems { + p!(new: str("if ") {self.expr()}) + } +} +impl Printable for CompSpec { + fn print(&self) -> PrintItems { + match self { + CompSpec::ForSpec(f) => f.print(), + CompSpec::IfSpec(i) => i.print(), + } + } +} +impl Printable for Expr { + fn print(&self) -> PrintItems { + match self { + Expr::ExprBinary(b) => { + p!(new: {b.lhs()} str(" ") {b.binary_operator()} str(" ") {b.rhs()}) + } + Expr::ExprUnary(u) => p!(new: {u.unary_operator()} {u.rhs()}), + Expr::ExprSlice(s) => { + p!(new: {s.expr()} {s.slice_desc()}) + } + Expr::ExprIndex(i) => { + p!(new: {i.expr()} str(".") {i.index()}) + } + Expr::ExprIndexExpr(i) => p!(new: {i.base()} str("[") {i.index()} str("]")), + Expr::ExprApply(a) => { + let mut pi = p!(new: {a.expr()} {a.args_desc()}); + if a.tailstrict_kw_token().is_some() { + p!(pi: str(" tailstrict")); + } + pi + } + Expr::ExprObjExtend(ex) => { + p!(new: {ex.lhs_expr()} str(" ") {ex.expr()}) + } + Expr::ExprParened(p) => { + p!(new: str("(") {p.expr()} str(")")) + } + Expr::ExprIntrinsicThisFile(_) => p!(new: str("$intrinsicThisFile")), + Expr::ExprIntrinsicId(_) => p!(new: str("$intrinsicId")), + Expr::ExprIntrinsic(i) => p!(new: str("$intrinsic(") {i.name()} str(")")), + Expr::ExprString(s) => p!(new: {s.string()}), + Expr::ExprNumber(n) => p!(new: {n.number()}), + Expr::ExprArray(a) => { + let mut pi = p!(new: str("[") >i nl); + for el in a.exprs() { + p!(pi: {el} str(",") nl); + } + p!(pi: { + p!(new: str("{") >i nl {o.obj_body()} { + let mut pi = p!(new: str("[") {arr.expr()}); + for spec in arr.comp_specs() { + p!(pi: str(" ") {spec}); + } + p!(pi: str("]")); + pi + } + Expr::ExprImport(v) => { + p!(new: {v.import_kind()} str(" ") {v.string()}) + } + Expr::ExprVar(n) => p!(new: {n.name()}), + Expr::ExprLocal(l) => { + let mut pi = p!(new: str("local") >i nl); + for bind in l.binds() { + p!(pi: {bind} str(",") nl); + } + p!(pi: { + let mut pi = + p!(new: str("if ") {ite.cond()} str(" then ") {ite.then().map(|t| t.expr())}); + if ite.else_kw_token().is_some() || ite.else_().is_some() { + p!(pi: str(" else ") {ite.else_().map(|t| t.expr())}) + } + pi + } + Expr::ExprFunction(f) => p!(new: str("function") {f.params_desc()} str(" ") {f.expr()}), + Expr::ExprAssert(a) => p!(new: {a.assertion()} str("; ") {a.expr()}), + Expr::ExprError(e) => p!(new: str("error ") {e.expr()}), + Expr::ExprLiteral(l) => { + p!(new: {l.literal()}) + } + } + } +} + +impl Printable for SourceFile { + fn print(&self) -> PrintItems { + assert!(self.expr().is_some()); + self.expr().print() + } +} + +fn main() { + let (parsed, _errors) = jrsonnet_rowan_parser::parse( + r#" + + + # Edit me! + local b = import "b.libsonnet"; # comment + local a = import "a.libsonnet"; + + local f(x,y)=x+y; + + local {a: [b, ..., c], d, ...e} = null; + + local ass = assert false : false; false; + + local fn = function(a, b, c = 3) 4; + + local comp = [a for b in c if d == e]; + local ocomp = {[k]: 1 for k in v}; + + local ? = skip; + + local intr = $intrinsic(test); + local intrId = $intrinsicId; + local intrThisFile = $intrinsicThisFile; + + local ie = a[expr]; + + local unary = !a; + + local Template = {z: "foo"}; + + { + local + + h = 3, + assert self.a == 1 + + : "error", + "f": ((((((3)))))) , + "g g": + f(4,2), + arr: [[ + 1, 2, + ], + 3, + { + b: { + c: { + k: [16] + } + } + } + ], + m: a[1::], + m: b[::], + k: if a == b then + + + 2 + + else Template {} + } + Template + + +"#, + ); + + // dbg!(errors); + dbg!(&parsed); + + let o = dprint_core::formatting::format( + || parsed.print(), + PrintOptions { + indent_width: 2, + max_width: 100, + use_tabs: false, + new_line_text: "\n", + }, + ); + println!("{}", o); +} --- a/crates/jrsonnet-rowan-parser/Cargo.toml +++ b/crates/jrsonnet-rowan-parser/Cargo.toml @@ -19,3 +19,4 @@ indoc = "1.0.3" insta = "1.10.0" anyhow = "1.0.57" +jrsonnet-stdlib = { path = "../jrsonnet-stdlib" } --- a/crates/jrsonnet-rowan-parser/jsonnet.ungram +++ b/crates/jrsonnet-rowan-parser/jsonnet.ungram @@ -1,7 +1,12 @@ +// This file describes structure of jsonnet source code +// It is also used to generate files in src/generated + +// Token names ending with `!` are considered meta, and handled specifically + SourceFile = Expr ExprBinary = - lhs:Expr + lhs:LhsExpr BinaryOperator rhs:Expr ExprUnary = @@ -9,29 +14,23 @@ rhs:Expr ExprSlice = Expr - '[' SliceDesc - ']' ExprIndex = Expr '.' index:Name ExprIndexExpr = - base:Expr + base:LhsExpr '[' index:Expr ']' ExprApply = Expr - '(' ArgsDesc - ')' 'tailstrict'? ExprObjExtend = + LhsExpr Expr - '{' - ObjBody - '}' ExprParened = '(' Expr @@ -64,13 +63,16 @@ '[' Expr ','? - ForSpec CompSpec* ']' + ExprImport = - 'importstr' String -| 'importbin' String -| 'import' String + ImportKind String + +ImportKind = + 'importstr' +| 'importbin' +| 'import' ExprVar = name:Name @@ -78,12 +80,15 @@ 'local' (Bind (',' Bind)* ','?) ';' + Expr + ExprIfThenElse = 'if' cond:Expr 'then' - then:Expr - ('else' else_:Expr)? + then:TrueExpr + ('else' else_:FalseExpr)? + ExprFunction = 'function' '(' @@ -112,6 +117,7 @@ | ExprIntrinsic | ExprString | ExprNumber +| ExprLiteral | ExprArray | ExprObject | ExprArrayComp @@ -130,42 +136,48 @@ | '<<' | '>>' | '+' | '-' | '*' | '/' | '%' +| 'ERROR_NO_OPERATOR!' UnaryOperator = '-' | '!' | '~' +SliceDescEnd=Expr +SliceDescStep=Expr SliceDesc = + '[' from:Expr? ':' ( - end:Expr? + end:SliceDescEnd? ( ':' - step:Expr? + step:SliceDescStep? )? )? + ']' Name = - 'ident' + 'LIT_IDENT!' ArgsDesc = + '(' (Arg (',' Arg)* ','?)? + ')' Arg = (name:Name '=')? Expr ObjBodyComp = pre:ObjLocalPostComma* '[' - key:Expr + key:LhsExpr ']' '+'? ':' value:Expr post:ObjLocalPreComma* - ForSpec CompSpec* ObjBodyMemberList = - (Member (',' Member) ','?)? + (Member (',' Member)* ','?)? ObjBody = ObjBodyComp | ObjBodyMemberList @@ -196,9 +208,7 @@ Expr FieldMethod = FieldName - '(' ParamsDesc - ')' Visibility Expr Field = @@ -230,14 +240,15 @@ | 'super' String = - 'string_double' -| 'string_single' -| 'string_double_verbatim' -| 'string_single_verbatim' -| 'string_block' + 'LIT_STRING_DOUBLE!' +| 'LIT_STRING_SINGLE!' +| 'LIT_STRING_DOUBLE_VERBATIM!' +| 'LIT_STRING_SINGLE_VERBATIM!' +| 'LIT_STRING_BLOCK!' Number = - 'number' + 'LIT_FLOAT!' +| 'META_FORCE_ENUM!' ForSpec = 'for' @@ -257,9 +268,7 @@ value:Expr BindFunction = name:Name - '(' params:ParamsDesc - ')' '=' value:Expr Bind = @@ -267,7 +276,9 @@ | BindFunction ParamsDesc = + '(' (Param (',' Param)* ','?)? + ')' Param = Destruct ( @@ -277,30 +288,23 @@ Assertion = 'assert' - condition:Expr + condition:LhsExpr ( ':' - Expr + message:Expr )? DestructFull = - into:Name + Name DestructSkip = '?' DestructArray = '[' - start:( - Destruct - (',' Destruct)* + ( + DestructArrayPart + (',' DestructArrayPart)* ','? )? - DestructRest? - ','? - end:( - Destruct - (',' Destruct)* - ','? - ) ']' DestructObject = '{' @@ -314,10 +318,16 @@ '}' Destruct = DestructFull - DestructSkip - DestructArray - DestructObject +| DestructSkip +| DestructArray +| DestructObject +DestructArrayElement = + Destruct +DestructArrayPart = + DestructArrayElement +| DestructRest + DestructRest = '...' into:Name? @@ -332,3 +342,8 @@ '=' Expr )? + +// Aliases used to resolve node type conflicts +TrueExpr=Expr +FalseExpr=Expr +LhsExpr=Expr --- a/crates/jrsonnet-rowan-parser/src/ast.rs +++ b/crates/jrsonnet-rowan-parser/src/ast.rs @@ -1 +1,95 @@ -pub trait AstToken {} +use std::marker::PhantomData; + +use crate::{SyntaxKind, SyntaxNode, SyntaxNodeChildren, SyntaxToken}; + +/// The main trait to go from untyped `SyntaxNode` to a typed ast. The +/// conversion itself has zero runtime cost: ast and syntax nodes have exactly +/// the same representation: a pointer to the tree root and a pointer to the +/// node itself. +pub trait AstNode { + fn can_cast(kind: SyntaxKind) -> bool + where + Self: Sized; + + fn cast(syntax: SyntaxNode) -> Option + where + Self: Sized; + + fn syntax(&self) -> &SyntaxNode; + fn clone_for_update(&self) -> Self + where + Self: Sized, + { + Self::cast(self.syntax().clone_for_update()).unwrap() + } + fn clone_subtree(&self) -> Self + where + Self: Sized, + { + Self::cast(self.syntax().clone_subtree()).unwrap() + } +} + +/// Like `AstNode`, but wraps tokens rather than interior nodes. +pub trait AstToken { + fn can_cast(token: SyntaxKind) -> bool + where + Self: Sized; + + fn cast(syntax: SyntaxToken) -> Option + where + Self: Sized; + + fn syntax(&self) -> &SyntaxToken; + + fn text(&self) -> &str { + self.syntax().text() + } +} + +#[derive(Debug, Clone)] +pub struct AstChildren { + inner: SyntaxNodeChildren, + ph: PhantomData, +} + +impl AstChildren { + fn new(parent: &SyntaxNode) -> Self { + AstChildren { + inner: parent.children(), + ph: PhantomData, + } + } +} + +impl Iterator for AstChildren { + type Item = N; + fn next(&mut self) -> Option { + self.inner.find_map(N::cast) + } +} + +pub mod support { + use super::{AstChildren, AstNode, AstToken, SyntaxKind, SyntaxNode, SyntaxToken}; + + pub fn child(parent: &SyntaxNode) -> Option { + parent.children().find_map(N::cast) + } + pub fn token_child(parent: &SyntaxNode) -> Option { + parent.children_with_tokens().find_map(|n| match n { + rowan::NodeOrToken::Node(_) => None, + rowan::NodeOrToken::Token(t) => N::cast(t), + }) + } + + pub fn children(parent: &SyntaxNode) -> AstChildren { + AstChildren::new(parent) + } + + pub fn token(parent: &SyntaxNode, kind: SyntaxKind) -> Option { + parent + .children_with_tokens() + .filter_map(|it| it.into_token()) + .find(|it| it.kind() == kind) + } +} --- a/crates/jrsonnet-rowan-parser/src/binary.rs +++ b/crates/jrsonnet-rowan-parser/src/binary.rs @@ -20,6 +20,7 @@ Or, In, ObjectApply, + #[allow(dead_code)] Invalid, } --- /dev/null +++ b/crates/jrsonnet-rowan-parser/src/classify.rs @@ -0,0 +1,51 @@ +use crate::SyntaxKind; + +impl SyntaxKind { + pub fn is_trivia(self) -> bool { + matches!( + self, + Self::WHITESPACE + | Self::MULTI_LINE_COMMENT + | Self::ERROR_COMMENT_TOO_SHORT + | Self::ERROR_COMMENT_UNTERMINATED + | Self::SINGLE_LINE_HASH_COMMENT + | Self::SINGLE_LINE_SLASH_COMMENT + ) + } + pub fn is_string(self) -> bool { + matches!( + self, + Self::STRING_SINGLE + | Self::ERROR_STRING_SINGLE_UNTERMINATED + | Self::STRING_DOUBLE + | Self::ERROR_STRING_DOUBLE_UNTERMINATED + | Self::STRING_SINGLE_VERBATIM + | Self::ERROR_STRING_SINGLE_VERBATIM_UNTERMINATED + | Self::STRING_DOUBLE_VERBATIM + | Self::ERROR_STRING_DOUBLE_VERBATIM_UNTERMINATED + | Self::STRING_BLOCK + | Self::ERROR_STRING_BLOCK_UNEXPECTED_END + | Self::ERROR_STRING_BLOCK_MISSING_NEW_LINE + | Self::ERROR_STRING_BLOCK_MISSING_TERMINATION + | Self::ERROR_STRING_BLOCK_MISSING_INDENT + ) + } + pub fn is_number(self) -> bool { + matches!( + self, + Self::FLOAT + | Self::ERROR_FLOAT_JUNK_AFTER_POINT + | Self::ERROR_FLOAT_JUNK_AFTER_EXPONENT + | Self::ERROR_FLOAT_JUNK_AFTER_EXPONENT_SIGN + ) + } + pub fn is_literal(self) -> bool { + matches!( + self, + Self::NULL_KW + | Self::TRUE_KW | Self::FALSE_KW + | Self::SELF_KW | Self::DOLLAR + | Self::SUPER_KW + ) + } +} --- a/crates/jrsonnet-rowan-parser/src/event.rs +++ b/crates/jrsonnet-rowan-parser/src/event.rs @@ -1,6 +1,6 @@ use std::mem; -use rowan::{GreenNode, GreenNodeBuilder, Language}; +use rowan::{GreenNodeBuilder, Language}; use crate::{ lex::Lexeme, @@ -10,14 +10,27 @@ #[derive(Clone, Debug, PartialEq, Eq)] pub enum Event { + /// Used for unfinished markers + Pending, + /// After marker is completed, Pending event is replaced with Start Start { kind: SyntaxKind, + /// If marker is preceded or wrapped - instead of reordering events, we + /// insert start event in the end of events Vec instead, and store relative offset to this event here forward_parent: Option, }, - Token, - Finish, - Placeholder, + /// Eat token + Token { + kind: SyntaxKind, + }, + /// Position of finished node + Finish { + /// Same as forward_parent of Start, but for wrapping + wrapper: Option, + }, Error(SyntaxError), + /// Used for dropped markers and other things + Noop, } pub(super) struct Sink<'i> { @@ -40,12 +53,17 @@ } pub(super) fn finish(mut self) -> Parse { + let mut eat_start_whitespace = false; + let mut depth = 0; for idx in 0..self.events.len() { - match mem::replace(&mut self.events[idx], Event::Placeholder) { + match mem::replace(&mut self.events[idx], Event::Noop) { Event::Start { kind, forward_parent, } => { + if depth != 0 { + self.skip_whitespace(); + } let mut kinds = vec![kind]; let mut idx = idx; @@ -60,7 +78,7 @@ forward_parent = if let Event::Start { kind, forward_parent, - } = mem::replace(&mut self.events[idx], Event::Placeholder) + } = mem::replace(&mut self.events[idx], Event::Noop) { kinds.push(kind); forward_parent @@ -71,18 +89,46 @@ for kind in kinds.into_iter().rev() { self.builder.start_node(JsonnetLanguage::kind_to_raw(kind)); + depth += 1; + if depth == 1 { + self.skip_whitespace(); + } + } + + eat_start_whitespace = false; + } + Event::Token { kind } => { + if eat_start_whitespace { + self.skip_whitespace(); } + self.token(kind); + eat_start_whitespace = true; } - Event::Token => self.token(), - Event::Finish => { + Event::Finish { wrapper } => { self.builder.finish_node(); + depth -= 1; + let mut idx = idx; + let mut wrapper = wrapper; + while let Some(w) = wrapper { + idx += w; + wrapper = if let Event::Finish { wrapper } = + mem::replace(&mut self.events[idx], Event::Noop) + { + self.builder.finish_node(); + depth -= 1; + wrapper + } else { + unreachable!() + } + } + eat_start_whitespace = true; } - Event::Placeholder => {} + Event::Pending => panic!("placeholder should not end in events"), + Event::Noop => {} Event::Error(e) => { self.errors.push(e); } } - self.skip_whitespace(); } Parse { @@ -90,10 +136,10 @@ errors: self.errors, } } - fn token(&mut self) { + fn token(&mut self, kind: SyntaxKind) { let lexeme = self.lexemes[self.offset]; self.builder - .token(JsonnetLanguage::kind_to_raw(lexeme.kind), lexeme.text); + .token(JsonnetLanguage::kind_to_raw(kind), lexeme.text); self.offset += 1; } fn skip_whitespace(&mut self) { @@ -102,7 +148,7 @@ break; } - self.token(); + self.token(lexeme.kind); } } } --- a/crates/jrsonnet-rowan-parser/src/generated/mod.rs +++ b/crates/jrsonnet-rowan-parser/src/generated/mod.rs @@ -1,3 +1,2 @@ -// mod tokens; -// mod nodes; +pub mod nodes; pub mod syntax_kinds; --- a/crates/jrsonnet-rowan-parser/src/generated/nodes.rs +++ b/crates/jrsonnet-rowan-parser/src/generated/nodes.rs @@ -1,9 +1,9 @@ //! This is a generated file, please do not edit manually. Changes can be //! made in codegeneration that lives in `xtask` top-level dir. -#![allow(non_snake_case)] +#![allow(non_snake_case, clippy::match_like_matches_macro)] use crate::{ - ast::{self, support, AstChildren, AstNode}, + ast::{support, AstChildren, AstNode, AstToken}, SyntaxKind::{self, *}, SyntaxNode, SyntaxToken, T, }; @@ -13,7 +13,9 @@ pub(crate) syntax: SyntaxNode, } impl SourceFile { - pub fn expr(&self) -> Option { support::child(&self.syntax) } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -21,35 +23,25 @@ pub(crate) syntax: SyntaxNode, } impl ExprBinary { - pub fn lhs(&self) -> Option { support::child(&self.syntax) } - pub fn binary_operator(&self) -> Option { support::child(&self.syntax) } - pub fn rhs(&self) -> Option { support::child(&self.syntax) } + pub fn lhs(&self) -> Option { + support::child(&self.syntax) + } + pub fn binary_operator(&self) -> Option { + support::token_child(&self.syntax) + } + pub fn rhs(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct BinaryOperator { +pub struct LhsExpr { pub(crate) syntax: SyntaxNode, } -impl BinaryOperator { - pub fn or_token(&self) -> Option { support::token(&self.syntax, T![||]) } - pub fn and_token(&self) -> Option { support::token(&self.syntax, T![&&]) } - pub fn bit_or_token(&self) -> Option { support::token(&self.syntax, T![|]) } - pub fn bit_xor_token(&self) -> Option { support::token(&self.syntax, T![^]) } - pub fn bit_and_token(&self) -> Option { support::token(&self.syntax, T![&]) } - pub fn eq_token(&self) -> Option { support::token(&self.syntax, T![==]) } - pub fn ne_token(&self) -> Option { support::token(&self.syntax, T![!=]) } - pub fn lt_token(&self) -> Option { support::token(&self.syntax, T![<]) } - pub fn gt_token(&self) -> Option { support::token(&self.syntax, T![>]) } - pub fn le_token(&self) -> Option { support::token(&self.syntax, T![<=]) } - pub fn ge_token(&self) -> Option { support::token(&self.syntax, T![>=]) } - pub fn in_token(&self) -> Option { support::token(&self.syntax, T![in]) } - pub fn lhs_token(&self) -> Option { support::token(&self.syntax, T![<<]) } - pub fn rhs_token(&self) -> Option { support::token(&self.syntax, T![>>]) } - pub fn plus_token(&self) -> Option { support::token(&self.syntax, T![+]) } - pub fn minus_token(&self) -> Option { support::token(&self.syntax, T![-]) } - pub fn mul_token(&self) -> Option { support::token(&self.syntax, T![*]) } - pub fn div_token(&self) -> Option { support::token(&self.syntax, T![/]) } - pub fn modulo_token(&self) -> Option { support::token(&self.syntax, T![%]) } +impl LhsExpr { + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -57,29 +49,25 @@ pub(crate) syntax: SyntaxNode, } impl ExprUnary { - pub fn unary_operator(&self) -> Option { support::child(&self.syntax) } - pub fn rhs(&self) -> Option { support::child(&self.syntax) } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct UnaryOperator { - pub(crate) syntax: SyntaxNode, + pub fn unary_operator(&self) -> Option { + support::token_child(&self.syntax) + } + pub fn rhs(&self) -> Option { + support::child(&self.syntax) + } } -impl UnaryOperator { - pub fn minus_token(&self) -> Option { support::token(&self.syntax, T![-]) } - pub fn not_token(&self) -> Option { support::token(&self.syntax, T![!]) } - pub fn bit_not_token(&self) -> Option { support::token(&self.syntax, T![~]) } -} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ExprSlice { pub(crate) syntax: SyntaxNode, } impl ExprSlice { - pub fn expr(&self) -> Option { support::child(&self.syntax) } - pub fn l_brack_token(&self) -> Option { support::token(&self.syntax, T!['[']) } - pub fn slice_desc(&self) -> Option { support::child(&self.syntax) } - pub fn r_brack_token(&self) -> Option { support::token(&self.syntax, T![']']) } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } + pub fn slice_desc(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -87,10 +75,24 @@ pub(crate) syntax: SyntaxNode, } impl SliceDesc { - pub fn from(&self) -> Option { support::child(&self.syntax) } - pub fn colon_token(&self) -> Option { support::token(&self.syntax, T![:]) } - pub fn end(&self) -> Option { support::child(&self.syntax) } - pub fn step(&self) -> Option { support::child(&self.syntax) } + pub fn l_brack_token(&self) -> Option { + support::token(&self.syntax, T!['[']) + } + pub fn from(&self) -> Option { + support::child(&self.syntax) + } + pub fn colon_token(&self) -> Option { + support::token(&self.syntax, T![:]) + } + pub fn end(&self) -> Option { + support::child(&self.syntax) + } + pub fn step(&self) -> Option { + support::child(&self.syntax) + } + pub fn r_brack_token(&self) -> Option { + support::token(&self.syntax, T![']']) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -98,9 +100,15 @@ pub(crate) syntax: SyntaxNode, } impl ExprIndex { - pub fn expr(&self) -> Option { support::child(&self.syntax) } - pub fn dot_token(&self) -> Option { support::token(&self.syntax, T![.]) } - pub fn index(&self) -> Option { support::child(&self.syntax) } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } + pub fn dot_token(&self) -> Option { + support::token(&self.syntax, T![.]) + } + pub fn index(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -108,7 +116,9 @@ pub(crate) syntax: SyntaxNode, } impl Name { - pub fn ident_token(&self) -> Option { support::token(&self.syntax, T![ident]) } + pub fn ident_lit(&self) -> Option { + support::token(&self.syntax, IDENT) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -116,10 +126,18 @@ pub(crate) syntax: SyntaxNode, } impl ExprIndexExpr { - pub fn base(&self) -> Option { support::child(&self.syntax) } - pub fn l_brack_token(&self) -> Option { support::token(&self.syntax, T!['[']) } - pub fn index(&self) -> Option { support::child(&self.syntax) } - pub fn r_brack_token(&self) -> Option { support::token(&self.syntax, T![']']) } + pub fn base(&self) -> Option { + support::child(&self.syntax) + } + pub fn l_brack_token(&self) -> Option { + support::token(&self.syntax, T!['[']) + } + pub fn index(&self) -> Option { + support::child(&self.syntax) + } + pub fn r_brack_token(&self) -> Option { + support::token(&self.syntax, T![']']) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -127,11 +145,13 @@ pub(crate) syntax: SyntaxNode, } impl ExprApply { - pub fn expr(&self) -> Option { support::child(&self.syntax) } - pub fn l_paren_token(&self) -> Option { support::token(&self.syntax, T!['(']) } - pub fn args_desc(&self) -> Option { support::child(&self.syntax) } - pub fn r_paren_token(&self) -> Option { support::token(&self.syntax, T![')']) } - pub fn tailstrict_token(&self) -> Option { + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } + pub fn args_desc(&self) -> Option { + support::child(&self.syntax) + } + pub fn tailstrict_kw_token(&self) -> Option { support::token(&self.syntax, T![tailstrict]) } } @@ -141,7 +161,15 @@ pub(crate) syntax: SyntaxNode, } impl ArgsDesc { - pub fn args(&self) -> AstChildren { support::children(&self.syntax) } + pub fn l_paren_token(&self) -> Option { + support::token(&self.syntax, T!['(']) + } + pub fn args(&self) -> AstChildren { + support::children(&self.syntax) + } + pub fn r_paren_token(&self) -> Option { + support::token(&self.syntax, T![')']) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -149,10 +177,12 @@ pub(crate) syntax: SyntaxNode, } impl ExprObjExtend { - pub fn expr(&self) -> Option { support::child(&self.syntax) } - pub fn l_brace_token(&self) -> Option { support::token(&self.syntax, T!['{']) } - pub fn obj_body(&self) -> Option { support::child(&self.syntax) } - pub fn r_brace_token(&self) -> Option { support::token(&self.syntax, T!['}']) } + pub fn lhs_expr(&self) -> Option { + support::child(&self.syntax) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -160,9 +190,15 @@ pub(crate) syntax: SyntaxNode, } impl ExprParened { - pub fn l_paren_token(&self) -> Option { support::token(&self.syntax, T!['(']) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } - pub fn r_paren_token(&self) -> Option { support::token(&self.syntax, T![')']) } + pub fn l_paren_token(&self) -> Option { + support::token(&self.syntax, T!['(']) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } + pub fn r_paren_token(&self) -> Option { + support::token(&self.syntax, T![')']) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -170,20 +206,9 @@ pub(crate) syntax: SyntaxNode, } impl ExprLiteral { - pub fn literal(&self) -> Option { support::child(&self.syntax) } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Literal { - pub(crate) syntax: SyntaxNode, -} -impl Literal { - pub fn null_token(&self) -> Option { support::token(&self.syntax, T![null]) } - pub fn true_token(&self) -> Option { support::token(&self.syntax, T![true]) } - pub fn false_token(&self) -> Option { support::token(&self.syntax, T![false]) } - pub fn self_token(&self) -> Option { support::token(&self.syntax, T![self]) } - pub fn dollar_token(&self) -> Option { support::token(&self.syntax, T!['$']) } - pub fn super_token(&self) -> Option { support::token(&self.syntax, T![super]) } + pub fn literal(&self) -> Option { + support::token_child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -214,9 +239,15 @@ pub fn intrinsic_token(&self) -> Option { support::token(&self.syntax, T!["$intrinsic"]) } - pub fn l_paren_token(&self) -> Option { support::token(&self.syntax, T!['(']) } - pub fn name(&self) -> Option { support::child(&self.syntax) } - pub fn r_paren_token(&self) -> Option { support::token(&self.syntax, T![')']) } + pub fn l_paren_token(&self) -> Option { + support::token(&self.syntax, T!['(']) + } + pub fn name(&self) -> Option { + support::child(&self.syntax) + } + pub fn r_paren_token(&self) -> Option { + support::token(&self.syntax, T![')']) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -224,28 +255,8 @@ pub(crate) syntax: SyntaxNode, } impl ExprString { - pub fn string(&self) -> Option { support::child(&self.syntax) } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct String { - pub(crate) syntax: SyntaxNode, -} -impl String { - pub fn string_double_token(&self) -> Option { - support::token(&self.syntax, T![string_double]) - } - pub fn string_single_token(&self) -> Option { - support::token(&self.syntax, T![string_single]) - } - pub fn string_double_verbatim_token(&self) -> Option { - support::token(&self.syntax, T![string_double_verbatim]) - } - pub fn string_single_verbatim_token(&self) -> Option { - support::token(&self.syntax, T![string_single_verbatim]) - } - pub fn string_block_token(&self) -> Option { - support::token(&self.syntax, T![string_block]) + pub fn string(&self) -> Option { + support::token_child(&self.syntax) } } @@ -254,25 +265,25 @@ pub(crate) syntax: SyntaxNode, } impl ExprNumber { - pub fn number(&self) -> Option { support::child(&self.syntax) } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Number { - pub(crate) syntax: SyntaxNode, + pub fn number(&self) -> Option { + support::token_child(&self.syntax) + } } -impl Number { - pub fn number_token(&self) -> Option { support::token(&self.syntax, T![number]) } -} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ExprArray { pub(crate) syntax: SyntaxNode, } impl ExprArray { - pub fn l_brack_token(&self) -> Option { support::token(&self.syntax, T!['[']) } - pub fn exprs(&self) -> AstChildren { support::children(&self.syntax) } - pub fn r_brack_token(&self) -> Option { support::token(&self.syntax, T![']']) } + pub fn l_brack_token(&self) -> Option { + support::token(&self.syntax, T!['[']) + } + pub fn exprs(&self) -> AstChildren { + support::children(&self.syntax) + } + pub fn r_brack_token(&self) -> Option { + support::token(&self.syntax, T![']']) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -280,9 +291,15 @@ pub(crate) syntax: SyntaxNode, } impl ExprObject { - pub fn l_brace_token(&self) -> Option { support::token(&self.syntax, T!['{']) } - pub fn obj_body(&self) -> Option { support::child(&self.syntax) } - pub fn r_brace_token(&self) -> Option { support::token(&self.syntax, T!['}']) } + pub fn l_brace_token(&self) -> Option { + support::token(&self.syntax, T!['{']) + } + pub fn obj_body(&self) -> Option { + support::child(&self.syntax) + } + pub fn r_brace_token(&self) -> Option { + support::token(&self.syntax, T!['}']) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -290,38 +307,34 @@ pub(crate) syntax: SyntaxNode, } impl ExprArrayComp { - pub fn l_brack_token(&self) -> Option { support::token(&self.syntax, T!['[']) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } - pub fn comma_token(&self) -> Option { support::token(&self.syntax, T![,]) } - pub fn for_spec(&self) -> Option { support::child(&self.syntax) } - pub fn comp_specs(&self) -> AstChildren { support::children(&self.syntax) } - pub fn r_brack_token(&self) -> Option { support::token(&self.syntax, T![']']) } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ForSpec { - pub(crate) syntax: SyntaxNode, + pub fn l_brack_token(&self) -> Option { + support::token(&self.syntax, T!['[']) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } + pub fn comma_token(&self) -> Option { + support::token(&self.syntax, T![,]) + } + pub fn comp_specs(&self) -> AstChildren { + support::children(&self.syntax) + } + pub fn r_brack_token(&self) -> Option { + support::token(&self.syntax, T![']']) + } } -impl ForSpec { - pub fn for_token(&self) -> Option { support::token(&self.syntax, T![for]) } - pub fn bind(&self) -> Option { support::child(&self.syntax) } - pub fn in_token(&self) -> Option { support::token(&self.syntax, T![in]) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } -} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ExprImport { pub(crate) syntax: SyntaxNode, } impl ExprImport { - pub fn importstr_token(&self) -> Option { - support::token(&self.syntax, T![importstr]) + pub fn import_kind(&self) -> Option { + support::token_child(&self.syntax) } - pub fn string(&self) -> Option { support::child(&self.syntax) } - pub fn importbin_token(&self) -> Option { - support::token(&self.syntax, T![importbin]) + pub fn string(&self) -> Option { + support::token_child(&self.syntax) } - pub fn import_token(&self) -> Option { support::token(&self.syntax, T![import]) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -329,7 +342,9 @@ pub(crate) syntax: SyntaxNode, } impl ExprVar { - pub fn name(&self) -> Option { support::child(&self.syntax) } + pub fn name(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -337,9 +352,18 @@ pub(crate) syntax: SyntaxNode, } impl ExprLocal { - pub fn local_token(&self) -> Option { support::token(&self.syntax, T![local]) } - pub fn binds(&self) -> AstChildren { support::children(&self.syntax) } - pub fn semi_token(&self) -> Option { support::token(&self.syntax, T![;]) } + pub fn local_kw_token(&self) -> Option { + support::token(&self.syntax, T![local]) + } + pub fn binds(&self) -> AstChildren { + support::children(&self.syntax) + } + pub fn semi_token(&self) -> Option { + support::token(&self.syntax, T![;]) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -347,12 +371,44 @@ pub(crate) syntax: SyntaxNode, } impl ExprIfThenElse { - pub fn if_token(&self) -> Option { support::token(&self.syntax, T![if]) } - pub fn cond(&self) -> Option { support::child(&self.syntax) } - pub fn then_token(&self) -> Option { support::token(&self.syntax, T![then]) } - pub fn then(&self) -> Option { support::child(&self.syntax) } - pub fn else_token(&self) -> Option { support::token(&self.syntax, T![else]) } - pub fn else_(&self) -> Option { support::child(&self.syntax) } + pub fn if_kw_token(&self) -> Option { + support::token(&self.syntax, T![if]) + } + pub fn cond(&self) -> Option { + support::child(&self.syntax) + } + pub fn then_kw_token(&self) -> Option { + support::token(&self.syntax, T![then]) + } + pub fn then(&self) -> Option { + support::child(&self.syntax) + } + pub fn else_kw_token(&self) -> Option { + support::token(&self.syntax, T![else]) + } + pub fn else_(&self) -> Option { + support::child(&self.syntax) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct TrueExpr { + pub(crate) syntax: SyntaxNode, +} +impl TrueExpr { + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct FalseExpr { + pub(crate) syntax: SyntaxNode, +} +impl FalseExpr { + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -360,13 +416,21 @@ pub(crate) syntax: SyntaxNode, } impl ExprFunction { - pub fn function_token(&self) -> Option { + pub fn function_kw_token(&self) -> Option { support::token(&self.syntax, T![function]) } - pub fn l_paren_token(&self) -> Option { support::token(&self.syntax, T!['(']) } - pub fn params_desc(&self) -> Option { support::child(&self.syntax) } - pub fn r_paren_token(&self) -> Option { support::token(&self.syntax, T![')']) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } + pub fn l_paren_token(&self) -> Option { + support::token(&self.syntax, T!['(']) + } + pub fn params_desc(&self) -> Option { + support::child(&self.syntax) + } + pub fn r_paren_token(&self) -> Option { + support::token(&self.syntax, T![')']) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -374,7 +438,15 @@ pub(crate) syntax: SyntaxNode, } impl ParamsDesc { - pub fn params(&self) -> AstChildren { support::children(&self.syntax) } + pub fn l_paren_token(&self) -> Option { + support::token(&self.syntax, T!['(']) + } + pub fn params(&self) -> AstChildren { + support::children(&self.syntax) + } + pub fn r_paren_token(&self) -> Option { + support::token(&self.syntax, T![')']) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -382,9 +454,15 @@ pub(crate) syntax: SyntaxNode, } impl ExprAssert { - pub fn assertion(&self) -> Option { support::child(&self.syntax) } - pub fn semi_token(&self) -> Option { support::token(&self.syntax, T![;]) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } + pub fn assertion(&self) -> Option { + support::child(&self.syntax) + } + pub fn semi_token(&self) -> Option { + support::token(&self.syntax, T![;]) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -392,10 +470,18 @@ pub(crate) syntax: SyntaxNode, } impl Assertion { - pub fn assert_token(&self) -> Option { support::token(&self.syntax, T![assert]) } - pub fn condition(&self) -> Option { support::child(&self.syntax) } - pub fn colon_token(&self) -> Option { support::token(&self.syntax, T![:]) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } + pub fn assert_kw_token(&self) -> Option { + support::token(&self.syntax, T![assert]) + } + pub fn condition(&self) -> Option { + support::child(&self.syntax) + } + pub fn colon_token(&self) -> Option { + support::token(&self.syntax, T![:]) + } + pub fn message(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -403,18 +489,48 @@ pub(crate) syntax: SyntaxNode, } impl ExprError { - pub fn error_token(&self) -> Option { support::token(&self.syntax, T![error]) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } + pub fn error_kw_token(&self) -> Option { + support::token(&self.syntax, T![error]) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct SliceDescEnd { + pub(crate) syntax: SyntaxNode, +} +impl SliceDescEnd { + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct SliceDescStep { + pub(crate) syntax: SyntaxNode, +} +impl SliceDescStep { + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Arg { pub(crate) syntax: SyntaxNode, } impl Arg { - pub fn name(&self) -> Option { support::child(&self.syntax) } - pub fn assign_token(&self) -> Option { support::token(&self.syntax, T![=]) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } + pub fn name(&self) -> Option { + support::child(&self.syntax) + } + pub fn assign_token(&self) -> Option { + support::token(&self.syntax, T![=]) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -422,16 +538,33 @@ pub(crate) syntax: SyntaxNode, } impl ObjBodyComp { - pub fn pre(&self) -> AstChildren { support::children(&self.syntax) } - pub fn l_brack_token(&self) -> Option { support::token(&self.syntax, T!['[']) } - pub fn key(&self) -> Option { support::child(&self.syntax) } - pub fn r_brack_token(&self) -> Option { support::token(&self.syntax, T![']']) } - pub fn plus_token(&self) -> Option { support::token(&self.syntax, T![+]) } - pub fn colon_token(&self) -> Option { support::token(&self.syntax, T![:]) } - pub fn value(&self) -> Option { support::child(&self.syntax) } - pub fn post(&self) -> AstChildren { support::children(&self.syntax) } - pub fn for_spec(&self) -> Option { support::child(&self.syntax) } - pub fn comp_specs(&self) -> AstChildren { support::children(&self.syntax) } + pub fn pre(&self) -> AstChildren { + support::children(&self.syntax) + } + pub fn l_brack_token(&self) -> Option { + support::token(&self.syntax, T!['[']) + } + pub fn key(&self) -> Option { + support::child(&self.syntax) + } + pub fn r_brack_token(&self) -> Option { + support::token(&self.syntax, T![']']) + } + pub fn plus_token(&self) -> Option { + support::token(&self.syntax, T![+]) + } + pub fn colon_token(&self) -> Option { + support::token(&self.syntax, T![:]) + } + pub fn value(&self) -> Option { + support::child(&self.syntax) + } + pub fn post(&self) -> AstChildren { + support::children(&self.syntax) + } + pub fn comp_specs(&self) -> AstChildren { + support::children(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -439,8 +572,12 @@ pub(crate) syntax: SyntaxNode, } impl ObjLocalPostComma { - pub fn obj_local(&self) -> Option { support::child(&self.syntax) } - pub fn comma_token(&self) -> Option { support::token(&self.syntax, T![,]) } + pub fn obj_local(&self) -> Option { + support::child(&self.syntax) + } + pub fn comma_token(&self) -> Option { + support::token(&self.syntax, T![,]) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -448,8 +585,12 @@ pub(crate) syntax: SyntaxNode, } impl ObjLocalPreComma { - pub fn comma_token(&self) -> Option { support::token(&self.syntax, T![,]) } - pub fn obj_local(&self) -> Option { support::child(&self.syntax) } + pub fn comma_token(&self) -> Option { + support::token(&self.syntax, T![,]) + } + pub fn obj_local(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -457,8 +598,9 @@ pub(crate) syntax: SyntaxNode, } impl ObjBodyMemberList { - pub fn member(&self) -> Option { support::child(&self.syntax) } - pub fn comma_token(&self) -> Option { support::token(&self.syntax, T![,]) } + pub fn members(&self) -> AstChildren { + support::children(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -466,8 +608,12 @@ pub(crate) syntax: SyntaxNode, } impl ObjLocal { - pub fn local_token(&self) -> Option { support::token(&self.syntax, T![local]) } - pub fn bind(&self) -> Option { support::child(&self.syntax) } + pub fn local_kw_token(&self) -> Option { + support::token(&self.syntax, T![local]) + } + pub fn bind(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -475,7 +621,9 @@ pub(crate) syntax: SyntaxNode, } impl MemberBindStmt { - pub fn obj_local(&self) -> Option { support::child(&self.syntax) } + pub fn obj_local(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -483,7 +631,9 @@ pub(crate) syntax: SyntaxNode, } impl MemberAssertStmt { - pub fn assertion(&self) -> Option { support::child(&self.syntax) } + pub fn assertion(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -491,7 +641,9 @@ pub(crate) syntax: SyntaxNode, } impl MemberField { - pub fn field(&self) -> Option { support::child(&self.syntax) } + pub fn field(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -499,22 +651,18 @@ pub(crate) syntax: SyntaxNode, } impl FieldNormal { - pub fn field_name(&self) -> Option { support::child(&self.syntax) } - pub fn plus_token(&self) -> Option { support::token(&self.syntax, T![+]) } - pub fn visibility(&self) -> Option { support::child(&self.syntax) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Visibility { - pub(crate) syntax: SyntaxNode, -} -impl Visibility { - pub fn coloncoloncolon_token(&self) -> Option { - support::token(&self.syntax, T![:::]) + pub fn field_name(&self) -> Option { + support::child(&self.syntax) + } + pub fn plus_token(&self) -> Option { + support::token(&self.syntax, T![+]) + } + pub fn visibility(&self) -> Option { + support::token_child(&self.syntax) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) } - pub fn coloncolon_token(&self) -> Option { support::token(&self.syntax, T![::]) } - pub fn colon_token(&self) -> Option { support::token(&self.syntax, T![:]) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -522,12 +670,18 @@ pub(crate) syntax: SyntaxNode, } impl FieldMethod { - pub fn field_name(&self) -> Option { support::child(&self.syntax) } - pub fn l_paren_token(&self) -> Option { support::token(&self.syntax, T!['(']) } - pub fn params_desc(&self) -> Option { support::child(&self.syntax) } - pub fn r_paren_token(&self) -> Option { support::token(&self.syntax, T![')']) } - pub fn visibility(&self) -> Option { support::child(&self.syntax) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } + pub fn field_name(&self) -> Option { + support::child(&self.syntax) + } + pub fn params_desc(&self) -> Option { + support::child(&self.syntax) + } + pub fn visibility(&self) -> Option { + support::token_child(&self.syntax) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -535,8 +689,12 @@ pub(crate) syntax: SyntaxNode, } impl FieldNameFixed { - pub fn id(&self) -> Option { support::child(&self.syntax) } - pub fn string(&self) -> Option { support::child(&self.syntax) } + pub fn id(&self) -> Option { + support::child(&self.syntax) + } + pub fn string(&self) -> Option { + support::token_child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -544,39 +702,63 @@ pub(crate) syntax: SyntaxNode, } impl FieldNameDynamic { - pub fn l_brack_token(&self) -> Option { support::token(&self.syntax, T!['[']) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } - pub fn r_brack_token(&self) -> Option { support::token(&self.syntax, T![']']) } + pub fn l_brack_token(&self) -> Option { + support::token(&self.syntax, T!['[']) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } + pub fn r_brack_token(&self) -> Option { + support::token(&self.syntax, T![']']) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct IfSpec { +pub struct ForSpec { pub(crate) syntax: SyntaxNode, } -impl IfSpec { - pub fn if_token(&self) -> Option { support::token(&self.syntax, T![if]) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } +impl ForSpec { + pub fn for_kw_token(&self) -> Option { + support::token(&self.syntax, T![for]) + } + pub fn bind(&self) -> Option { + support::child(&self.syntax) + } + pub fn in_kw_token(&self) -> Option { + support::token(&self.syntax, T![in]) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct BindDestruct { +pub struct IfSpec { pub(crate) syntax: SyntaxNode, } -impl BindDestruct { - pub fn into(&self) -> Option { support::child(&self.syntax) } - pub fn assign_token(&self) -> Option { support::token(&self.syntax, T![=]) } - pub fn value(&self) -> Option { support::child(&self.syntax) } +impl IfSpec { + pub fn if_kw_token(&self) -> Option { + support::token(&self.syntax, T![if]) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Destruct { +pub struct BindDestruct { pub(crate) syntax: SyntaxNode, } -impl Destruct { - pub fn destruct_full(&self) -> Option { support::child(&self.syntax) } - pub fn destruct_skip(&self) -> Option { support::child(&self.syntax) } - pub fn destruct_array(&self) -> Option { support::child(&self.syntax) } - pub fn destruct_object(&self) -> Option { support::child(&self.syntax) } +impl BindDestruct { + pub fn into(&self) -> Option { + support::child(&self.syntax) + } + pub fn assign_token(&self) -> Option { + support::token(&self.syntax, T![=]) + } + pub fn value(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -584,12 +766,18 @@ pub(crate) syntax: SyntaxNode, } impl BindFunction { - pub fn name(&self) -> Option { support::child(&self.syntax) } - pub fn l_paren_token(&self) -> Option { support::token(&self.syntax, T!['(']) } - pub fn params(&self) -> Option { support::child(&self.syntax) } - pub fn r_paren_token(&self) -> Option { support::token(&self.syntax, T![')']) } - pub fn assign_token(&self) -> Option { support::token(&self.syntax, T![=]) } - pub fn value(&self) -> Option { support::child(&self.syntax) } + pub fn name(&self) -> Option { + support::child(&self.syntax) + } + pub fn params(&self) -> Option { + support::child(&self.syntax) + } + pub fn assign_token(&self) -> Option { + support::token(&self.syntax, T![=]) + } + pub fn value(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -597,9 +785,15 @@ pub(crate) syntax: SyntaxNode, } impl Param { - pub fn destruct(&self) -> Option { support::child(&self.syntax) } - pub fn assign_token(&self) -> Option { support::token(&self.syntax, T![=]) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } + pub fn destruct(&self) -> Option { + support::child(&self.syntax) + } + pub fn assign_token(&self) -> Option { + support::token(&self.syntax, T![=]) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -607,7 +801,9 @@ pub(crate) syntax: SyntaxNode, } impl DestructFull { - pub fn into(&self) -> Option { support::child(&self.syntax) } + pub fn name(&self) -> Option { + support::child(&self.syntax) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -615,7 +811,9 @@ pub(crate) syntax: SyntaxNode, } impl DestructSkip { - pub fn question_mark_token(&self) -> Option { support::token(&self.syntax, T![?]) } + pub fn question_mark_token(&self) -> Option { + support::token(&self.syntax, T![?]) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -623,21 +821,15 @@ pub(crate) syntax: SyntaxNode, } impl DestructArray { - pub fn l_brack_token(&self) -> Option { support::token(&self.syntax, T!['[']) } - pub fn start(&self) -> AstChildren { support::children(&self.syntax) } - pub fn destruct_rest(&self) -> Option { support::child(&self.syntax) } - pub fn comma_token(&self) -> Option { support::token(&self.syntax, T![,]) } - pub fn end(&self) -> AstChildren { support::children(&self.syntax) } - pub fn r_brack_token(&self) -> Option { support::token(&self.syntax, T![']']) } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct DestructRest { - pub(crate) syntax: SyntaxNode, -} -impl DestructRest { - pub fn dotdotdot_token(&self) -> Option { support::token(&self.syntax, T![...]) } - pub fn into(&self) -> Option { support::child(&self.syntax) } + pub fn l_brack_token(&self) -> Option { + support::token(&self.syntax, T!['[']) + } + pub fn destruct_array_parts(&self) -> AstChildren { + support::children(&self.syntax) + } + pub fn r_brack_token(&self) -> Option { + support::token(&self.syntax, T![']']) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -645,13 +837,21 @@ pub(crate) syntax: SyntaxNode, } impl DestructObject { - pub fn l_brace_token(&self) -> Option { support::token(&self.syntax, T!['{']) } + pub fn l_brace_token(&self) -> Option { + support::token(&self.syntax, T!['{']) + } pub fn destruct_object_fields(&self) -> AstChildren { support::children(&self.syntax) } - pub fn destruct_rest(&self) -> Option { support::child(&self.syntax) } - pub fn comma_token(&self) -> Option { support::token(&self.syntax, T![,]) } - pub fn r_brace_token(&self) -> Option { support::token(&self.syntax, T!['}']) } + pub fn destruct_rest(&self) -> Option { + support::child(&self.syntax) + } + pub fn comma_token(&self) -> Option { + support::token(&self.syntax, T![,]) + } + pub fn r_brace_token(&self) -> Option { + support::token(&self.syntax, T!['}']) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -659,12 +859,45 @@ pub(crate) syntax: SyntaxNode, } impl DestructObjectField { - pub fn field(&self) -> Option { support::child(&self.syntax) } - pub fn colon_token(&self) -> Option { support::token(&self.syntax, T![:]) } - pub fn destruct(&self) -> Option { support::child(&self.syntax) } - pub fn assign_token(&self) -> Option { support::token(&self.syntax, T![=]) } - pub fn expr(&self) -> Option { support::child(&self.syntax) } + pub fn field(&self) -> Option { + support::child(&self.syntax) + } + pub fn colon_token(&self) -> Option { + support::token(&self.syntax, T![:]) + } + pub fn destruct(&self) -> Option { + support::child(&self.syntax) + } + pub fn assign_token(&self) -> Option { + support::token(&self.syntax, T![=]) + } + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct DestructRest { + pub(crate) syntax: SyntaxNode, +} +impl DestructRest { + pub fn dotdotdot_token(&self) -> Option { + support::token(&self.syntax, T![...]) + } + pub fn into(&self) -> Option { + support::child(&self.syntax) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct DestructArrayElement { + pub(crate) syntax: SyntaxNode, } +impl DestructArrayElement { + pub fn destruct(&self) -> Option { + support::child(&self.syntax) + } +} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Expr { @@ -681,6 +914,7 @@ ExprIntrinsic(ExprIntrinsic), ExprString(ExprString), ExprNumber(ExprNumber), + ExprLiteral(ExprLiteral), ExprArray(ExprArray), ExprObject(ExprObject), ExprArrayComp(ExprArrayComp), @@ -729,8 +963,136 @@ FieldNameFixed(FieldNameFixed), FieldNameDynamic(FieldNameDynamic), } + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum Destruct { + DestructFull(DestructFull), + DestructSkip(DestructSkip), + DestructArray(DestructArray), + DestructObject(DestructObject), +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum DestructArrayPart { + DestructArrayElement(DestructArrayElement), + DestructRest(DestructRest), +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct BinaryOperator { + syntax: SyntaxToken, + kind: BinaryOperatorKind, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum BinaryOperatorKind { + Or, + And, + BitOr, + BitXor, + BitAnd, + Eq, + Ne, + Lt, + Gt, + Le, + Ge, + InKw, + Lhs, + Rhs, + Plus, + Minus, + Mul, + Div, + Modulo, + ErrorNoOperator, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct UnaryOperator { + syntax: SyntaxToken, + kind: UnaryOperatorKind, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum UnaryOperatorKind { + Minus, + Not, + BitNot, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Literal { + syntax: SyntaxToken, + kind: LiteralKind, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum LiteralKind { + NullKw, + TrueKw, + FalseKw, + SelfKw, + Dollar, + SuperKw, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct String { + syntax: SyntaxToken, + kind: StringKind, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum StringKind { + StringDouble, + StringSingle, + StringDoubleVerbatim, + StringSingleVerbatim, + StringBlock, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Number { + syntax: SyntaxToken, + kind: NumberKind, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum NumberKind { + Float, + MetaForceEnum, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ImportKind { + syntax: SyntaxToken, + kind: ImportKindKind, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum ImportKindKind { + ImportstrKw, + ImportbinKw, + ImportKw, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Visibility { + syntax: SyntaxToken, + kind: VisibilityKind, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum VisibilityKind { + Coloncoloncolon, + Coloncolon, + Colon, +} impl AstNode for SourceFile { - fn can_cast(kind: SyntaxKind) -> bool { kind == SOURCE_FILE } + fn can_cast(kind: SyntaxKind) -> bool { + kind == SOURCE_FILE + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -738,10 +1100,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ExprBinary { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_BINARY } + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_BINARY + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -749,10 +1115,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for BinaryOperator { - fn can_cast(kind: SyntaxKind) -> bool { kind == BINARY_OPERATOR } +impl AstNode for LhsExpr { + fn can_cast(kind: SyntaxKind) -> bool { + kind == LHS_EXPR + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -760,10 +1130,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ExprUnary { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_UNARY } + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_UNARY + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -771,21 +1145,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } -} -impl AstNode for UnaryOperator { - fn can_cast(kind: SyntaxKind) -> bool { kind == UNARY_OPERATOR } - fn cast(syntax: SyntaxNode) -> Option { - if Self::can_cast(syntax.kind()) { - Some(Self { syntax }) - } else { - None - } + fn syntax(&self) -> &SyntaxNode { + &self.syntax } - fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ExprSlice { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_SLICE } + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_SLICE + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -793,10 +1160,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for SliceDesc { - fn can_cast(kind: SyntaxKind) -> bool { kind == SLICE_DESC } + fn can_cast(kind: SyntaxKind) -> bool { + kind == SLICE_DESC + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -804,10 +1175,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ExprIndex { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_INDEX } + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_INDEX + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -815,10 +1190,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for Name { - fn can_cast(kind: SyntaxKind) -> bool { kind == NAME } + fn can_cast(kind: SyntaxKind) -> bool { + kind == NAME + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -826,10 +1205,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ExprIndexExpr { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_INDEX_EXPR } + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_INDEX_EXPR + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -837,10 +1220,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ExprApply { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_APPLY } + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_APPLY + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -848,10 +1235,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ArgsDesc { - fn can_cast(kind: SyntaxKind) -> bool { kind == ARGS_DESC } + fn can_cast(kind: SyntaxKind) -> bool { + kind == ARGS_DESC + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -859,10 +1250,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ExprObjExtend { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_OBJ_EXTEND } + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_OBJ_EXTEND + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -870,10 +1265,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ExprParened { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_PARENED } + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_PARENED + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -881,10 +1280,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ExprLiteral { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_LITERAL } + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_LITERAL + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -892,10 +1295,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for Literal { - fn can_cast(kind: SyntaxKind) -> bool { kind == LITERAL } +impl AstNode for ExprIntrinsicThisFile { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_INTRINSIC_THIS_FILE + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -903,10 +1310,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprIntrinsicThisFile { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_INTRINSIC_THIS_FILE } +impl AstNode for ExprIntrinsicId { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_INTRINSIC_ID + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -914,10 +1325,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprIntrinsicId { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_INTRINSIC_ID } +impl AstNode for ExprIntrinsic { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_INTRINSIC + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -925,10 +1340,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprIntrinsic { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_INTRINSIC } +impl AstNode for ExprString { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_STRING + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -936,10 +1355,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprString { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_STRING } +impl AstNode for ExprNumber { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_NUMBER + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -947,10 +1370,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for String { - fn can_cast(kind: SyntaxKind) -> bool { kind == STRING } +impl AstNode for ExprArray { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_ARRAY + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -958,10 +1385,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprNumber { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_NUMBER } +impl AstNode for ExprObject { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_OBJECT + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -969,10 +1400,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for Number { - fn can_cast(kind: SyntaxKind) -> bool { kind == NUMBER } +impl AstNode for ExprArrayComp { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_ARRAY_COMP + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -980,10 +1415,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprArray { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_ARRAY } +impl AstNode for ExprImport { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_IMPORT + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -991,10 +1430,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprObject { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_OBJECT } +impl AstNode for ExprVar { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_VAR + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1002,10 +1445,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprArrayComp { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_ARRAY_COMP } +impl AstNode for ExprLocal { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_LOCAL + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1013,10 +1460,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ForSpec { - fn can_cast(kind: SyntaxKind) -> bool { kind == FOR_SPEC } +impl AstNode for ExprIfThenElse { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_IF_THEN_ELSE + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1024,10 +1475,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprImport { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_IMPORT } +impl AstNode for TrueExpr { + fn can_cast(kind: SyntaxKind) -> bool { + kind == TRUE_EXPR + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1035,10 +1490,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprVar { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_VAR } +impl AstNode for FalseExpr { + fn can_cast(kind: SyntaxKind) -> bool { + kind == FALSE_EXPR + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1046,10 +1505,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprLocal { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_LOCAL } +impl AstNode for ExprFunction { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_FUNCTION + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1057,10 +1520,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprIfThenElse { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_IF_THEN_ELSE } +impl AstNode for ParamsDesc { + fn can_cast(kind: SyntaxKind) -> bool { + kind == PARAMS_DESC + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1068,10 +1535,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprFunction { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_FUNCTION } +impl AstNode for ExprAssert { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_ASSERT + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1079,10 +1550,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ParamsDesc { - fn can_cast(kind: SyntaxKind) -> bool { kind == PARAMS_DESC } +impl AstNode for Assertion { + fn can_cast(kind: SyntaxKind) -> bool { + kind == ASSERTION + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1090,10 +1565,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprAssert { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_ASSERT } +impl AstNode for ExprError { + fn can_cast(kind: SyntaxKind) -> bool { + kind == EXPR_ERROR + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1101,10 +1580,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for Assertion { - fn can_cast(kind: SyntaxKind) -> bool { kind == ASSERTION } +impl AstNode for SliceDescEnd { + fn can_cast(kind: SyntaxKind) -> bool { + kind == SLICE_DESC_END + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1112,10 +1595,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for ExprError { - fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_ERROR } +impl AstNode for SliceDescStep { + fn can_cast(kind: SyntaxKind) -> bool { + kind == SLICE_DESC_STEP + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1123,10 +1610,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for Arg { - fn can_cast(kind: SyntaxKind) -> bool { kind == ARG } + fn can_cast(kind: SyntaxKind) -> bool { + kind == ARG + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1134,10 +1625,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ObjBodyComp { - fn can_cast(kind: SyntaxKind) -> bool { kind == OBJ_BODY_COMP } + fn can_cast(kind: SyntaxKind) -> bool { + kind == OBJ_BODY_COMP + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1145,10 +1640,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ObjLocalPostComma { - fn can_cast(kind: SyntaxKind) -> bool { kind == OBJ_LOCAL_POST_COMMA } + fn can_cast(kind: SyntaxKind) -> bool { + kind == OBJ_LOCAL_POST_COMMA + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1156,10 +1655,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ObjLocalPreComma { - fn can_cast(kind: SyntaxKind) -> bool { kind == OBJ_LOCAL_PRE_COMMA } + fn can_cast(kind: SyntaxKind) -> bool { + kind == OBJ_LOCAL_PRE_COMMA + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1167,10 +1670,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ObjBodyMemberList { - fn can_cast(kind: SyntaxKind) -> bool { kind == OBJ_BODY_MEMBER_LIST } + fn can_cast(kind: SyntaxKind) -> bool { + kind == OBJ_BODY_MEMBER_LIST + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1178,10 +1685,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for ObjLocal { - fn can_cast(kind: SyntaxKind) -> bool { kind == OBJ_LOCAL } + fn can_cast(kind: SyntaxKind) -> bool { + kind == OBJ_LOCAL + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1189,10 +1700,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for MemberBindStmt { - fn can_cast(kind: SyntaxKind) -> bool { kind == MEMBER_BIND_STMT } + fn can_cast(kind: SyntaxKind) -> bool { + kind == MEMBER_BIND_STMT + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1200,10 +1715,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for MemberAssertStmt { - fn can_cast(kind: SyntaxKind) -> bool { kind == MEMBER_ASSERT_STMT } + fn can_cast(kind: SyntaxKind) -> bool { + kind == MEMBER_ASSERT_STMT + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1211,10 +1730,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for MemberField { - fn can_cast(kind: SyntaxKind) -> bool { kind == MEMBER_FIELD } + fn can_cast(kind: SyntaxKind) -> bool { + kind == MEMBER_FIELD + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1222,10 +1745,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for FieldNormal { - fn can_cast(kind: SyntaxKind) -> bool { kind == FIELD_NORMAL } + fn can_cast(kind: SyntaxKind) -> bool { + kind == FIELD_NORMAL + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1233,10 +1760,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for Visibility { - fn can_cast(kind: SyntaxKind) -> bool { kind == VISIBILITY } +impl AstNode for FieldMethod { + fn can_cast(kind: SyntaxKind) -> bool { + kind == FIELD_METHOD + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1244,10 +1775,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for FieldMethod { - fn can_cast(kind: SyntaxKind) -> bool { kind == FIELD_METHOD } +impl AstNode for FieldNameFixed { + fn can_cast(kind: SyntaxKind) -> bool { + kind == FIELD_NAME_FIXED + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1255,10 +1790,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for FieldNameFixed { - fn can_cast(kind: SyntaxKind) -> bool { kind == FIELD_NAME_FIXED } +impl AstNode for FieldNameDynamic { + fn can_cast(kind: SyntaxKind) -> bool { + kind == FIELD_NAME_DYNAMIC + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1266,10 +1805,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for FieldNameDynamic { - fn can_cast(kind: SyntaxKind) -> bool { kind == FIELD_NAME_DYNAMIC } +impl AstNode for ForSpec { + fn can_cast(kind: SyntaxKind) -> bool { + kind == FOR_SPEC + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1277,10 +1820,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for IfSpec { - fn can_cast(kind: SyntaxKind) -> bool { kind == IF_SPEC } + fn can_cast(kind: SyntaxKind) -> bool { + kind == IF_SPEC + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1288,10 +1835,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl AstNode for BindDestruct { - fn can_cast(kind: SyntaxKind) -> bool { kind == BIND_DESTRUCT } + fn can_cast(kind: SyntaxKind) -> bool { + kind == BIND_DESTRUCT + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1299,10 +1850,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for Destruct { - fn can_cast(kind: SyntaxKind) -> bool { kind == DESTRUCT } +impl AstNode for BindFunction { + fn can_cast(kind: SyntaxKind) -> bool { + kind == BIND_FUNCTION + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1310,10 +1865,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for BindFunction { - fn can_cast(kind: SyntaxKind) -> bool { kind == BIND_FUNCTION } +impl AstNode for Param { + fn can_cast(kind: SyntaxKind) -> bool { + kind == PARAM + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1321,10 +1880,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for Param { - fn can_cast(kind: SyntaxKind) -> bool { kind == PARAM } +impl AstNode for DestructFull { + fn can_cast(kind: SyntaxKind) -> bool { + kind == DESTRUCT_FULL + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1332,10 +1895,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for DestructFull { - fn can_cast(kind: SyntaxKind) -> bool { kind == DESTRUCT_FULL } +impl AstNode for DestructSkip { + fn can_cast(kind: SyntaxKind) -> bool { + kind == DESTRUCT_SKIP + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1343,10 +1910,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for DestructSkip { - fn can_cast(kind: SyntaxKind) -> bool { kind == DESTRUCT_SKIP } +impl AstNode for DestructArray { + fn can_cast(kind: SyntaxKind) -> bool { + kind == DESTRUCT_ARRAY + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1354,10 +1925,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for DestructArray { - fn can_cast(kind: SyntaxKind) -> bool { kind == DESTRUCT_ARRAY } +impl AstNode for DestructObject { + fn can_cast(kind: SyntaxKind) -> bool { + kind == DESTRUCT_OBJECT + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1365,10 +1940,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for DestructRest { - fn can_cast(kind: SyntaxKind) -> bool { kind == DESTRUCT_REST } +impl AstNode for DestructObjectField { + fn can_cast(kind: SyntaxKind) -> bool { + kind == DESTRUCT_OBJECT_FIELD + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1376,10 +1955,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for DestructObject { - fn can_cast(kind: SyntaxKind) -> bool { kind == DESTRUCT_OBJECT } +impl AstNode for DestructRest { + fn can_cast(kind: SyntaxKind) -> bool { + kind == DESTRUCT_REST + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1387,10 +1970,14 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } -impl AstNode for DestructObjectField { - fn can_cast(kind: SyntaxKind) -> bool { kind == DESTRUCT_OBJECT_FIELD } +impl AstNode for DestructArrayElement { + fn can_cast(kind: SyntaxKind) -> bool { + kind == DESTRUCT_ARRAY_ELEMENT + } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { Some(Self { syntax }) @@ -1398,76 +1985,129 @@ None } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } } impl From for Expr { - fn from(node: ExprBinary) -> Expr { Expr::ExprBinary(node) } + fn from(node: ExprBinary) -> Expr { + Expr::ExprBinary(node) + } } impl From for Expr { - fn from(node: ExprUnary) -> Expr { Expr::ExprUnary(node) } + fn from(node: ExprUnary) -> Expr { + Expr::ExprUnary(node) + } } impl From for Expr { - fn from(node: ExprSlice) -> Expr { Expr::ExprSlice(node) } + fn from(node: ExprSlice) -> Expr { + Expr::ExprSlice(node) + } } impl From for Expr { - fn from(node: ExprIndex) -> Expr { Expr::ExprIndex(node) } + fn from(node: ExprIndex) -> Expr { + Expr::ExprIndex(node) + } } impl From for Expr { - fn from(node: ExprIndexExpr) -> Expr { Expr::ExprIndexExpr(node) } + fn from(node: ExprIndexExpr) -> Expr { + Expr::ExprIndexExpr(node) + } } impl From for Expr { - fn from(node: ExprApply) -> Expr { Expr::ExprApply(node) } + fn from(node: ExprApply) -> Expr { + Expr::ExprApply(node) + } } impl From for Expr { - fn from(node: ExprObjExtend) -> Expr { Expr::ExprObjExtend(node) } + fn from(node: ExprObjExtend) -> Expr { + Expr::ExprObjExtend(node) + } } impl From for Expr { - fn from(node: ExprParened) -> Expr { Expr::ExprParened(node) } + fn from(node: ExprParened) -> Expr { + Expr::ExprParened(node) + } } impl From for Expr { - fn from(node: ExprIntrinsicThisFile) -> Expr { Expr::ExprIntrinsicThisFile(node) } + fn from(node: ExprIntrinsicThisFile) -> Expr { + Expr::ExprIntrinsicThisFile(node) + } } impl From for Expr { - fn from(node: ExprIntrinsicId) -> Expr { Expr::ExprIntrinsicId(node) } + fn from(node: ExprIntrinsicId) -> Expr { + Expr::ExprIntrinsicId(node) + } } impl From for Expr { - fn from(node: ExprIntrinsic) -> Expr { Expr::ExprIntrinsic(node) } + fn from(node: ExprIntrinsic) -> Expr { + Expr::ExprIntrinsic(node) + } } impl From for Expr { - fn from(node: ExprString) -> Expr { Expr::ExprString(node) } + fn from(node: ExprString) -> Expr { + Expr::ExprString(node) + } } impl From for Expr { - fn from(node: ExprNumber) -> Expr { Expr::ExprNumber(node) } + fn from(node: ExprNumber) -> Expr { + Expr::ExprNumber(node) + } } +impl From for Expr { + fn from(node: ExprLiteral) -> Expr { + Expr::ExprLiteral(node) + } +} impl From for Expr { - fn from(node: ExprArray) -> Expr { Expr::ExprArray(node) } + fn from(node: ExprArray) -> Expr { + Expr::ExprArray(node) + } } impl From for Expr { - fn from(node: ExprObject) -> Expr { Expr::ExprObject(node) } + fn from(node: ExprObject) -> Expr { + Expr::ExprObject(node) + } } impl From for Expr { - fn from(node: ExprArrayComp) -> Expr { Expr::ExprArrayComp(node) } + fn from(node: ExprArrayComp) -> Expr { + Expr::ExprArrayComp(node) + } } impl From for Expr { - fn from(node: ExprImport) -> Expr { Expr::ExprImport(node) } + fn from(node: ExprImport) -> Expr { + Expr::ExprImport(node) + } } impl From for Expr { - fn from(node: ExprVar) -> Expr { Expr::ExprVar(node) } + fn from(node: ExprVar) -> Expr { + Expr::ExprVar(node) + } } impl From for Expr { - fn from(node: ExprLocal) -> Expr { Expr::ExprLocal(node) } + fn from(node: ExprLocal) -> Expr { + Expr::ExprLocal(node) + } } impl From for Expr { - fn from(node: ExprIfThenElse) -> Expr { Expr::ExprIfThenElse(node) } + fn from(node: ExprIfThenElse) -> Expr { + Expr::ExprIfThenElse(node) + } } impl From for Expr { - fn from(node: ExprFunction) -> Expr { Expr::ExprFunction(node) } + fn from(node: ExprFunction) -> Expr { + Expr::ExprFunction(node) + } } impl From for Expr { - fn from(node: ExprAssert) -> Expr { Expr::ExprAssert(node) } + fn from(node: ExprAssert) -> Expr { + Expr::ExprAssert(node) + } } impl From for Expr { - fn from(node: ExprError) -> Expr { Expr::ExprError(node) } + fn from(node: ExprError) -> Expr { + Expr::ExprError(node) + } } impl AstNode for Expr { fn can_cast(kind: SyntaxKind) -> bool { @@ -1485,6 +2125,7 @@ | EXPR_INTRINSIC | EXPR_STRING | EXPR_NUMBER + | EXPR_LITERAL | EXPR_ARRAY | EXPR_OBJECT | EXPR_ARRAY_COMP @@ -1515,6 +2156,7 @@ EXPR_INTRINSIC => Expr::ExprIntrinsic(ExprIntrinsic { syntax }), EXPR_STRING => Expr::ExprString(ExprString { syntax }), EXPR_NUMBER => Expr::ExprNumber(ExprNumber { syntax }), + EXPR_LITERAL => Expr::ExprLiteral(ExprLiteral { syntax }), EXPR_ARRAY => Expr::ExprArray(ExprArray { syntax }), EXPR_OBJECT => Expr::ExprObject(ExprObject { syntax }), EXPR_ARRAY_COMP => Expr::ExprArrayComp(ExprArrayComp { syntax }), @@ -1544,6 +2186,7 @@ Expr::ExprIntrinsic(it) => &it.syntax, Expr::ExprString(it) => &it.syntax, Expr::ExprNumber(it) => &it.syntax, + Expr::ExprLiteral(it) => &it.syntax, Expr::ExprArray(it) => &it.syntax, Expr::ExprObject(it) => &it.syntax, Expr::ExprArrayComp(it) => &it.syntax, @@ -1558,10 +2201,14 @@ } } impl From for ObjBody { - fn from(node: ObjBodyComp) -> ObjBody { ObjBody::ObjBodyComp(node) } + fn from(node: ObjBodyComp) -> ObjBody { + ObjBody::ObjBodyComp(node) + } } impl From for ObjBody { - fn from(node: ObjBodyMemberList) -> ObjBody { ObjBody::ObjBodyMemberList(node) } + fn from(node: ObjBodyMemberList) -> ObjBody { + ObjBody::ObjBodyMemberList(node) + } } impl AstNode for ObjBody { fn can_cast(kind: SyntaxKind) -> bool { @@ -1586,10 +2233,14 @@ } } impl From for CompSpec { - fn from(node: ForSpec) -> CompSpec { CompSpec::ForSpec(node) } + fn from(node: ForSpec) -> CompSpec { + CompSpec::ForSpec(node) + } } impl From for CompSpec { - fn from(node: IfSpec) -> CompSpec { CompSpec::IfSpec(node) } + fn from(node: IfSpec) -> CompSpec { + CompSpec::IfSpec(node) + } } impl AstNode for CompSpec { fn can_cast(kind: SyntaxKind) -> bool { @@ -1614,10 +2265,14 @@ } } impl From for Bind { - fn from(node: BindDestruct) -> Bind { Bind::BindDestruct(node) } + fn from(node: BindDestruct) -> Bind { + Bind::BindDestruct(node) + } } impl From for Bind { - fn from(node: BindFunction) -> Bind { Bind::BindFunction(node) } + fn from(node: BindFunction) -> Bind { + Bind::BindFunction(node) + } } impl AstNode for Bind { fn can_cast(kind: SyntaxKind) -> bool { @@ -1642,13 +2297,19 @@ } } impl From for Member { - fn from(node: MemberBindStmt) -> Member { Member::MemberBindStmt(node) } + fn from(node: MemberBindStmt) -> Member { + Member::MemberBindStmt(node) + } } impl From for Member { - fn from(node: MemberAssertStmt) -> Member { Member::MemberAssertStmt(node) } + fn from(node: MemberAssertStmt) -> Member { + Member::MemberAssertStmt(node) + } } impl From for Member { - fn from(node: MemberField) -> Member { Member::MemberField(node) } + fn from(node: MemberField) -> Member { + Member::MemberField(node) + } } impl AstNode for Member { fn can_cast(kind: SyntaxKind) -> bool { @@ -1675,10 +2336,14 @@ } } impl From for Field { - fn from(node: FieldNormal) -> Field { Field::FieldNormal(node) } + fn from(node: FieldNormal) -> Field { + Field::FieldNormal(node) + } } impl From for Field { - fn from(node: FieldMethod) -> Field { Field::FieldMethod(node) } + fn from(node: FieldMethod) -> Field { + Field::FieldMethod(node) + } } impl AstNode for Field { fn can_cast(kind: SyntaxKind) -> bool { @@ -1703,10 +2368,14 @@ } } impl From for FieldName { - fn from(node: FieldNameFixed) -> FieldName { FieldName::FieldNameFixed(node) } + fn from(node: FieldNameFixed) -> FieldName { + FieldName::FieldNameFixed(node) + } } impl From for FieldName { - fn from(node: FieldNameDynamic) -> FieldName { FieldName::FieldNameDynamic(node) } + fn from(node: FieldNameDynamic) -> FieldName { + FieldName::FieldNameDynamic(node) + } } impl AstNode for FieldName { fn can_cast(kind: SyntaxKind) -> bool { @@ -1730,6 +2399,448 @@ } } } +impl From for Destruct { + fn from(node: DestructFull) -> Destruct { + Destruct::DestructFull(node) + } +} +impl From for Destruct { + fn from(node: DestructSkip) -> Destruct { + Destruct::DestructSkip(node) + } +} +impl From for Destruct { + fn from(node: DestructArray) -> Destruct { + Destruct::DestructArray(node) + } +} +impl From for Destruct { + fn from(node: DestructObject) -> Destruct { + Destruct::DestructObject(node) + } +} +impl AstNode for Destruct { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + DESTRUCT_FULL | DESTRUCT_SKIP | DESTRUCT_ARRAY | DESTRUCT_OBJECT => true, + _ => false, + } + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + DESTRUCT_FULL => Destruct::DestructFull(DestructFull { syntax }), + DESTRUCT_SKIP => Destruct::DestructSkip(DestructSkip { syntax }), + DESTRUCT_ARRAY => Destruct::DestructArray(DestructArray { syntax }), + DESTRUCT_OBJECT => Destruct::DestructObject(DestructObject { syntax }), + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { + match self { + Destruct::DestructFull(it) => &it.syntax, + Destruct::DestructSkip(it) => &it.syntax, + Destruct::DestructArray(it) => &it.syntax, + Destruct::DestructObject(it) => &it.syntax, + } + } +} +impl From for DestructArrayPart { + fn from(node: DestructArrayElement) -> DestructArrayPart { + DestructArrayPart::DestructArrayElement(node) + } +} +impl From for DestructArrayPart { + fn from(node: DestructRest) -> DestructArrayPart { + DestructArrayPart::DestructRest(node) + } +} +impl AstNode for DestructArrayPart { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + DESTRUCT_ARRAY_ELEMENT | DESTRUCT_REST => true, + _ => false, + } + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + DESTRUCT_ARRAY_ELEMENT => { + DestructArrayPart::DestructArrayElement(DestructArrayElement { syntax }) + } + DESTRUCT_REST => DestructArrayPart::DestructRest(DestructRest { syntax }), + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { + match self { + DestructArrayPart::DestructArrayElement(it) => &it.syntax, + DestructArrayPart::DestructRest(it) => &it.syntax, + } + } +} +impl AstToken for BinaryOperator { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + OR | AND | BIT_OR | BIT_XOR | BIT_AND | EQ | NE | LT | GT | LE | GE | IN_KW | LHS + | RHS | PLUS | MINUS | MUL | DIV | MODULO | ERROR_NO_OPERATOR => true, + _ => false, + } + } + fn cast(syntax: SyntaxToken) -> Option { + let res = match syntax.kind() { + OR => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Or, + }, + AND => BinaryOperator { + syntax, + kind: BinaryOperatorKind::And, + }, + BIT_OR => BinaryOperator { + syntax, + kind: BinaryOperatorKind::BitOr, + }, + BIT_XOR => BinaryOperator { + syntax, + kind: BinaryOperatorKind::BitXor, + }, + BIT_AND => BinaryOperator { + syntax, + kind: BinaryOperatorKind::BitAnd, + }, + EQ => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Eq, + }, + NE => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Ne, + }, + LT => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Lt, + }, + GT => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Gt, + }, + LE => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Le, + }, + GE => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Ge, + }, + IN_KW => BinaryOperator { + syntax, + kind: BinaryOperatorKind::InKw, + }, + LHS => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Lhs, + }, + RHS => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Rhs, + }, + PLUS => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Plus, + }, + MINUS => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Minus, + }, + MUL => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Mul, + }, + DIV => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Div, + }, + MODULO => BinaryOperator { + syntax, + kind: BinaryOperatorKind::Modulo, + }, + ERROR_NO_OPERATOR => BinaryOperator { + syntax, + kind: BinaryOperatorKind::ErrorNoOperator, + }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl BinaryOperator { + pub fn kind(&self) -> BinaryOperatorKind { + self.kind + } +} +impl std::fmt::Display for BinaryOperator { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} +impl AstToken for UnaryOperator { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + MINUS | NOT | BIT_NOT => true, + _ => false, + } + } + fn cast(syntax: SyntaxToken) -> Option { + let res = match syntax.kind() { + MINUS => UnaryOperator { + syntax, + kind: UnaryOperatorKind::Minus, + }, + NOT => UnaryOperator { + syntax, + kind: UnaryOperatorKind::Not, + }, + BIT_NOT => UnaryOperator { + syntax, + kind: UnaryOperatorKind::BitNot, + }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl UnaryOperator { + pub fn kind(&self) -> UnaryOperatorKind { + self.kind + } +} +impl std::fmt::Display for UnaryOperator { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} +impl AstToken for Literal { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + NULL_KW | TRUE_KW | FALSE_KW | SELF_KW | DOLLAR | SUPER_KW => true, + _ => false, + } + } + fn cast(syntax: SyntaxToken) -> Option { + let res = match syntax.kind() { + NULL_KW => Literal { + syntax, + kind: LiteralKind::NullKw, + }, + TRUE_KW => Literal { + syntax, + kind: LiteralKind::TrueKw, + }, + FALSE_KW => Literal { + syntax, + kind: LiteralKind::FalseKw, + }, + SELF_KW => Literal { + syntax, + kind: LiteralKind::SelfKw, + }, + DOLLAR => Literal { + syntax, + kind: LiteralKind::Dollar, + }, + SUPER_KW => Literal { + syntax, + kind: LiteralKind::SuperKw, + }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl Literal { + pub fn kind(&self) -> LiteralKind { + self.kind + } +} +impl std::fmt::Display for Literal { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} +impl AstToken for String { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + STRING_DOUBLE + | STRING_SINGLE + | STRING_DOUBLE_VERBATIM + | STRING_SINGLE_VERBATIM + | STRING_BLOCK => true, + _ => false, + } + } + fn cast(syntax: SyntaxToken) -> Option { + let res = match syntax.kind() { + STRING_DOUBLE => String { + syntax, + kind: StringKind::StringDouble, + }, + STRING_SINGLE => String { + syntax, + kind: StringKind::StringSingle, + }, + STRING_DOUBLE_VERBATIM => String { + syntax, + kind: StringKind::StringDoubleVerbatim, + }, + STRING_SINGLE_VERBATIM => String { + syntax, + kind: StringKind::StringSingleVerbatim, + }, + STRING_BLOCK => String { + syntax, + kind: StringKind::StringBlock, + }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl String { + pub fn kind(&self) -> StringKind { + self.kind + } +} +impl std::fmt::Display for String { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} +impl AstToken for Number { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + FLOAT | META_FORCE_ENUM => true, + _ => false, + } + } + fn cast(syntax: SyntaxToken) -> Option { + let res = match syntax.kind() { + FLOAT => Number { + syntax, + kind: NumberKind::Float, + }, + META_FORCE_ENUM => Number { + syntax, + kind: NumberKind::MetaForceEnum, + }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl Number { + pub fn kind(&self) -> NumberKind { + self.kind + } +} +impl std::fmt::Display for Number { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} +impl AstToken for ImportKind { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + IMPORTSTR_KW | IMPORTBIN_KW | IMPORT_KW => true, + _ => false, + } + } + fn cast(syntax: SyntaxToken) -> Option { + let res = match syntax.kind() { + IMPORTSTR_KW => ImportKind { + syntax, + kind: ImportKindKind::ImportstrKw, + }, + IMPORTBIN_KW => ImportKind { + syntax, + kind: ImportKindKind::ImportbinKw, + }, + IMPORT_KW => ImportKind { + syntax, + kind: ImportKindKind::ImportKw, + }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl ImportKind { + pub fn kind(&self) -> ImportKindKind { + self.kind + } +} +impl std::fmt::Display for ImportKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} +impl AstToken for Visibility { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + COLONCOLONCOLON | COLONCOLON | COLON => true, + _ => false, + } + } + fn cast(syntax: SyntaxToken) -> Option { + let res = match syntax.kind() { + COLONCOLONCOLON => Visibility { + syntax, + kind: VisibilityKind::Coloncoloncolon, + }, + COLONCOLON => Visibility { + syntax, + kind: VisibilityKind::Coloncolon, + }, + COLON => Visibility { + syntax, + kind: VisibilityKind::Colon, + }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } +} +impl Visibility { + pub fn kind(&self) -> VisibilityKind { + self.kind + } +} +impl std::fmt::Display for Visibility { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for Expr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -1765,31 +2876,36 @@ std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for SourceFile { +impl std::fmt::Display for Destruct { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for ExprBinary { +impl std::fmt::Display for DestructArrayPart { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for BinaryOperator { +impl std::fmt::Display for SourceFile { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for ExprUnary { +impl std::fmt::Display for ExprBinary { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for UnaryOperator { +impl std::fmt::Display for LhsExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for ExprUnary { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for ExprSlice { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -1840,11 +2956,6 @@ std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for Literal { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(self.syntax(), f) - } -} impl std::fmt::Display for ExprIntrinsicThisFile { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -1861,11 +2972,6 @@ } } impl std::fmt::Display for ExprString { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(self.syntax(), f) - } -} -impl std::fmt::Display for String { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } @@ -1875,47 +2981,47 @@ std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for Number { +impl std::fmt::Display for ExprArray { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for ExprArray { +impl std::fmt::Display for ExprObject { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for ExprObject { +impl std::fmt::Display for ExprArrayComp { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for ExprArrayComp { +impl std::fmt::Display for ExprImport { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for ForSpec { +impl std::fmt::Display for ExprVar { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for ExprImport { +impl std::fmt::Display for ExprLocal { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for ExprVar { +impl std::fmt::Display for ExprIfThenElse { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for ExprLocal { +impl std::fmt::Display for TrueExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for ExprIfThenElse { +impl std::fmt::Display for FalseExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } @@ -1945,6 +3051,16 @@ std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for SliceDescEnd { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} +impl std::fmt::Display for SliceDescStep { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for Arg { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -1991,11 +3107,6 @@ } } impl std::fmt::Display for FieldNormal { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(self.syntax(), f) - } -} -impl std::fmt::Display for Visibility { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } @@ -2015,17 +3126,17 @@ std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for IfSpec { +impl std::fmt::Display for ForSpec { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for BindDestruct { +impl std::fmt::Display for IfSpec { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for Destruct { +impl std::fmt::Display for BindDestruct { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } @@ -2055,17 +3166,22 @@ std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for DestructRest { +impl std::fmt::Display for DestructObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} +impl std::fmt::Display for DestructObjectField { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for DestructObject { +impl std::fmt::Display for DestructRest { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for DestructObjectField { +impl std::fmt::Display for DestructArrayElement { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } --- a/crates/jrsonnet-rowan-parser/src/generated/syntax_kinds.rs +++ b/crates/jrsonnet-rowan-parser/src/generated/syntax_kinds.rs @@ -1,7 +1,13 @@ //! This is a generated file, please do not edit manually. Changes can be //! made in codegeneration that lives in `xtask` top-level dir. -#![allow(bad_style, missing_docs, unreachable_pub)] +#![allow( + bad_style, + missing_docs, + unreachable_pub, + clippy::manual_non_exhaustive, + clippy::match_like_matches_macro +)] use logos::Logos; #[doc = r" The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT`."] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Logos)] @@ -89,6 +95,52 @@ INTRINSIC_ID, #[token("$intrinsic")] INTRINSIC, + #[regex("(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?")] + FLOAT, + #[regex("(?:0|[1-9][0-9]*)\\.[^0-9]")] + ERROR_FLOAT_JUNK_AFTER_POINT, + #[regex("(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?[eE][^+\\-0-9]")] + ERROR_FLOAT_JUNK_AFTER_EXPONENT, + #[regex("(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?[eE][+-][^0-9]")] + ERROR_FLOAT_JUNK_AFTER_EXPONENT_SIGN, + #[regex("\"(?s:[^\"\\\\]|\\\\.)*\"")] + STRING_DOUBLE, + #[regex("\"(?s:[^\"\\\\]|\\\\.)*")] + ERROR_STRING_DOUBLE_UNTERMINATED, + #[regex("'(?s:[^'\\\\]|\\\\.)*'")] + STRING_SINGLE, + #[regex("'(?s:[^'\\\\]|\\\\.)*")] + ERROR_STRING_SINGLE_UNTERMINATED, + #[regex("@\"(?:[^\"]|\"\")*\"")] + STRING_DOUBLE_VERBATIM, + #[regex("@\"(?:[^\"]|\"\")*")] + ERROR_STRING_DOUBLE_VERBATIM_UNTERMINATED, + #[regex("@'(?:[^']|'')*'")] + STRING_SINGLE_VERBATIM, + #[regex("@'(?:[^']|'')*")] + ERROR_STRING_SINGLE_VERBATIM_UNTERMINATED, + #[regex("@[^\"'\\s]\\S+")] + ERROR_STRING_VERBATIM_MISSING_QUOTES, + #[regex("\\|\\|\\|", crate::string_block::lex_str_block_test)] + STRING_BLOCK, + ERROR_STRING_BLOCK_UNEXPECTED_END, + ERROR_STRING_BLOCK_MISSING_NEW_LINE, + ERROR_STRING_BLOCK_MISSING_TERMINATION, + ERROR_STRING_BLOCK_MISSING_INDENT, + #[regex("[_a-zA-Z][_a-zA-Z0-9]*")] + IDENT, + #[regex("[ \\t\\n\\r]+")] + WHITESPACE, + #[regex("//[^\\r\\n]*(\\r\\n|\\n)?")] + SINGLE_LINE_SLASH_COMMENT, + #[regex("#[^\\r\\n]*(\\r\\n|\\n)?")] + SINGLE_LINE_HASH_COMMENT, + #[regex("/\\*([^*]|\\*[^/])*\\*/")] + MULTI_LINE_COMMENT, + #[regex("/\\*/")] + ERROR_COMMENT_TOO_SHORT, + #[regex("/\\*([^*]|\\*[^/])+")] + ERROR_COMMENT_UNTERMINATED, #[token("tailstrict")] TAILSTRICT_KW, #[token("importstr")] @@ -111,6 +163,7 @@ ERROR_KW, #[token("in")] IN_KW, + ERROR_NO_OPERATOR, #[token("null")] NULL_KW, #[token("true")] @@ -121,39 +174,17 @@ SELF_KW, #[token("super")] SUPER_KW, + META_FORCE_ENUM, #[token("for")] FOR_KW, #[token("assert")] ASSERT_KW, - #[regex("(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?")] - NUMBER, - #[regex("\"(?s:[^\"\\\\]|\\\\.)*\"")] - STRING_DOUBLE, - #[regex("'(?s:[^'\\\\]|\\\\.)*'")] - STRING_SINGLE, - #[regex("@\"(?:[^\"]|\"\")*\"")] - STRING_DOUBLE_VERBATIM, - #[regex("@'(?:[^']|'')*'")] - STRING_SINGLE_VERBATIM, - #[regex("\\|\\|\\|")] - STRING_BLOCK, - #[regex("[_a-zA-Z][_a-zA-Z0-9]*")] - IDENT, - #[regex("[ \\t\\n\\r]+")] - WHITESPACE, - #[regex("//[^\\r\\n]*(\\r\\n|\\n)?")] - SINGLE_LINE_SLASH_COMMENT, - #[regex("#[^\\r\\n]*(\\r\\n|\\n)?")] - SINGLE_LINE_HASH_COMMENT, - #[regex("/\\*([^*]|\\*[^/])*\\*/")] - MULTI_LINE_COMMENT, #[error] ERROR, SOURCE_FILE, EXPR_BINARY, - BINARY_OPERATOR, + LHS_EXPR, EXPR_UNARY, - UNARY_OPERATOR, EXPR_SLICE, SLICE_DESC, EXPR_INDEX, @@ -164,26 +195,27 @@ EXPR_OBJ_EXTEND, EXPR_PARENED, EXPR_LITERAL, - LITERAL, EXPR_INTRINSIC_THIS_FILE, EXPR_INTRINSIC_ID, EXPR_INTRINSIC, EXPR_STRING, - STRING, EXPR_NUMBER, EXPR_ARRAY, EXPR_OBJECT, EXPR_ARRAY_COMP, - FOR_SPEC, EXPR_IMPORT, EXPR_VAR, EXPR_LOCAL, EXPR_IF_THEN_ELSE, + TRUE_EXPR, + FALSE_EXPR, EXPR_FUNCTION, PARAMS_DESC, EXPR_ASSERT, ASSERTION, EXPR_ERROR, + SLICE_DESC_END, + SLICE_DESC_STEP, ARG, OBJ_BODY_COMP, OBJ_LOCAL_POST_COMMA, @@ -194,21 +226,21 @@ MEMBER_ASSERT_STMT, MEMBER_FIELD, FIELD_NORMAL, - VISIBILITY, FIELD_METHOD, FIELD_NAME_FIXED, FIELD_NAME_DYNAMIC, + FOR_SPEC, IF_SPEC, BIND_DESTRUCT, - DESTRUCT, BIND_FUNCTION, PARAM, DESTRUCT_FULL, DESTRUCT_SKIP, DESTRUCT_ARRAY, - DESTRUCT_REST, DESTRUCT_OBJECT, DESTRUCT_OBJECT_FIELD, + DESTRUCT_REST, + DESTRUCT_ARRAY_ELEMENT, EXPR, OBJ_BODY, COMP_SPEC, @@ -216,6 +248,15 @@ MEMBER, FIELD, FIELD_NAME, + DESTRUCT, + DESTRUCT_ARRAY_PART, + BINARY_OPERATOR, + UNARY_OPERATOR, + LITERAL, + STRING, + NUMBER, + IMPORT_KIND, + VISIBILITY, #[doc(hidden)] __LAST, } @@ -223,76 +264,23 @@ impl SyntaxKind { pub fn is_keyword(self) -> bool { match self { - TAILSTRICT_KW | IMPORTSTR_KW | IMPORTBIN_KW | IMPORT_KW | LOCAL_KW | IF_KW - | THEN_KW | ELSE_KW | FUNCTION_KW | ERROR_KW | IN_KW | NULL_KW | TRUE_KW | FALSE_KW - | SELF_KW | SUPER_KW | FOR_KW | ASSERT_KW => true, - _ => false, - } - } - pub fn is_punct(self) -> bool { - match self { OR | AND | BIT_OR | BIT_XOR | BIT_AND | EQ | NE | LT | GT | LE | GE | LHS | RHS | PLUS | MINUS | MUL | DIV | MODULO | NOT | BIT_NOT | L_BRACK | R_BRACK | L_PAREN | R_PAREN | L_BRACE | R_BRACE | COLON | COLONCOLON | COLONCOLONCOLON | SEMI | DOT | DOTDOTDOT | COMMA | DOLLAR | ASSIGN | QUESTION_MARK | INTRINSIC_THIS_FILE - | INTRINSIC_ID | INTRINSIC => true, + | INTRINSIC_ID | INTRINSIC | TAILSTRICT_KW | IMPORTSTR_KW | IMPORTBIN_KW + | IMPORT_KW | LOCAL_KW | IF_KW | THEN_KW | ELSE_KW | FUNCTION_KW | ERROR_KW | IN_KW + | NULL_KW | TRUE_KW | FALSE_KW | SELF_KW | SUPER_KW | FOR_KW | ASSERT_KW => true, _ => false, } } - pub fn from_keyword(ident: &str) -> Option { - let kw = match ident { - "tailstrict" => TAILSTRICT_KW, - "importstr" => IMPORTSTR_KW, - "importbin" => IMPORTBIN_KW, - "import" => IMPORT_KW, - "local" => LOCAL_KW, - "if" => IF_KW, - "then" => THEN_KW, - "else" => ELSE_KW, - "function" => FUNCTION_KW, - "error" => ERROR_KW, - "in" => IN_KW, - "null" => NULL_KW, - "true" => TRUE_KW, - "false" => FALSE_KW, - "self" => SELF_KW, - "super" => SUPER_KW, - "for" => FOR_KW, - "assert" => ASSERT_KW, - _ => return None, - }; - Some(kw) - } - pub fn from_char(c: char) -> Option { - let tok = match c { - '|' => BIT_OR, - '^' => BIT_XOR, - '&' => BIT_AND, - '<' => LT, - '>' => GT, - '+' => PLUS, - '-' => MINUS, - '*' => MUL, - '/' => DIV, - '%' => MODULO, - '!' => NOT, - '~' => BIT_NOT, - '[' => L_BRACK, - ']' => R_BRACK, - '(' => L_PAREN, - ')' => R_PAREN, - '{' => L_BRACE, - '}' => R_BRACE, - ':' => COLON, - ';' => SEMI, - '.' => DOT, - ',' => COMMA, - '$' => DOLLAR, - '=' => ASSIGN, - '?' => QUESTION_MARK, - _ => return None, - }; - Some(tok) + pub fn is_enum(self) -> bool { + match self { + EXPR | OBJ_BODY | COMP_SPEC | BIND | MEMBER | FIELD | FIELD_NAME | DESTRUCT + | DESTRUCT_ARRAY_PART | BINARY_OPERATOR | UNARY_OPERATOR | LITERAL | STRING + | NUMBER | IMPORT_KIND | VISIBILITY => true, + _ => false, + } } pub fn from_raw(r: u16) -> Self { assert!(r < Self::__LAST as u16); @@ -303,5 +291,5 @@ } } #[macro_export] -macro_rules ! T { [||] => { $ crate :: SyntaxKind :: OR } ; [&&] => { $ crate :: SyntaxKind :: AND } ; [|] => { $ crate :: SyntaxKind :: BIT_OR } ; [^] => { $ crate :: SyntaxKind :: BIT_XOR } ; [&] => { $ crate :: SyntaxKind :: BIT_AND } ; [==] => { $ crate :: SyntaxKind :: EQ } ; [!=] => { $ crate :: SyntaxKind :: NE } ; [<] => { $ crate :: SyntaxKind :: LT } ; [>] => { $ crate :: SyntaxKind :: GT } ; [<=] => { $ crate :: SyntaxKind :: LE } ; [>=] => { $ crate :: SyntaxKind :: GE } ; [<<] => { $ crate :: SyntaxKind :: LHS } ; [>>] => { $ crate :: SyntaxKind :: RHS } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [*] => { $ crate :: SyntaxKind :: MUL } ; [/] => { $ crate :: SyntaxKind :: DIV } ; [%] => { $ crate :: SyntaxKind :: MODULO } ; [!] => { $ crate :: SyntaxKind :: NOT } ; [~] => { $ crate :: SyntaxKind :: BIT_NOT } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_BRACE } ; ['}'] => { $ crate :: SyntaxKind :: R_BRACE } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLONCOLON } ; [:::] => { $ crate :: SyntaxKind :: COLONCOLONCOLON } ; [;] => { $ crate :: SyntaxKind :: SEMI } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [...] => { $ crate :: SyntaxKind :: DOTDOTDOT } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['$'] => { $ crate :: SyntaxKind :: DOLLAR } ; [=] => { $ crate :: SyntaxKind :: ASSIGN } ; [?] => { $ crate :: SyntaxKind :: QUESTION_MARK } ; ["$intrinsicThisFile"] => { $ crate :: SyntaxKind :: INTRINSIC_THIS_FILE } ; ["$intrinsicId"] => { $ crate :: SyntaxKind :: INTRINSIC_ID } ; ["$intrinsic"] => { $ crate :: SyntaxKind :: INTRINSIC } ; [tailstrict] => { $ crate :: SyntaxKind :: TAILSTRICT_KW } ; [importstr] => { $ crate :: SyntaxKind :: IMPORTSTR_KW } ; [importbin] => { $ crate :: SyntaxKind :: IMPORTBIN_KW } ; [import] => { $ crate :: SyntaxKind :: IMPORT_KW } ; [local] => { $ crate :: SyntaxKind :: LOCAL_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [then] => { $ crate :: SyntaxKind :: THEN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [function] => { $ crate :: SyntaxKind :: FUNCTION_KW } ; [error] => { $ crate :: SyntaxKind :: ERROR_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [null] => { $ crate :: SyntaxKind :: NULL_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [assert] => { $ crate :: SyntaxKind :: ASSERT_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } +macro_rules ! T { [||] => { $ crate :: SyntaxKind :: OR } ; [&&] => { $ crate :: SyntaxKind :: AND } ; [|] => { $ crate :: SyntaxKind :: BIT_OR } ; [^] => { $ crate :: SyntaxKind :: BIT_XOR } ; [&] => { $ crate :: SyntaxKind :: BIT_AND } ; [==] => { $ crate :: SyntaxKind :: EQ } ; [!=] => { $ crate :: SyntaxKind :: NE } ; [<] => { $ crate :: SyntaxKind :: LT } ; [>] => { $ crate :: SyntaxKind :: GT } ; [<=] => { $ crate :: SyntaxKind :: LE } ; [>=] => { $ crate :: SyntaxKind :: GE } ; [<<] => { $ crate :: SyntaxKind :: LHS } ; [>>] => { $ crate :: SyntaxKind :: RHS } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [*] => { $ crate :: SyntaxKind :: MUL } ; [/] => { $ crate :: SyntaxKind :: DIV } ; [%] => { $ crate :: SyntaxKind :: MODULO } ; [!] => { $ crate :: SyntaxKind :: NOT } ; [~] => { $ crate :: SyntaxKind :: BIT_NOT } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_BRACE } ; ['}'] => { $ crate :: SyntaxKind :: R_BRACE } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLONCOLON } ; [:::] => { $ crate :: SyntaxKind :: COLONCOLONCOLON } ; [;] => { $ crate :: SyntaxKind :: SEMI } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [...] => { $ crate :: SyntaxKind :: DOTDOTDOT } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['$'] => { $ crate :: SyntaxKind :: DOLLAR } ; [=] => { $ crate :: SyntaxKind :: ASSIGN } ; [?] => { $ crate :: SyntaxKind :: QUESTION_MARK } ; ["$intrinsicThisFile"] => { $ crate :: SyntaxKind :: INTRINSIC_THIS_FILE } ; ["$intrinsicId"] => { $ crate :: SyntaxKind :: INTRINSIC_ID } ; ["$intrinsic"] => { $ crate :: SyntaxKind :: INTRINSIC } ; [tailstrict] => { $ crate :: SyntaxKind :: TAILSTRICT_KW } ; [importstr] => { $ crate :: SyntaxKind :: IMPORTSTR_KW } ; [importbin] => { $ crate :: SyntaxKind :: IMPORTBIN_KW } ; [import] => { $ crate :: SyntaxKind :: IMPORT_KW } ; [local] => { $ crate :: SyntaxKind :: LOCAL_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [then] => { $ crate :: SyntaxKind :: THEN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [function] => { $ crate :: SyntaxKind :: FUNCTION_KW } ; [error] => { $ crate :: SyntaxKind :: ERROR_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [null] => { $ crate :: SyntaxKind :: NULL_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [assert] => { $ crate :: SyntaxKind :: ASSERT_KW } } pub use T; --- a/crates/jrsonnet-rowan-parser/src/generated/tokens.rs +++ /dev/null @@ -1,155 +0,0 @@ -//! This is a generated file, please do not edit manually. Changes can be -//! made in codegeneration that lives in `xtask` top-level dir. - -use crate::{ - ast::AstToken, - SyntaxKind::{self, *}, - SyntaxToken, -}; - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Whitespace { - pub(crate) syntax: SyntaxToken, -} -impl std::fmt::Display for Whitespace { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.syntax, f) - } -} -impl AstToken for Whitespace { - fn can_cast(kind: SyntaxKind) -> bool { kind == WHITESPACE } - fn cast(syntax: SyntaxToken) -> Option { - if Self::can_cast(syntax.kind()) { - Some(Self { syntax }) - } else { - None - } - } - fn syntax(&self) -> &SyntaxToken { &self.syntax } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Comment { - pub(crate) syntax: SyntaxToken, -} -impl std::fmt::Display for Comment { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.syntax, f) - } -} -impl AstToken for Comment { - fn can_cast(kind: SyntaxKind) -> bool { kind == COMMENT } - fn cast(syntax: SyntaxToken) -> Option { - if Self::can_cast(syntax.kind()) { - Some(Self { syntax }) - } else { - None - } - } - fn syntax(&self) -> &SyntaxToken { &self.syntax } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct String { - pub(crate) syntax: SyntaxToken, -} -impl std::fmt::Display for String { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.syntax, f) - } -} -impl AstToken for String { - fn can_cast(kind: SyntaxKind) -> bool { kind == STRING } - fn cast(syntax: SyntaxToken) -> Option { - if Self::can_cast(syntax.kind()) { - Some(Self { syntax }) - } else { - None - } - } - fn syntax(&self) -> &SyntaxToken { &self.syntax } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct StringVerbantim { - pub(crate) syntax: SyntaxToken, -} -impl std::fmt::Display for StringVerbantim { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.syntax, f) - } -} -impl AstToken for StringVerbantim { - fn can_cast(kind: SyntaxKind) -> bool { kind == STRING_VERBANTIM } - fn cast(syntax: SyntaxToken) -> Option { - if Self::can_cast(syntax.kind()) { - Some(Self { syntax }) - } else { - None - } - } - fn syntax(&self) -> &SyntaxToken { &self.syntax } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct StringBlock { - pub(crate) syntax: SyntaxToken, -} -impl std::fmt::Display for StringBlock { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.syntax, f) - } -} -impl AstToken for StringBlock { - fn can_cast(kind: SyntaxKind) -> bool { kind == STRING_BLOCK } - fn cast(syntax: SyntaxToken) -> Option { - if Self::can_cast(syntax.kind()) { - Some(Self { syntax }) - } else { - None - } - } - fn syntax(&self) -> &SyntaxToken { &self.syntax } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Number { - pub(crate) syntax: SyntaxToken, -} -impl std::fmt::Display for Number { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.syntax, f) - } -} -impl AstToken for Number { - fn can_cast(kind: SyntaxKind) -> bool { kind == NUMBER } - fn cast(syntax: SyntaxToken) -> Option { - if Self::can_cast(syntax.kind()) { - Some(Self { syntax }) - } else { - None - } - } - fn syntax(&self) -> &SyntaxToken { &self.syntax } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Ident { - pub(crate) syntax: SyntaxToken, -} -impl std::fmt::Display for Ident { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.syntax, f) - } -} -impl AstToken for Ident { - fn can_cast(kind: SyntaxKind) -> bool { kind == IDENT } - fn cast(syntax: SyntaxToken) -> Option { - if Self::can_cast(syntax.kind()) { - Some(Self { syntax }) - } else { - None - } - } - fn syntax(&self) -> &SyntaxToken { &self.syntax } -} --- a/crates/jrsonnet-rowan-parser/src/lex.rs +++ b/crates/jrsonnet-rowan-parser/src/lex.rs @@ -6,40 +6,6 @@ use crate::SyntaxKind; -impl SyntaxKind { - pub fn is_trivia(self) -> bool { - matches!( - self, - Self::WHITESPACE - | Self::MULTI_LINE_COMMENT - | Self::SINGLE_LINE_HASH_COMMENT - | Self::SINGLE_LINE_SLASH_COMMENT - ) - } - pub fn is_string(self) -> bool { - matches!( - self, - Self::STRING_SINGLE - | Self::STRING_DOUBLE - | Self::STRING_SINGLE_VERBATIM - | Self::STRING_DOUBLE_VERBATIM - | Self::STRING_BLOCK - ) - } - pub fn is_number(self) -> bool { - matches!(self, Self::NUMBER) - } - pub fn is_literal(self) -> bool { - matches!( - self, - Self::NULL_KW - | Self::TRUE_KW | Self::FALSE_KW - | Self::SELF_KW | Self::DOLLAR - | Self::SUPER_KW - ) - } -} - pub struct Lexer<'a> { inner: logos::Lexer<'a, SyntaxKind>, } @@ -74,7 +40,7 @@ } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub struct Lexeme<'i> { pub kind: SyntaxKind, pub text: &'i str, --- a/crates/jrsonnet-rowan-parser/src/lib.rs +++ b/crates/jrsonnet-rowan-parser/src/lib.rs @@ -2,6 +2,7 @@ mod ast; mod binary; +mod classify; mod event; mod generated; mod language; @@ -13,8 +14,27 @@ mod token_set; mod unary; -pub use generated::syntax_kinds::SyntaxKind; +pub use ast::{AstChildren, AstNode, AstToken}; +use event::Sink; +use generated::nodes::SourceFile; +pub use generated::{nodes, syntax_kinds::SyntaxKind}; pub use language::{ JsonnetLanguage, PreorderWithTokens, SyntaxElement, SyntaxElementChildren, SyntaxNode, SyntaxNodeChildren, SyntaxToken, }; +use lex::lex; +use parser::{Parser, SyntaxError}; +pub fn parse(input: &str) -> (SourceFile, Vec) { + let lexemes = lex(input); + let parser = Parser::new(&lexemes); + let events = parser.parse(); + let sink = Sink::new(events, &lexemes); + + let parse = sink.finish(); + ( + SourceFile { + syntax: parse.syntax(), + }, + parse.errors, + ) +} --- a/crates/jrsonnet-rowan-parser/src/marker.rs +++ b/crates/jrsonnet-rowan-parser/src/marker.rs @@ -7,7 +7,7 @@ pub pos: usize, } impl Ranger { - pub fn finish(mut self, p: &Parser) -> FinishedRanger { + pub fn finish(self, p: &Parser) -> FinishedRanger { FinishedRanger { start_token: self.pos, end_token: self.pos.max(p.offset.saturating_sub(1)), @@ -20,6 +20,7 @@ pub end_token: usize, } impl FinishedRanger { + #[allow(dead_code)] pub fn had_error_since(&self, p: &Parser) -> bool { p.last_error_token >= self.start_token } @@ -28,76 +29,94 @@ #[must_use] pub struct Marker { pub start_event_idx: usize, - pub token: usize, bomb: DropBomb, } impl Marker { - pub fn new(pos: usize, token: usize) -> Self { + pub fn new(pos: usize) -> Self { Self { start_event_idx: pos, - token, bomb: DropBomb::new("marked dropped while not completed"), } } pub fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { self.bomb.defuse(); + assert!( + !kind.is_enum(), + "{kind:?} is a enum kind, you should use variant kinds instead" + ); + // TODO: is_parser should return true if enum variant has #[regex]/#[token] over it + // debug_assert!( + // !kind.is_parser(), + // "{kind:?} should be only emitted by parser, not used directly" + // ); let event_at_pos = &mut p.events[self.start_event_idx]; - assert_eq!(*event_at_pos, Event::Placeholder); + assert_eq!(*event_at_pos, Event::Pending); *event_at_pos = Event::Start { kind, forward_parent: None, }; - p.events.push(Event::Finish); + let finish_event_idx = p.events.len(); + p.events.push(Event::Finish { wrapper: None }); p.entered -= 1; p.clear_outdated_hints(); CompletedMarker { start_event_idx: self.start_event_idx, - start_token: self.token, - end_token: self.token.max(p.offset.saturating_sub(1)), + finish_event_idx, } } + pub fn forget(mut self, p: &mut Parser) { + self.bomb.defuse(); + let event_at_pos = &mut p.events[self.start_event_idx]; + assert_eq!(*event_at_pos, Event::Pending); + + *event_at_pos = Event::Noop; + p.entered -= 1; + p.clear_outdated_hints(); + } } pub struct CompletedMarker { start_event_idx: usize, - pub start_token: usize, - pub end_token: usize, + finish_event_idx: usize, } impl CompletedMarker { pub(super) fn precede(self, p: &mut Parser) -> Marker { - let mut new_m = p.start(); - new_m.token = self.start_token; - - if let Event::Start { - ref mut forward_parent, - .. - } = p.events[self.start_event_idx] - { - *forward_parent = Some(new_m.start_event_idx - self.start_event_idx); - } else { - unreachable!(); + let new_m = p.start(); + match &mut p.events[self.start_event_idx] { + Event::Start { forward_parent, .. } => { + *forward_parent = Some(new_m.start_event_idx - self.start_event_idx); + } + _ => unreachable!(), } new_m } + /// Create new node around existing marker, not counting anything that comes after it + pub fn wrap(self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { + let new_m = p.start(); + match &mut p.events[self.start_event_idx] { + Event::Start { forward_parent, .. } => { + *forward_parent = Some(new_m.start_event_idx - self.start_event_idx); + } + _ => unreachable!(), + } + + let completed = new_m.complete(p, kind); + + match &mut p.events[self.finish_event_idx] { + Event::Finish { wrapper } => { + *wrapper = Some(completed.finish_event_idx - self.finish_event_idx); + } + _ => unreachable!(), + } + completed + } } pub trait AsRange { fn as_range(&self, p: &Parser) -> TextRange; fn end_token(&self) -> usize; -} - -impl AsRange for CompletedMarker { - fn as_range(&self, p: &Parser) -> TextRange { - TextRange::new( - p.start_of_token(self.start_token), - p.end_of_token(self.end_token), - ) - } - fn end_token(&self) -> usize { - self.end_token - } } impl AsRange for FinishedRanger { --- a/crates/jrsonnet-rowan-parser/src/parser.rs +++ b/crates/jrsonnet-rowan-parser/src/parser.rs @@ -5,9 +5,10 @@ use crate::{ binary::BinaryOperator, - event::{Event, Sink}, - lex::{lex, Lexeme}, + event::Event, + lex::Lexeme, marker::{AsRange, CompletedMarker, Marker, Ranger}, + string_block::{lex_str_block, StringBlockError}, token_set::SyntaxKindSet, unary::UnaryOperator, SyntaxKind, @@ -43,9 +44,10 @@ pub last_error_token: usize, expected_syntax: Option, expected_syntax_tracking_state: Rc>, + steps: Cell, } -const DEFAULT_RECOVERY_SET: SyntaxKindSet = TS![; ')' ']' '}' local]; +const DEFAULT_RECOVERY_SET: SyntaxKindSet = TS![]; #[derive(Clone, Debug, PartialEq, Eq)] pub enum SyntaxError { @@ -68,9 +70,9 @@ }, } -impl Into for SyntaxError { - fn into(self) -> LabeledSpan { - match self { +impl From for LabeledSpan { + fn from(val: SyntaxError) -> Self { + match val { SyntaxError::Unexpected { expected, found, @@ -91,7 +93,7 @@ ), SyntaxError::Custom { error, range } | SyntaxError::Hint { error, range } => { LabeledSpan::new_with_span( - Some(format!("{}", error)), + Some(error), SourceSpan::new( SourceOffset::from(usize::from(range.start())), SourceOffset::from(usize::from(range.end() - range.start())), @@ -103,7 +105,7 @@ } impl<'i> Parser<'i> { - fn new(lexemes: &'i [Lexeme<'i>]) -> Self { + pub fn new(lexemes: &'i [Lexeme<'i>]) -> Self { Self { lexemes, offset: 0, @@ -115,6 +117,7 @@ expected_syntax_tracking_state: Rc::new(Cell::new( ExpectedSyntaxTrackingState::Unnamed, )), + steps: Cell::new(0), } } pub fn clear_outdated_hints(&mut self) { @@ -132,27 +135,21 @@ .set(ExpectedSyntaxTrackingState::Unnamed); } pub fn start(&mut self) -> Marker { + self.skip_trivia(); let start_event_idx = self.events.len(); - self.events.push(Event::Placeholder); + self.events.push(Event::Pending); self.entered += 1; - Marker::new(start_event_idx, self.offset) + Marker::new(start_event_idx) } pub fn start_ranger(&mut self) -> Ranger { + self.skip_trivia(); let pos = self.offset; Ranger { pos } } - fn parse(mut self) -> Vec { + pub fn parse(mut self) -> Vec { let m = self.start(); expr(&mut self); - if !self.at_end() { - let ranger = self.start_ranger(); - - while self.peek().is_some() { - self.bump() - } - let end = ranger.finish(&self); - self.custom_error(end, "unexpected input after expression"); - } + self.expect(EOF); m.complete(&mut self, SOURCE_FILE); self.events @@ -168,7 +165,9 @@ recovery_set: SyntaxKindSet, ) { if self.at(kind) { - self.bump(); + if kind != EOF { + self.bump(); + } } else { self.error_with_recovery_set(recovery_set); } @@ -180,9 +179,6 @@ } else { self.error_with_no_skip(); } - } - pub(crate) fn last_token_range(&self) -> Option { - self.lexemes.last().map(|Lexeme { range, .. }| *range) } fn current_token(&self) -> Lexeme<'i> { self.lexemes[self.offset] @@ -236,15 +232,19 @@ &mut self, recovery_set: SyntaxKindSet, ) -> Option { - let expected_syntax = self.expected_syntax.take().unwrap(); + let expected_syntax = self + .expected_syntax + .take() + .unwrap_or(ExpectedSyntax::Named("unknown")); self.expected_syntax_tracking_state .set(ExpectedSyntaxTrackingState::Unnamed); - if self.at_end() || self.at_set(recovery_set) { + self.skip_trivia(); + if self.at_end() || self.at_ts(recovery_set) { let range = self .previous_token() .map(|t| t.range) - .unwrap_or(TextRange::at(TextSize::from(0), TextSize::from(0))); + .unwrap_or_else(|| TextRange::at(TextSize::from(0), TextSize::from(0))); self.events.push(Event::Error(SyntaxError::Missing { expected: expected_syntax, @@ -256,7 +256,7 @@ let current_token = self.current_token(); self.events.push(Event::Error(SyntaxError::Unexpected { - expected: expected_syntax.clone(), + expected: expected_syntax, found: current_token.kind, range: current_token.range, })); @@ -270,30 +270,85 @@ fn bump(&mut self) { self.skip_trivia(); + self.bump_remap(self.current()); + } + fn bump_remap(&mut self, kind: SyntaxKind) { + self.skip_trivia(); assert_ne!(self.offset, self.lexemes.len(), "already at end"); - self.events.push(Event::Token); + self.events.push(Event::Token { kind }); self.offset += 1; self.clear_expected_syntaxes(); } - fn peek(&mut self) -> Option { - self.skip_trivia(); - self.peek_raw() + fn step(&self) { + use std::fmt::Write; + let steps = self.steps.get(); + if steps >= 15000000 { + let mut out = "seems like parsing is stuck".to_owned(); + { + let last = 20; + write!(out, "\n\nLast {} events:", last).unwrap(); + for (i, event) in self + .events + .iter() + .skip(self.events.len().saturating_sub(last)) + .enumerate() + { + write!(out, "\n{i}. {event:?}").unwrap(); + } + } + { + let next = 20; + write!(out, "\n\nNext {next} tokens:").unwrap(); + for (i, tok) in self.lexemes.iter().skip(self.offset).take(next).enumerate() { + write!(out, "\n{i}. {tok:?}").unwrap(); + } + } + panic!("{out}") + } + self.steps.set(steps + 1); + } + fn nth(&self, i: usize) -> SyntaxKind { + self.step(); + let mut offset = self.offset; + for _ in 0..i { + while self + .lexemes + .get(offset) + .map(|l| l.kind.is_trivia()) + .unwrap_or(false) + { + offset += 1; + } + offset += 1; + } + while self + .lexemes + .get(offset) + .map(|l| l.kind.is_trivia()) + .unwrap_or(false) + { + offset += 1; + } + self.lexemes.get(offset).map(|l| l.kind).unwrap_or(EOF) } - pub fn peek_token(&mut self) -> Option<&Lexeme<'i>> { - self.skip_trivia(); - self.peek_token_raw() + fn current(&self) -> SyntaxKind { + self.nth(0) } fn skip_trivia(&mut self) { - while self.peek_raw().map(|c| c.is_trivia()).unwrap_or(false) { + while self.peek_raw().is_trivia() { self.offset += 1; } - } - fn peek_raw(&mut self) -> Option { - self.lexemes.get(self.offset).map(|l| l.kind) } - fn peek_token_raw(&mut self) -> Option<&Lexeme<'i>> { + fn current_lexeme(&mut self) -> Option<&Lexeme> { + self.skip_trivia(); self.lexemes.get(self.offset) } + fn peek_raw(&mut self) -> SyntaxKind { + self.lexemes + .get(self.offset) + .map(|l| l.kind) + .unwrap_or(SyntaxKind::EOF) + } #[must_use] pub(crate) fn expected_syntax_name(&mut self, name: &'static str) -> ExpectedSyntaxGuard { self.expected_syntax_tracking_state @@ -303,16 +358,19 @@ ExpectedSyntaxGuard::new(Rc::clone(&self.expected_syntax_tracking_state)) } pub fn at(&mut self, kind: SyntaxKind) -> bool { + self.nth_at(0, kind) + } + pub fn nth_at(&mut self, n: usize, kind: SyntaxKind) -> bool { if let ExpectedSyntaxTrackingState::Unnamed = self.expected_syntax_tracking_state.get() { self.expected_syntax = Some(ExpectedSyntax::Unnamed(kind)); } - self.peek() == Some(kind) + self.nth(n) == kind } - pub fn at_set(&mut self, set: SyntaxKindSet) -> bool { - self.peek().map_or(false, |k| set.contains(k)) + pub fn at_ts(&mut self, set: SyntaxKindSet) -> bool { + set.contains(self.current()) } pub fn at_end(&mut self) -> bool { - self.peek().is_none() + self.at(EOF) } } pub(crate) struct ExpectedSyntaxGuard { @@ -352,8 +410,8 @@ }} } -fn expr(p: &mut Parser) { - expr_binding_power(p, 0); +fn expr(p: &mut Parser) -> Option { + expr_binding_power(p, 0) } fn expr_binding_power(p: &mut Parser, minimum_binding_power: u8) -> Option { let mut lhs = lhs(p)?; @@ -392,7 +450,7 @@ p.bump(); } - let m = lhs.precede(p); + let m = lhs.wrap(p, LHS_EXPR).precede(p); let parsed_rhs = expr_binding_power(p, right_binding_power).is_some(); lhs = m.complete( p, @@ -414,11 +472,11 @@ if p.at(T![for]) { let m = p.start(); p.bump(); - p.expect(IDENT); + name(p); p.expect(T![in]); expr(p); m.complete(p, FOR_SPEC); - } else if p.at(T![in]) { + } else if p.at(T![if]) { let m = p.start(); p.bump(); expr(p); @@ -439,7 +497,7 @@ if p.at(T![,]) { p.bump(); true - } else if p.at_set(set) { + } else if p.at_ts(set) { p.expect_with_no_skip(T![,]); p.bump(); true @@ -449,18 +507,76 @@ } fn field_name(p: &mut Parser) { let _e = p.expected_syntax_name("field name"); + let m = p.start(); if p.at(T!['[']) { p.bump(); expr(p); p.expect(T![']']); + m.complete(p, FIELD_NAME_DYNAMIC); } else if p.at(IDENT) { + name(p); + m.complete(p, FIELD_NAME_FIXED); + } else if p.current().is_string() { + string(p); + m.complete(p, FIELD_NAME_FIXED); + } else { + p.error_with_recovery_set(TS![;]); + } +} +fn visibility(p: &mut Parser) { + if p.at_ts(TS![: :: :::]) { p.bump() } else { - p.error_with_recovery_set(TS![;]); + p.error_with_recovery_set(TS![]); } } +fn field(p: &mut Parser) { + let m = p.start(); + field_name(p); + let plus = if p.at(T![+]) { + let r = p.start_ranger(); + p.bump(); + Some(r.finish(p)) + } else { + None + }; + let params = if p.at(T!['(']) { + if let Some(plus) = plus { + p.custom_error(plus, "can't extend with method"); + } + params_desc(p); + if p.at(T![+]) { + let r = p.start_ranger(); + p.bump(); + p.custom_error(r.finish(p), "can't extend with method"); + } + true + } else { + false + }; + visibility(p); + expr(p); + + if params { + m.complete(p, FIELD_METHOD) + } else { + m.complete(p, FIELD_NORMAL) + }; +} +fn assertion(p: &mut Parser) { + assert!(p.at(T![assert])); + let m = p.start(); + p.bump(); + expr(p).map(|c| c.wrap(p, LHS_EXPR)); + if p.at(T![:]) { + p.bump(); + expr(p); + } + m.complete(p, ASSERTION); +} fn object(p: &mut Parser) -> CompletedMarker { assert!(p.at(T!['{'])); + let m_t = p.start(); let m = p.start(); p.bump(); @@ -470,13 +586,19 @@ break; } let m = p.start(); - field_name(p); - p.expect(T![,]); - expr(p); - while p.at(T![for]) || p.at(T![if]) { - compspec(p) - } - m.complete(p, MEMBER); + if p.at(T![local]) { + obj_local(p); + m.complete(p, MEMBER_BIND_STMT) + } else if p.at(T![assert]) { + assertion(p); + m.complete(p, MEMBER_ASSERT_STMT) + } else { + field(p); + while p.at(T![for]) || p.at(T![if]) { + compspec(p) + } + m.complete(p, MEMBER_FIELD) + }; if comma_with_alternatives(p, SyntaxKindSet::new(&[T![=]])) { continue; } @@ -484,10 +606,19 @@ break; } - m.complete(p, OBJ_BODY) + m.complete(p, OBJ_BODY_MEMBER_LIST); + m_t.complete(p, EXPR_OBJECT) +} +fn param(p: &mut Parser) { + let m = p.start(); + destruct(p); + if p.at(T![=]) { + p.bump(); + expr(p); + } + m.complete(p, PARAM); } - -fn params(p: &mut Parser) -> CompletedMarker { +fn params_desc(p: &mut Parser) -> CompletedMarker { assert!(p.at(T!['('])); let m = p.start(); p.bump(); @@ -496,14 +627,8 @@ if p.at(T![')']) { p.bump(); break; - } - let m = p.start(); - p.expect(IDENT); - if p.at(T![=]) { - p.bump(); - expr(p); } - m.complete(p, PARAM); + param(p); if comma(p) { continue; } @@ -513,48 +638,39 @@ m.complete(p, PARAMS_DESC) } -fn args(p: &mut Parser) { +fn args_desc(p: &mut Parser) { + let m = p.start(); assert!(p.at(T!['('])); p.bump(); - let mut error_positional_start = None::; - let mut started_named = Cell::new(false); - let mut on_positional = |p: &mut Parser, m: Marker| { - let c = m.complete(p, ARG); - if started_named.get() && error_positional_start.is_none() { - error_positional_start = Some(c.precede(p)); - } - }; + let started_named = Cell::new(false); + loop { if p.at(T![')']) { break; } let m = p.start(); - if p.at(IDENT) { + if p.at(IDENT) && p.nth_at(1, T![=]) { + name(p); p.bump(); - if p.at(T![=]) { - p.bump(); - expr(p); - m.complete(p, ARG); - started_named.set(true); - } else { - on_positional(p, m); - } + expr(p); + m.complete(p, ARG); + started_named.set(true); } else { expr(p); - on_positional(p, m); + m.complete(p, ARG); } if comma(p) { continue; } break; } - if let Some(error_positional_start) = error_positional_start { - let c = error_positional_start.complete(p, ERROR); - p.custom_error(c, "positional arguments can't be placed after named") + p.expect(T![')']); + if p.at(T![tailstrict]) { + p.bump() } - p.expect(T![')']); + m.complete(p, ARGS_DESC); } fn array(p: &mut Parser) -> CompletedMarker { @@ -605,7 +721,45 @@ m.complete(p, EXPR_ARRAY) } } - +/// Returns true if it was slice, false if just index +#[must_use] +fn slice_desc_or_index(p: &mut Parser) -> bool { + let m = p.start(); + p.bump(); + // TODO: do not treat :, ::, ::: as full tokens? + // Start + if !p.at(T![:]) && !p.at(T![::]) { + expr(p); + } + if p.at(T![:]) { + p.bump(); + // End + if !p.at(T![']']) { + expr(p).map(|c| c.wrap(p, SLICE_DESC_END)); + } + if p.at(T![:]) { + p.bump(); + // Step + if !p.at(T![']']) { + expr(p).map(|c| c.wrap(p, SLICE_DESC_STEP)); + } + } + } else if p.at(T![::]) { + p.bump(); + // End + if !p.at(T![']']) { + expr(p).map(|c| c.wrap(p, SLICE_DESC_END)); + } + } else { + // It was not a slice + p.expect(T![']']); + m.forget(p); + return false; + } + p.expect(T![']']); + m.complete(p, SLICE_DESC); + true +} fn lhs(p: &mut Parser) -> Option { let mut lhs = lhs_basic(p)?; @@ -613,34 +767,20 @@ if p.at(T![.]) { let m = lhs.precede(p); p.bump(); - p.expect(IDENT); + name(p); lhs = m.complete(p, EXPR_INDEX); } else if p.at(T!['[']) { - let m = lhs.precede(p); - p.bump(); - // Start - if !p.at(T![:]) { - expr(p); - } - if p.at(T![:]) { - p.bump(); - // End - if !p.at(T![']']) && !p.at(T![:]) { - expr(p); - } - if p.at(T![:]) { - p.bump(); - // Step - if !p.at(T![']']) { - expr(p); - } - } + if slice_desc_or_index(p) { + lhs = lhs.precede(p).complete(p, EXPR_SLICE); + } else { + lhs = lhs + .wrap(p, LHS_EXPR) + .precede(p) + .complete(p, EXPR_INDEX_EXPR); } - p.expect(T![']']); - lhs = m.complete(p, EXPR_SLICE); } else if p.at(T!['(']) { let m = lhs.precede(p); - args(p); + args_desc(p); lhs = m.complete(p, EXPR_APPLY); } else { break; @@ -649,25 +789,199 @@ Some(lhs) } - +fn name(p: &mut Parser) { + let m = p.start(); + p.expect(IDENT); + m.complete(p, NAME); +} +fn destruct_rest(p: &mut Parser) { + assert!(p.at(T![...])); + p.bump(); + let m = p.start(); + if p.at(IDENT) { + p.bump() + } + m.complete(p, DESTRUCT_REST); +} +fn destruct_object_field(p: &mut Parser) { + let m = p.start(); + name(p); + if p.at(T![:]) { + p.bump(); + destruct(p); + }; + if p.at(T![=]) { + p.bump(); + expr(p); + } + m.complete(p, DESTRUCT_OBJECT_FIELD); +} +fn obj_local(p: &mut Parser) { + assert!(p.at(T![local])); + let m = p.start(); + p.bump(); + bind(p); + m.complete(p, OBJ_LOCAL); +} +fn destruct(p: &mut Parser) -> CompletedMarker { + let m = p.start(); + if p.at(T![?]) { + p.bump(); + m.complete(p, DESTRUCT_SKIP) + } else if p.at(T!['[']) { + p.bump(); + let mut had_rest = false; + loop { + if p.at(T![']']) { + p.bump(); + break; + } else if p.at(T![...]) { + let m_err = p.start_ranger(); + destruct_rest(p); + if had_rest { + p.custom_error(m_err.finish(p), "only one rest can be present in array"); + } + had_rest = true; + } else { + destruct(p); + } + if p.at(T![,]) { + p.bump(); + continue; + } + p.expect(T![']']); + break; + } + m.complete(p, DESTRUCT_ARRAY) + } else if p.at(T!['{']) { + p.bump(); + let mut had_rest = false; + loop { + if p.at(T!['}']) { + p.bump(); + break; + } else if p.at(T![...]) { + let m_err = p.start_ranger(); + destruct_rest(p); + if had_rest { + p.custom_error(m_err.finish(p), "only one rest can be present in object"); + } + had_rest = true; + } else { + if had_rest { + p.error_with_recovery_set(TS![]); + } + destruct_object_field(p); + } + if p.at(T![,]) { + p.bump(); + continue; + } + p.expect(T!['}']); + break; + } + m.complete(p, DESTRUCT_OBJECT) + } else if p.at(IDENT) { + name(p); + m.complete(p, DESTRUCT_FULL) + } else { + m.complete(p, ERROR) + } +} +fn bind(p: &mut Parser) { + let m = p.start(); + if p.at(IDENT) && p.nth_at(1, T!['(']) { + name(p); + params_desc(p); + p.expect(T![=]); + expr(p); + m.complete(p, BIND_FUNCTION) + } else { + destruct(p); + p.expect(T![=]); + expr(p); + m.complete(p, BIND_DESTRUCT) + }; +} +fn string(p: &mut Parser) { + assert!(p.current().is_string()); + if p.at(STRING_BLOCK) { + // We use custom lexer, which skips enough bytes, but not returns error + // Instead we should call lexer again to verify if there is something wrong with string block + let mut lexer = logos::Lexer::::new(dbg!( + &p.current_lexeme().expect("parser is at string block").text + )); + // In kinds, string blocks is parsed at least as `|||` + lexer.bump(3); + let res = lex_str_block(&mut lexer); + debug_assert!(lexer.next().is_none(), "str_block is lexed"); + match res { + Ok(_) => { + p.bump(); + } + Err(e) => p.bump_remap(match e { + StringBlockError::UnexpectedEnd => ERROR_STRING_BLOCK_UNEXPECTED_END, + StringBlockError::MissingNewLine => ERROR_STRING_BLOCK_MISSING_NEW_LINE, + StringBlockError::MissingTermination => ERROR_STRING_BLOCK_MISSING_TERMINATION, + StringBlockError::MissingIndent => ERROR_STRING_BLOCK_MISSING_INDENT, + }), + } + } else { + p.bump(); + } +} +fn number(p: &mut Parser) { + assert!(p.current().is_number()); + p.bump(); +} +fn literal(p: &mut Parser) { + assert!(p.current().is_literal()); + p.bump(); +} fn lhs_basic(p: &mut Parser) -> Option { let _e = p.expected_syntax_name("value"); - Some(if p.peek().map(|l| l.is_literal()).unwrap_or(false) { + Some(if p.current().is_literal() { let m = p.start(); - p.bump(); + literal(p); m.complete(p, EXPR_LITERAL) - } else if p.peek().map(|l| l.is_string()).unwrap_or(false) { + } else if p.current().is_string() { let m = p.start(); - p.bump(); + string(p); m.complete(p, EXPR_STRING) - } else if p.peek().map(|l| l.is_number()).unwrap_or(false) { + } else if p.current().is_number() { let m = p.start(); - p.bump(); + number(p); m.complete(p, EXPR_NUMBER) } else if p.at(IDENT) { let m = p.start(); - p.bump(); + name(p); m.complete(p, EXPR_VAR) + } else if p.at(INTRINSIC_THIS_FILE) { + let m = p.start(); + p.bump(); + m.complete(p, EXPR_INTRINSIC_THIS_FILE) + } else if p.at(INTRINSIC_ID) { + let m = p.start(); + p.bump(); + m.complete(p, EXPR_INTRINSIC_ID) + } else if p.at(INTRINSIC) { + let m = p.start(); + p.bump(); + p.expect(T!['(']); + name(p); + p.expect(T![')']); + m.complete(p, EXPR_INTRINSIC) + } else if p.at(T![if]) { + let m = p.start(); + p.bump(); + expr(p); + p.expect(T![then]); + expr(p).map(|c| c.wrap(p, TRUE_EXPR)); + if p.at(T![else]) { + p.bump(); + expr(p).map(|c| c.wrap(p, FALSE_EXPR)); + } + m.complete(p, EXPR_IF_THEN_ELSE) } else if p.at(T!['[']) { array(p) } else if p.at(T!['{']) { @@ -675,35 +989,26 @@ } else if p.at(T![local]) { let m = p.start(); p.bump(); - let mut sus_local = None; loop { - p.expect_with_recovery_set(IDENT, TS![= ; local]); - if p.at(T!['(']) { - params(p); + if p.at(T![;]) { + p.bump(); + break; } - - let sus_local_candidate = p.start_ranger(); - p.expect_with_recovery_set(T![=], TS![; local]); + bind(p); - sus_local = p.at(T![local]).then(|| sus_local_candidate.finish(p)); - expr(p); - - if !comma(p) { - break; + if p.at(T![,]) { + p.bump(); + continue; } - } - p.expect(T![;]); - if let Some(sus_local) = sus_local { - if sus_local.had_error_since(p) { - p.custom_error(sus_local, "unusal local placement, missing ';' ?") - } + p.expect(T![;]); + break; } expr(p); - m.complete(p, T![local]) + m.complete(p, EXPR_LOCAL) } else if p.at(T![function]) { let m = p.start(); p.bump(); - args(p); + params_desc(p); expr(p); m.complete(p, EXPR_FUNCTION) } else if p.at(T![error]) { @@ -713,20 +1018,17 @@ m.complete(p, EXPR_ERROR) } else if p.at(T![assert]) { let m = p.start(); - p.bump(); + assertion(p); + p.expect(T![;]); expr(p); - if p.at(T![:]) { - p.bump(); - expr(p); - } m.complete(p, EXPR_ASSERT) } else if p.at(T![import]) || p.at(T![importstr]) || p.at(T![importbin]) { let m = p.start(); p.bump(); - expr(p); + string(p); m.complete(p, EXPR_IMPORT) } else if p.at(T![-]) || p.at(T![!]) || p.at(T![~]) { - let op = match p.peek().unwrap() { + let op = match p.current() { T![-] => UnaryOperator::Minus, T![!] => UnaryOperator::Not, T![~] => UnaryOperator::BitNegate, @@ -746,7 +1048,7 @@ p.bump(); m.complete(p, EXPR_PARENED) } else { - p.error_with_no_skip(); + p.error_with_recovery_set(TS![]); return None; }) } @@ -755,14 +1057,4 @@ pub fn syntax(&self) -> SyntaxNode { SyntaxNode::new_root(self.green_node.clone()) } -} - -pub fn parse(input: &str) -> Parse { - let lexemes = lex(input); - let parser = Parser::new(&lexemes); - let events = parser.parse(); - dbg!(&events); - let sink = Sink::new(events, &lexemes); - - sink.finish() } --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__array_comp.snap +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__array_comp.snap @@ -1,43 +1,34 @@ --- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 +source: crates/jrsonnet-rowan-parser/src/tests.rs expression: "[a for a in [1, 2, 3]]\n" - --- -Root@0..23 - Array@0..23 - SymbolLeftBracket@0..1 "[" - ArrayElem@1..21 - BodyDef@1..3 - Ident@1..3 - Ident@1..2 "a" - Whitespace@2..3 " " - CompspecFor@3..21 - KeywordFor@3..6 "for" - Whitespace@6..7 " " - Ident@7..8 "a" - Whitespace@8..9 " " - OpIn@9..11 "in" - Whitespace@11..12 " " - Array@12..21 - SymbolLeftBracket@12..13 "[" - ArrayElem@13..14 - BodyDef@13..14 - Literal@13..14 - Number@13..14 "1" - SymbolComma@14..15 "," - Whitespace@15..16 " " - ArrayElem@16..17 - BodyDef@16..17 - Literal@16..17 - Number@16..17 "2" - SymbolComma@17..18 "," - Whitespace@18..19 " " - ArrayElem@19..20 - BodyDef@19..20 - Literal@19..20 - Number@19..20 "3" - SymbolRightBracket@20..21 "]" - SymbolRightBracket@21..22 "]" - Whitespace@22..23 "\n" +SOURCE_FILE@0..22 + EXPR_ARRAY_COMP@0..22 + L_BRACK@0..1 "[" + EXPR_VAR@1..2 + NAME@1..2 + IDENT@1..2 "a" + WHITESPACE@2..3 " " + FOR_SPEC@3..21 + FOR_KW@3..6 "for" + WHITESPACE@6..7 " " + NAME@7..8 + IDENT@7..8 "a" + WHITESPACE@8..9 " " + IN_KW@9..11 "in" + WHITESPACE@11..12 " " + EXPR_ARRAY@12..21 + L_BRACK@12..13 "[" + EXPR_NUMBER@13..14 + FLOAT@13..14 "1" + COMMA@14..15 "," + WHITESPACE@15..16 " " + EXPR_NUMBER@16..17 + FLOAT@16..17 "2" + COMMA@17..18 "," + WHITESPACE@18..19 " " + EXPR_NUMBER@19..20 + FLOAT@19..20 "3" + R_BRACK@20..21 "]" + R_BRACK@21..22 "]" --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__array_comp_incompatible_with_multiple_elems.snap +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__array_comp_incompatible_with_multiple_elems.snap @@ -1,58 +1,48 @@ --- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 +source: crates/jrsonnet-rowan-parser/src/tests.rs expression: "[a for a in [1, 2, 3], b]\n" - --- -Root@0..26 - Array@0..26 - SymbolLeftBracket@0..1 "[" - ArrayElem@1..21 - BodyDef@1..3 - Ident@1..3 - Ident@1..2 "a" - Whitespace@2..3 " " - CompspecFor@3..21 - KeywordFor@3..6 "for" - Whitespace@6..7 " " - Ident@7..8 "a" - Whitespace@8..9 " " - OpIn@9..11 "in" - Whitespace@11..12 " " - Array@12..21 - SymbolLeftBracket@12..13 "[" - ArrayElem@13..14 - BodyDef@13..14 - Literal@13..14 - Number@13..14 "1" - SymbolComma@14..15 "," - Whitespace@15..16 " " - ArrayElem@16..17 - BodyDef@16..17 - Literal@16..17 - Number@16..17 "2" - SymbolComma@17..18 "," - Whitespace@18..19 " " - ArrayElem@19..20 - BodyDef@19..20 - Literal@19..20 - Number@19..20 "3" - SymbolRightBracket@20..21 "]" - SymbolComma@21..22 "," - Whitespace@22..23 " " - ArrayElem@23..24 - BodyDef@23..24 - Ident@23..24 - Ident@23..24 "b" - SymbolRightBracket@24..25 "]" - Whitespace@25..26 "\n" +SOURCE_FILE@0..25 + EXPR_ARRAY@0..25 + L_BRACK@0..1 "[" + EXPR_VAR@1..2 + NAME@1..2 + IDENT@1..2 "a" + WHITESPACE@2..3 " " + FOR_SPEC@3..21 + FOR_KW@3..6 "for" + WHITESPACE@6..7 " " + NAME@7..8 + IDENT@7..8 "a" + WHITESPACE@8..9 " " + IN_KW@9..11 "in" + WHITESPACE@11..12 " " + EXPR_ARRAY@12..21 + L_BRACK@12..13 "[" + EXPR_NUMBER@13..14 + FLOAT@13..14 "1" + COMMA@14..15 "," + WHITESPACE@15..16 " " + EXPR_NUMBER@16..17 + FLOAT@16..17 "2" + COMMA@17..18 "," + WHITESPACE@18..19 " " + EXPR_NUMBER@19..20 + FLOAT@19..20 "3" + R_BRACK@20..21 "]" + COMMA@21..22 "," + WHITESPACE@22..23 " " + EXPR_VAR@23..24 + NAME@23..24 + IDENT@23..24 "b" + R_BRACK@24..25 "]" === Custom { error: "compspec may only be used if there is only one array element", range: 3..21 } === - × syntax error - ╭──── - 1 │ [a for a in [1, 2, 3], b] - ·  ─────────┬──────── - · ╰── compspec may only be used if there is only one array element - ╰──── + x syntax error + ,---- + 1 | [a for a in [1, 2, 3], b] + : ^^^^^^^^^|^^^^^^^^ + : `-- compspec may only be used if there is only one array element + `---- --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__empty.snap +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__empty.snap @@ -1,18 +1,14 @@ --- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 +source: crates/jrsonnet-rowan-parser/src/tests.rs expression: " " - --- -Root@0..1 - Whitespace@0..1 " " +SOURCE_FILE@0..1 + WHITESPACE@0..1 " " === Missing { expected: Named("value"), offset: 1 } === - × syntax error - ╭──── - 1 │ - ·  ▲ - · ╰── missing value - ╰──── + x syntax error + ,---- + 1 | + `---- --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__function.snap +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__function.snap @@ -1,34 +1,38 @@ --- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 +source: crates/jrsonnet-rowan-parser/src/tests.rs expression: "function(a, b = 1) a + b\n" - --- -Root@0..25 - FunctionDef@0..25 - KeywordFunction@0..8 "function" - LParen@8..9 "(" - DefPositionalArg@9..10 - Ident@9..10 "a" - SymbolComma@10..11 "," - Whitespace@11..12 " " - DefNamedArg@12..17 - Ident@12..13 "b" - Whitespace@13..14 " " - SymbolAssign@14..15 "=" - Whitespace@15..16 " " - Literal@16..17 - Number@16..17 "1" - RParen@17..18 ")" - Whitespace@18..19 " " - BodyDef@19..25 - BinOp@19..25 - Ident@19..21 - Ident@19..20 "a" - Whitespace@20..21 " " - OpPlus@21..22 "+" - Whitespace@22..23 " " - Ident@23..25 - Ident@23..24 "b" - Whitespace@24..25 "\n" +SOURCE_FILE@0..24 + EXPR_FUNCTION@0..24 + FUNCTION_KW@0..8 "function" + PARAMS_DESC@8..18 + L_PAREN@8..9 "(" + PARAM@9..10 + DESTRUCT_FULL@9..10 + NAME@9..10 + IDENT@9..10 "a" + COMMA@10..11 "," + WHITESPACE@11..12 " " + PARAM@12..17 + DESTRUCT_FULL@12..13 + NAME@12..13 + IDENT@12..13 "b" + WHITESPACE@13..14 " " + ASSIGN@14..15 "=" + WHITESPACE@15..16 " " + EXPR_NUMBER@16..17 + FLOAT@16..17 "1" + R_PAREN@17..18 ")" + WHITESPACE@18..19 " " + EXPR_BINARY@19..24 + LHS_EXPR@19..20 + EXPR_VAR@19..20 + NAME@19..20 + IDENT@19..20 "a" + WHITESPACE@20..21 " " + PLUS@21..22 "+" + WHITESPACE@22..23 " " + EXPR_VAR@23..24 + NAME@23..24 + IDENT@23..24 "b" --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__function_error_body.snap +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__function_error_body.snap @@ -1,29 +1,30 @@ --- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 +source: crates/jrsonnet-rowan-parser/src/tests.rs expression: "function(a, b)\n" - --- -Root@0..15 - FunctionDef@0..15 - KeywordFunction@0..8 "function" - LParen@8..9 "(" - DefPositionalArg@9..10 - Ident@9..10 "a" - SymbolComma@10..11 "," - Whitespace@11..12 " " - DefPositionalArg@12..13 - Ident@12..13 "b" - RParen@13..14 ")" - Whitespace@14..15 "\n" - BodyDef@15..15 +SOURCE_FILE@0..14 + EXPR_FUNCTION@0..14 + FUNCTION_KW@0..8 "function" + PARAMS_DESC@8..14 + L_PAREN@8..9 "(" + PARAM@9..10 + DESTRUCT_FULL@9..10 + NAME@9..10 + IDENT@9..10 "a" + COMMA@10..11 "," + WHITESPACE@11..12 " " + PARAM@12..13 + DESTRUCT_FULL@12..13 + NAME@12..13 + IDENT@12..13 "b" + R_PAREN@13..14 ")" === Missing { expected: Named("value"), offset: 14 } === - × syntax error - ╭──── - 1 │ function(a, b) - ·  ▲ - · ╰── missing value - ╰──── + x syntax error + ,---- + 1 | function(a, b) + : ^ + : `-- missing value + `---- --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__function_error_no_value.snap +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__function_error_no_value.snap @@ -1,41 +1,39 @@ --- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 +source: crates/jrsonnet-rowan-parser/src/tests.rs expression: "function(a, b = ) a + b\n" - --- -Root@0..24 - FunctionDef@0..24 - KeywordFunction@0..8 "function" - LParen@8..9 "(" - DefPositionalArg@9..10 - Ident@9..10 "a" - SymbolComma@10..11 "," - Whitespace@11..12 " " - DefNamedArg@12..16 - Ident@12..13 "b" - Whitespace@13..14 " " - SymbolAssign@14..15 "=" - Whitespace@15..16 " " - RParen@16..17 ")" - Whitespace@17..18 " " - BodyDef@18..24 - BinOp@18..24 - Ident@18..20 - Ident@18..19 "a" - Whitespace@19..20 " " - OpPlus@20..21 "+" - Whitespace@21..22 " " - Ident@22..24 - Ident@22..23 "b" - Whitespace@23..24 "\n" +SOURCE_FILE@0..24 + EXPR_FUNCTION@0..24 + FUNCTION_KW@0..8 "function" + PARAMS_DESC@8..18 + L_PAREN@8..9 "(" + PARAM@9..10 + IDENT@9..10 "a" + COMMA@10..11 "," + WHITESPACE@11..12 " " + PARAM@12..16 + IDENT@12..13 "b" + WHITESPACE@13..14 " " + ASSIGN@14..15 "=" + WHITESPACE@15..16 " " + R_PAREN@16..17 ")" + WHITESPACE@17..18 " " + EXPR_BINARY@18..24 + EXPR_VAR@18..20 + IDENT@18..19 "a" + WHITESPACE@19..20 " " + PLUS@20..21 "+" + WHITESPACE@21..22 " " + EXPR_VAR@22..24 + IDENT@22..23 "b" + WHITESPACE@23..24 "\n" === Missing { expected: Named("value"), offset: 15 } === - × syntax error - ╭──── - 1 │ function(a, b = ) a + b - ·  ▲ - · ╰── missing value - ╰──── + x syntax error + ,---- + 1 | function(a, b = ) a + b + : ^ + : `-- missing value + `---- --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__function_error_rparen.snap +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__function_error_rparen.snap @@ -1,30 +1,31 @@ --- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 +source: crates/jrsonnet-rowan-parser/src/tests.rs expression: "function(a, b\n" - --- -Root@0..14 - FunctionDef@0..14 - KeywordFunction@0..8 "function" - LParen@8..9 "(" - DefPositionalArg@9..10 - Ident@9..10 "a" - SymbolComma@10..11 "," - Whitespace@11..12 " " - DefPositionalArg@12..14 - Ident@12..13 "b" - Whitespace@13..14 "\n" - BodyDef@14..14 +SOURCE_FILE@0..13 + EXPR_FUNCTION@0..13 + FUNCTION_KW@0..8 "function" + PARAMS_DESC@8..13 + L_PAREN@8..9 "(" + PARAM@9..10 + DESTRUCT_FULL@9..10 + NAME@9..10 + IDENT@9..10 "a" + COMMA@10..11 "," + WHITESPACE@11..12 " " + PARAM@12..13 + DESTRUCT_FULL@12..13 + NAME@12..13 + IDENT@12..13 "b" === -Missing { expected: Unnamed(RParen), offset: 13 } +Missing { expected: Unnamed(R_PAREN), offset: 13 } Missing { expected: Named("value"), offset: 13 } === - × syntax error - ╭──── - 1 │ function(a, b - ·  ▲ - · │╰── missing value - · ╰── missing RParen - ╰──── + x syntax error + ,---- + 1 | function(a, b + : ^ + : |`-- missing value + : `-- missing R_PAREN + `---- --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__local_no_value_recovery.snap +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__local_no_value_recovery.snap @@ -1,47 +1,39 @@ --- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 +source: crates/jrsonnet-rowan-parser/src/tests.rs expression: "local a =\nlocal b = 3;\n1\n" - --- -Root@0..25 - Local@0..25 - KeywordLocal@0..5 "local" - Whitespace@5..6 " " - Ident@6..7 "a" - Whitespace@7..8 " " - SymbolAssign@8..9 "=" - Whitespace@9..10 "\n" - Local@10..25 - KeywordLocal@10..15 "local" - Whitespace@15..16 " " - Ident@16..17 "b" - Whitespace@17..18 " " - SymbolAssign@18..19 "=" - Whitespace@19..20 " " - Literal@20..21 - Number@20..21 "3" - SymbolSemi@21..22 ";" - Whitespace@22..23 "\n" - BodyDef@23..25 - Literal@23..25 - Number@23..24 "1" - Whitespace@24..25 "\n" - BodyDef@25..25 +SOURCE_FILE@0..25 + LOCAL_KW@0..25 + LOCAL_KW@0..5 "local" + WHITESPACE@5..6 " " + IDENT@6..7 "a" + WHITESPACE@7..8 " " + ASSIGN@8..9 "=" + WHITESPACE@9..10 "\n" + LOCAL_KW@10..25 + LOCAL_KW@10..15 "local" + WHITESPACE@15..16 " " + IDENT@16..17 "b" + WHITESPACE@17..18 " " + ASSIGN@18..19 "=" + WHITESPACE@19..20 " " + EXPR_NUMBER@20..21 + NUMBER@20..21 "3" + SEMI@21..22 ";" + WHITESPACE@22..23 "\n" + EXPR_NUMBER@23..25 + NUMBER@23..24 "1" + WHITESPACE@24..25 "\n" === -Missing { expected: Unnamed(SymbolSemi), offset: 24 } -Custom { error: "unusal local placement, missing ';' ?", range: 8..9 } +Missing { expected: Unnamed(SEMI), offset: 24 } Missing { expected: Named("value"), offset: 24 } === - × syntax error - ╭─[1:1] - 1 │ local a = - ·  ┬ - · ╰── unusal local placement, missing ';' ? - 2 │ local b = 3; - 3 │ 1 - ·  ▲ - · │╰── missing value - · ╰── missing SymbolSemi - ╰──── + x syntax error + ,-[2:1] + 2 | local b = 3; + 3 | 1 + : ^ + : |`-- missing value + : `-- missing SEMI + `---- --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__local_no_value_recovery.snap.new +++ /dev/null @@ -1,43 +0,0 @@ ---- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 -expression: "local a =\nlocal b = 3;\n1\n" - ---- -Root@0..25 - Local@0..25 - KeywordLocal@0..5 "local" - Whitespace@5..6 " " - Ident@6..7 "a" - Whitespace@7..8 " " - SymbolAssign@8..9 "=" - Whitespace@9..10 "\n" - Local@10..25 - KeywordLocal@10..15 "local" - Whitespace@15..16 " " - Ident@16..17 "b" - Whitespace@17..18 " " - SymbolAssign@18..19 "=" - Whitespace@19..20 " " - Literal@20..21 - Number@20..21 "3" - SymbolSemi@21..22 ";" - Whitespace@22..23 "\n" - BodyDef@23..25 - Literal@23..25 - Number@23..24 "1" - Whitespace@24..25 "\n" - BodyDef@25..25 -=== -Missing { expected: Unnamed(SymbolSemi), offset: 24 } -Missing { expected: Named("value"), offset: 24 } -=== - × syntax error - ╭─[2:1] - 2 │ local b = 3; - 3 │ 1 - ·  ▲ - · │╰── missing value - · ╰── missing SymbolSemi - ╰──── - --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__local_novalue.snap +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__local_novalue.snap @@ -1,29 +1,26 @@ --- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 +source: crates/jrsonnet-rowan-parser/src/tests.rs expression: "local a =\n" - --- -Root@0..10 - Local@0..10 - KeywordLocal@0..5 "local" - Whitespace@5..6 " " - Ident@6..7 "a" - Whitespace@7..8 " " - SymbolAssign@8..9 "=" - Whitespace@9..10 "\n" - BodyDef@10..10 +SOURCE_FILE@0..10 + LOCAL_KW@0..10 + LOCAL_KW@0..5 "local" + WHITESPACE@5..6 " " + IDENT@6..7 "a" + WHITESPACE@7..8 " " + ASSIGN@8..9 "=" + WHITESPACE@9..10 "\n" === Missing { expected: Named("value"), offset: 9 } -Missing { expected: Unnamed(SymbolSemi), offset: 9 } +Missing { expected: Unnamed(SEMI), offset: 9 } Missing { expected: Named("value"), offset: 9 } === - × syntax error - ╭──── - 1 │ local a = - ·  ▲ - · ╰── missing value - · │╰── missing SymbolSemi - · ╰── missing value - ╰──── + x syntax error + ,---- + 1 | local a = + : ^ + : `-- missing value + : |`-- missing SEMI + : `-- missing value + `---- --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__named_before_positional.snap +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__named_before_positional.snap @@ -1,63 +1,61 @@ --- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 +source: crates/jrsonnet-rowan-parser/src/tests.rs expression: "a(1, 2, b=4, 3, 5, k = 12, 6)\n" - --- -Root@0..30 - FunctionCall@0..30 - Ident@0..1 - Ident@0..1 "a" - LParen@1..2 "(" - DefPositionalArg@2..3 - Literal@2..3 - Number@2..3 "1" - SymbolComma@3..4 "," - Whitespace@4..5 " " - DefPositionalArg@5..6 - Literal@5..6 - Number@5..6 "2" - SymbolComma@6..7 "," - Whitespace@7..8 " " - DefNamedArg@8..11 - Ident@8..9 "b" - SymbolAssign@9..10 "=" - Literal@10..11 - Number@10..11 "4" - SymbolComma@11..12 "," - Whitespace@12..13 " " - ErrorPositionalAfterNamed@13..28 - DefPositionalArg@13..14 - Literal@13..14 - Number@13..14 "3" - SymbolComma@14..15 "," - Whitespace@15..16 " " - DefPositionalArg@16..17 - Literal@16..17 - Number@16..17 "5" - SymbolComma@17..18 "," - Whitespace@18..19 " " - DefNamedArg@19..25 - Ident@19..20 "k" - Whitespace@20..21 " " - SymbolAssign@21..22 "=" - Whitespace@22..23 " " - Literal@23..25 - Number@23..25 "12" - SymbolComma@25..26 "," - Whitespace@26..27 " " - DefPositionalArg@27..28 - Literal@27..28 - Number@27..28 "6" - RParen@28..29 ")" - Whitespace@29..30 "\n" +SOURCE_FILE@0..30 + EXPR_APPLY@0..30 + EXPR_VAR@0..1 + IDENT@0..1 "a" + L_PAREN@1..2 "(" + ARG@2..3 + EXPR_NUMBER@2..3 + NUMBER@2..3 "1" + COMMA@3..4 "," + WHITESPACE@4..5 " " + ARG@5..6 + EXPR_NUMBER@5..6 + NUMBER@5..6 "2" + COMMA@6..7 "," + WHITESPACE@7..8 " " + ARG@8..11 + IDENT@8..9 "b" + ASSIGN@9..10 "=" + EXPR_NUMBER@10..11 + NUMBER@10..11 "4" + COMMA@11..12 "," + WHITESPACE@12..13 " " + ERROR@13..28 + ARG@13..14 + EXPR_NUMBER@13..14 + NUMBER@13..14 "3" + COMMA@14..15 "," + WHITESPACE@15..16 " " + ARG@16..17 + EXPR_NUMBER@16..17 + NUMBER@16..17 "5" + COMMA@17..18 "," + WHITESPACE@18..19 " " + ARG@19..25 + IDENT@19..20 "k" + WHITESPACE@20..21 " " + ASSIGN@21..22 "=" + WHITESPACE@22..23 " " + EXPR_NUMBER@23..25 + NUMBER@23..25 "12" + COMMA@25..26 "," + WHITESPACE@26..27 " " + ARG@27..28 + EXPR_NUMBER@27..28 + NUMBER@27..28 "6" + R_PAREN@28..29 ")" + WHITESPACE@29..30 "\n" === Custom { error: "positional arguments can't be placed after named", range: 13..28 } === - × syntax error - ╭──── - 1 │ a(1, 2, b=4, 3, 5, k = 12, 6) - ·  ───────┬─────── - · ╰── positional arguments can't be placed after named - ╰──── + x syntax error + ,---- + 1 | a(1, 2, b=4, 3, 5, k = 12, 6) + : ^^^^^^^|^^^^^^^ + : `-- positional arguments can't be placed after named + `---- --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__no_lhs.snap +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__no_lhs.snap @@ -1,23 +1,19 @@ --- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 +source: crates/jrsonnet-rowan-parser/src/tests.rs expression: "+ 2\n" - --- -Root@0..4 - OpPlus@0..1 "+" - Whitespace@1..2 " " - Number@2..3 "2" - Whitespace@3..4 "\n" +SOURCE_FILE@0..2 + PLUS@0..1 "+" + WHITESPACE@1..2 " " === Missing { expected: Named("value"), offset: 0 } -Custom { error: "unexpected input after expression", range: 0..3 } +Custom { error: "unexpected input after expression", range: 0..1 } === - × syntax error - ╭──── - 1 │ + 2 - · ▲─┬─ - · │╰── unexpected input after expression - · ╰── missing value - ╰──── + x syntax error + ,---- + 1 | + 2 + : ^ + : |`-- unexpected input after expression + : `-- missing value + `---- --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__no_operator.snap +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__no_operator.snap @@ -1,22 +1,20 @@ --- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 +source: crates/jrsonnet-rowan-parser/src/tests.rs expression: "2 2\n" - --- -Root@0..4 - Literal@0..2 - Number@0..1 "2" - Whitespace@1..2 " " - Number@2..3 "2" - Whitespace@3..4 "\n" +SOURCE_FILE@0..3 + EXPR_NUMBER@0..1 + FLOAT@0..1 "2" + WHITESPACE@1..2 " " + ERROR@2..3 + FLOAT@2..3 "2" === -Custom { error: "unexpected input after expression", range: 2..3 } +Unexpected { expected: Unnamed(EOF), found: FLOAT, range: 2..3 } === - × syntax error - ╭──── - 1 │ 2 2 - ·  ┬ - · ╰── unexpected input after expression - ╰──── + x syntax error + ,---- + 1 | 2 2 + : | + : `-- expected EOF, found FLOAT + `---- --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__no_rhs.snap +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__no_rhs.snap @@ -1,23 +1,22 @@ --- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 +source: crates/jrsonnet-rowan-parser/src/tests.rs expression: "a +\n" - --- -Root@0..4 - BinOp@0..4 - Ident@0..2 - Ident@0..1 "a" - Whitespace@1..2 " " - OpPlus@2..3 "+" - Whitespace@3..4 "\n" +SOURCE_FILE@0..3 + EXPR_BINARY@0..3 + LHS_EXPR@0..1 + EXPR_VAR@0..1 + NAME@0..1 + IDENT@0..1 "a" + WHITESPACE@1..2 " " + PLUS@2..3 "+" === Missing { expected: Named("value"), offset: 3 } === - × syntax error - ╭──── - 1 │ a + - ·  ▲ - · ╰── missing value - ╰──── + x syntax error + ,---- + 1 | a + + : ^ + : `-- missing value + `---- --- /dev/null +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__plain_call.snap @@ -0,0 +1,52 @@ +--- +source: crates/jrsonnet-rowan-parser/src/tests.rs +expression: "std.substr(a, 0, std.length(b)) == b\n" +--- +SOURCE_FILE@0..36 + EXPR_BINARY@0..36 + LHS_EXPR@0..31 + EXPR_APPLY@0..31 + EXPR_INDEX@0..10 + EXPR_VAR@0..3 + NAME@0..3 + IDENT@0..3 "std" + DOT@3..4 "." + NAME@4..10 + IDENT@4..10 "substr" + ARGS_DESC@10..31 + L_PAREN@10..11 "(" + ARG@11..12 + EXPR_VAR@11..12 + NAME@11..12 + IDENT@11..12 "a" + COMMA@12..13 "," + WHITESPACE@13..14 " " + ARG@14..15 + EXPR_NUMBER@14..15 + FLOAT@14..15 "0" + COMMA@15..16 "," + WHITESPACE@16..17 " " + ARG@17..30 + EXPR_APPLY@17..30 + EXPR_INDEX@17..27 + EXPR_VAR@17..20 + NAME@17..20 + IDENT@17..20 "std" + DOT@20..21 "." + NAME@21..27 + IDENT@21..27 "length" + ARGS_DESC@27..30 + L_PAREN@27..28 "(" + ARG@28..29 + EXPR_VAR@28..29 + NAME@28..29 + IDENT@28..29 "b" + R_PAREN@29..30 ")" + R_PAREN@30..31 ")" + WHITESPACE@31..32 " " + EQ@32..34 "==" + WHITESPACE@34..35 " " + EXPR_VAR@35..36 + NAME@35..36 + IDENT@35..36 "b" + --- /dev/null +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__stdlib.snap @@ -0,0 +1,12345 @@ +--- +source: crates/jrsonnet-rowan-parser/src/tests.rs +expression: "{\n local std = self,\n local id = std.id,\n\n # Magic legacy field\n thisFile:: $intrinsicThisFile,\n id:: $intrinsicId,\n\n # Those functions aren't normally located in stdlib\n length:: $intrinsic(length),\n type:: $intrinsic(type),\n makeArray:: $intrinsic(makeArray),\n codepoint:: $intrinsic(codepoint),\n objectFieldsEx:: $intrinsic(objectFieldsEx),\n objectHasEx:: $intrinsic(objectHasEx),\n primitiveEquals:: $intrinsic(primitiveEquals),\n modulo:: $intrinsic(modulo),\n floor:: $intrinsic(floor),\n ceil:: $intrinsic(ceil),\n extVar:: $intrinsic(extVar),\n native:: $intrinsic(native),\n filter:: $intrinsic(filter),\n char:: $intrinsic(char),\n encodeUTF8:: $intrinsic(encodeUTF8),\n decodeUTF8:: $intrinsic(decodeUTF8),\n md5:: $intrinsic(md5),\n trace:: $intrinsic(trace),\n parseJson:: $intrinsic(parseJson),\n parseYaml:: $intrinsic(parseYaml),\n\n log:: $intrinsic(log),\n pow:: $intrinsic(pow),\n sqrt:: $intrinsic(sqrt),\n\n sin:: $intrinsic(sin),\n cos:: $intrinsic(cos),\n tan:: $intrinsic(tan),\n asin:: $intrinsic(asin),\n acos:: $intrinsic(acos),\n atan:: $intrinsic(atan),\n\n exp:: $intrinsic(exp),\n mantissa:: $intrinsic(mantissa),\n exponent:: $intrinsic(exponent),\n\n any:: $intrinsic(any),\n all:: $intrinsic(all),\n\n isString(v):: std.type(v) == 'string',\n isNumber(v):: std.type(v) == 'number',\n isBoolean(v):: std.type(v) == 'boolean',\n isObject(v):: std.type(v) == 'object',\n isArray(v):: std.type(v) == 'array',\n isFunction(v):: std.type(v) == 'function',\n\n toString(a)::\n if std.type(a) == 'string' then a else '' + a,\n\n substr:: $intrinsic(substr),\n\n startsWith(a, b)::\n if std.length(a) < std.length(b) then\n false\n else\n std.substr(a, 0, std.length(b)) == b,\n\n endsWith(a, b)::\n if std.length(a) < std.length(b) then\n false\n else\n std.substr(a, std.length(a) - std.length(b), std.length(b)) == b,\n\n lstripChars(str, chars)::\n if std.length(str) > 0 && std.member(chars, str[0]) then\n std.lstripChars(str[1:], chars)\n else\n str,\n\n rstripChars(str, chars)::\n local len = std.length(str);\n if len > 0 && std.member(chars, str[len - 1]) then\n std.rstripChars(str[:len - 1], chars)\n else\n str,\n\n stripChars(str, chars)::\n std.lstripChars(std.rstripChars(str, chars), chars),\n\n stringChars(str)::\n std.makeArray(std.length(str), function(i) str[i]),\n\n local parse_nat(str, base) =\n assert base > 0 && base <= 16 : 'integer base %d invalid' % base;\n // These codepoints are in ascending order:\n local zero_code = std.codepoint('0');\n local upper_a_code = std.codepoint('A');\n local lower_a_code = std.codepoint('a');\n local addDigit(aggregate, char) =\n local code = std.codepoint(char);\n local digit = if code >= lower_a_code then\n code - lower_a_code + 10\n else if code >= upper_a_code then\n code - upper_a_code + 10\n else\n code - zero_code;\n assert digit >= 0 && digit < base : '%s is not a base %d integer' % [str, base];\n base * aggregate + digit;\n std.foldl(addDigit, std.stringChars(str), 0),\n\n parseInt(str)::\n assert std.isString(str) : 'Expected string, got ' + std.type(str);\n assert std.length(str) > 0 && str != '-' : 'Not an integer: \"%s\"' % [str];\n if str[0] == '-' then\n -parse_nat(str[1:], 10)\n else\n parse_nat(str, 10),\n\n parseOctal(str)::\n assert std.isString(str) : 'Expected string, got ' + std.type(str);\n assert std.length(str) > 0 : 'Not an octal number: \"\"';\n parse_nat(str, 8),\n\n parseHex(str)::\n assert std.isString(str) : 'Expected string, got ' + std.type(str);\n assert std.length(str) > 0 : 'Not hexadecimal: \"\"';\n parse_nat(str, 16),\n\n split(str, c):: std.splitLimit(str, c, -1),\n\n splitLimit:: $intrinsic(splitLimit),\n\n strReplace:: $intrinsic(strReplace),\n\n asciiUpper:: $intrinsic(asciiUpper),\n\n asciiLower:: $intrinsic(asciiLower),\n\n range:: $intrinsic(range),\n\n repeat(what, count)::\n local joiner =\n if std.isString(what) then ''\n else if std.isArray(what) then []\n else error 'std.repeat first argument must be an array or a string';\n std.join(joiner, std.makeArray(count, function(i) what)),\n\n slice:: $intrinsic(slice),\n\n member:: $intrinsic(member),\n\n count:: $intrinsic(count),\n\n mod:: $intrinsic(mod),\n\n map:: $intrinsic(map),\n\n mapWithIndex(func, arr)::\n if !std.isFunction(func) then\n error ('std.mapWithIndex first param must be function, got ' + std.type(func))\n else if !std.isArray(arr) && !std.isString(arr) then\n error ('std.mapWithIndex second param must be array, got ' + std.type(arr))\n else\n std.makeArray(std.length(arr), function(i) func(i, arr[i])),\n\n mapWithKey(func, obj)::\n if !std.isFunction(func) then\n error ('std.mapWithKey first param must be function, got ' + std.type(func))\n else if !std.isObject(obj) then\n error ('std.mapWithKey second param must be object, got ' + std.type(obj))\n else\n { [k]: func(k, obj[k]) for k in std.objectFields(obj) },\n\n flatMap:: $intrinsic(flatMap),\n\n join:: $intrinsic(join),\n\n lines(arr)::\n std.join('\\n', arr + ['']),\n\n deepJoin(arr)::\n if std.isString(arr) then\n arr\n else if std.isArray(arr) then\n std.join('', [std.deepJoin(x) for x in arr])\n else\n error 'Expected string or array, got %s' % std.type(arr),\n\n\n format:: $intrinsic(format),\n\n foldr:: $intrinsic(foldr),\n\n foldl:: $intrinsic(foldl),\n\n filterMap(filter_func, map_func, arr)::\n if !std.isFunction(filter_func) then\n error ('std.filterMap first param must be function, got ' + std.type(filter_func))\n else if !std.isFunction(map_func) then\n error ('std.filterMap second param must be function, got ' + std.type(map_func))\n else if !std.isArray(arr) then\n error ('std.filterMap third param must be array, got ' + std.type(arr))\n else\n std.map(map_func, std.filter(filter_func, arr)),\n\n assertEqual(a, b)::\n if a == b then\n true\n else\n error 'Assertion failed. ' + a + ' != ' + b,\n\n abs(n)::\n if !std.isNumber(n) then\n error 'std.abs expected number, got ' + std.type(n)\n else\n if n > 0 then n else -n,\n\n sign(n)::\n if !std.isNumber(n) then\n error 'std.sign expected number, got ' + std.type(n)\n else\n if n > 0 then\n 1\n else if n < 0 then\n -1\n else 0,\n\n max(a, b)::\n if !std.isNumber(a) then\n error 'std.max first param expected number, got ' + std.type(a)\n else if !std.isNumber(b) then\n error 'std.max second param expected number, got ' + std.type(b)\n else\n if a > b then a else b,\n\n min(a, b)::\n if !std.isNumber(a) then\n error 'std.min first param expected number, got ' + std.type(a)\n else if !std.isNumber(b) then\n error 'std.min second param expected number, got ' + std.type(b)\n else\n if a < b then a else b,\n\n clamp(x, minVal, maxVal)::\n if x < minVal then minVal\n else if x > maxVal then maxVal\n else x,\n\n flattenArrays(arrs)::\n std.foldl(function(a, b) a + b, arrs, []),\n\n manifestIni(ini)::\n local body_lines(body) =\n std.join([], [\n local value_or_values = body[k];\n if std.isArray(value_or_values) then\n ['%s = %s' % [k, value] for value in value_or_values]\n else\n ['%s = %s' % [k, value_or_values]]\n\n for k in std.objectFields(body)\n ]);\n\n local section_lines(sname, sbody) = ['[%s]' % [sname]] + body_lines(sbody),\n main_body = if std.objectHas(ini, 'main') then body_lines(ini.main) else [],\n all_sections = [\n section_lines(k, ini.sections[k])\n for k in std.objectFields(ini.sections)\n ];\n std.join('\\n', main_body + std.flattenArrays(all_sections) + ['']),\n\n manifestToml(value):: std.manifestTomlEx(value, ' '),\n\n manifestTomlEx(value, indent)::\n local\n escapeStringToml = std.escapeStringJson,\n escapeKeyToml(key) =\n local bare_allowed = std.set(std.stringChars('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-'));\n if std.setUnion(std.set(std.stringChars(key)), bare_allowed) == bare_allowed then key else escapeStringToml(key),\n isTableArray(v) = std.isArray(v) && std.length(v) > 0 && std.foldl(function(a, b) a && std.isObject(b), v, true),\n isSection(v) = std.isObject(v) || isTableArray(v),\n renderValue(v, indexedPath, inline, cindent) =\n if v == true then\n 'true'\n else if v == false then\n 'false'\n else if v == null then\n error 'Tried to manifest \"null\" at ' + indexedPath\n else if std.isNumber(v) then\n '' + v\n else if std.isString(v) then\n escapeStringToml(v)\n else if std.isFunction(v) then\n error 'Tried to manifest function at ' + indexedPath\n else if std.isArray(v) then\n if std.length(v) == 0 then\n '[]'\n else\n local range = std.range(0, std.length(v) - 1);\n local new_indent = if inline then '' else cindent + indent;\n local separator = if inline then ' ' else '\\n';\n local lines = ['[' + separator]\n + std.join([',' + separator],\n [\n [new_indent + renderValue(v[i], indexedPath + [i], true, '')]\n for i in range\n ])\n + [separator + (if inline then '' else cindent) + ']'];\n std.join('', lines)\n else if std.isObject(v) then\n local lines = ['{ ']\n + std.join([', '],\n [\n [escapeKeyToml(k) + ' = ' + renderValue(v[k], indexedPath + [k], true, '')]\n for k in std.objectFields(v)\n ])\n + [' }'];\n std.join('', lines),\n renderTableInternal(v, path, indexedPath, cindent) =\n local kvp = std.flattenArrays([\n [cindent + escapeKeyToml(k) + ' = ' + renderValue(v[k], indexedPath + [k], false, cindent)]\n for k in std.objectFields(v)\n if !isSection(v[k])\n ]);\n local sections = [std.join('\\n', kvp)] + [\n (\n if std.isObject(v[k]) then\n renderTable(v[k], path + [k], indexedPath + [k], cindent)\n else\n renderTableArray(v[k], path + [k], indexedPath + [k], cindent)\n )\n for k in std.objectFields(v)\n if isSection(v[k])\n ];\n std.join('\\n\\n', sections),\n renderTable(v, path, indexedPath, cindent) =\n cindent + '[' + std.join('.', std.map(escapeKeyToml, path)) + ']'\n + (if v == {} then '' else '\\n')\n + renderTableInternal(v, path, indexedPath, cindent + indent),\n renderTableArray(v, path, indexedPath, cindent) =\n local range = std.range(0, std.length(v) - 1);\n local sections = [\n (cindent + '[[' + std.join('.', std.map(escapeKeyToml, path)) + ']]'\n + (if v[i] == {} then '' else '\\n')\n + renderTableInternal(v[i], path, indexedPath + [i], cindent + indent))\n for i in range\n ];\n std.join('\\n\\n', sections);\n if std.isObject(value) then\n renderTableInternal(value, [], [], '')\n else\n error 'TOML body must be an object. Got ' + std.type(value),\n\n escapeStringJson:: $intrinsic(escapeStringJson),\n\n escapeStringPython(str)::\n std.escapeStringJson(str),\n\n escapeStringBash(str_)::\n local str = std.toString(str_);\n local trans(ch) =\n if ch == \"'\" then\n \"'\\\"'\\\"'\"\n else\n ch;\n \"'%s'\" % std.join('', [trans(ch) for ch in std.stringChars(str)]),\n\n escapeStringDollars(str_)::\n local str = std.toString(str_);\n local trans(ch) =\n if ch == '$' then\n '$$'\n else\n ch;\n std.foldl(function(a, b) a + trans(b), std.stringChars(str), ''),\n\n manifestJson(value):: std.manifestJsonEx(value, ' ') tailstrict,\n\n manifestJsonMinified(value):: std.manifestJsonEx(value, '', '', ':'),\n\n manifestJsonEx:: $intrinsic(manifestJsonEx),\n\n manifestYamlDoc:: $intrinsic(manifestYamlDoc),\n\n manifestYamlStream(value, indent_array_in_object=false, c_document_end=true)::\n if !std.isArray(value) then\n error 'manifestYamlStream only takes arrays, got ' + std.type(value)\n else\n '---\\n' + std.join(\n '\\n---\\n', [std.manifestYamlDoc(e, indent_array_in_object) for e in value]\n ) + if c_document_end then '\\n...\\n' else '\\n',\n\n\n manifestPython(v)::\n if std.isObject(v) then\n local fields = [\n '%s: %s' % [std.escapeStringPython(k), std.manifestPython(v[k])]\n for k in std.objectFields(v)\n ];\n '{%s}' % [std.join(', ', fields)]\n else if std.isArray(v) then\n '[%s]' % [std.join(', ', [std.manifestPython(v2) for v2 in v])]\n else if std.isString(v) then\n '%s' % [std.escapeStringPython(v)]\n else if std.isFunction(v) then\n error 'cannot manifest function'\n else if std.isNumber(v) then\n std.toString(v)\n else if v == true then\n 'True'\n else if v == false then\n 'False'\n else if v == null then\n 'None',\n\n manifestPythonVars(conf)::\n local vars = ['%s = %s' % [k, std.manifestPython(conf[k])] for k in std.objectFields(conf)];\n std.join('\\n', vars + ['']),\n\n manifestXmlJsonml(value)::\n if !std.isArray(value) then\n error 'Expected a JSONML value (an array), got %s' % std.type(value)\n else\n local aux(v) =\n if std.isString(v) then\n v\n else\n local tag = v[0];\n local has_attrs = std.length(v) > 1 && std.isObject(v[1]);\n local attrs = if has_attrs then v[1] else {};\n local children = if has_attrs then v[2:] else v[1:];\n local attrs_str =\n std.join('', [' %s=\"%s\"' % [k, attrs[k]] for k in std.objectFields(attrs)]);\n std.deepJoin(['<', tag, attrs_str, '>', [aux(x) for x in children], '']);\n\n aux(value),\n\n local base64_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',\n local base64_inv = { [base64_table[i]]: i for i in std.range(0, 63) },\n\n base64:: $intrinsic(base64),\n\n base64DecodeBytes:: $intrinsic(base64DecodeBytes),\n\n base64Decode:: $intrinsic(base64Decode),\n\n reverse:: $intrinsic(reverse),\n\n sort:: $intrinsic(sort),\n\n uniq(arr, keyF=id)::\n local f(a, b) =\n if std.length(a) == 0 then\n [b]\n else if keyF(a[std.length(a) - 1]) == keyF(b) then\n a\n else\n a + [b];\n std.foldl(f, arr, []),\n\n set(arr, keyF=id)::\n std.uniq(std.sort(arr, keyF), keyF),\n\n setMember(x, arr, keyF=id)::\n // TODO(dcunnin): Binary chop for O(log n) complexity\n std.length(std.setInter([x], arr, keyF)) > 0,\n\n setUnion(a, b, keyF=id)::\n // NOTE: order matters, values in `a` win\n local aux(a, b, i, j, acc) =\n if i >= std.length(a) then\n acc + b[j:]\n else if j >= std.length(b) then\n acc + a[i:]\n else\n local ak = keyF(a[i]);\n local bk = keyF(b[j]);\n if ak == bk then\n aux(a, b, i + 1, j + 1, acc + [a[i]]) tailstrict\n else if ak < bk then\n aux(a, b, i + 1, j, acc + [a[i]]) tailstrict\n else\n aux(a, b, i, j + 1, acc + [b[j]]) tailstrict;\n aux(a, b, 0, 0, []),\n\n setInter(a, b, keyF=id)::\n local aux(a, b, i, j, acc) =\n if i >= std.length(a) || j >= std.length(b) then\n acc\n else\n if keyF(a[i]) == keyF(b[j]) then\n aux(a, b, i + 1, j + 1, acc + [a[i]]) tailstrict\n else if keyF(a[i]) < keyF(b[j]) then\n aux(a, b, i + 1, j, acc) tailstrict\n else\n aux(a, b, i, j + 1, acc) tailstrict;\n aux(a, b, 0, 0, []) tailstrict,\n\n setDiff(a, b, keyF=id)::\n local aux(a, b, i, j, acc) =\n if i >= std.length(a) then\n acc\n else if j >= std.length(b) then\n acc + a[i:]\n else\n if keyF(a[i]) == keyF(b[j]) then\n aux(a, b, i + 1, j + 1, acc) tailstrict\n else if keyF(a[i]) < keyF(b[j]) then\n aux(a, b, i + 1, j, acc + [a[i]]) tailstrict\n else\n aux(a, b, i, j + 1, acc) tailstrict;\n aux(a, b, 0, 0, []) tailstrict,\n\n mergePatch(target, patch)::\n if std.isObject(patch) then\n local target_object =\n if std.isObject(target) then target else {};\n\n local target_fields =\n if std.isObject(target_object) then std.objectFields(target_object) else [];\n\n local null_fields = [k for k in std.objectFields(patch) if patch[k] == null];\n local both_fields = std.setUnion(target_fields, std.objectFields(patch));\n\n {\n [k]:\n if !std.objectHas(patch, k) then\n target_object[k]\n else if !std.objectHas(target_object, k) then\n std.mergePatch(null, patch[k]) tailstrict\n else\n std.mergePatch(target_object[k], patch[k]) tailstrict\n for k in std.setDiff(both_fields, null_fields)\n }\n else\n patch,\n\n get(o, f, default = null, inc_hidden = true)::\n if std.objectHasEx(o, f, inc_hidden) then o[f] else default,\n\n objectFields(o)::\n std.objectFieldsEx(o, false),\n\n objectFieldsAll(o)::\n std.objectFieldsEx(o, true),\n\n objectHas(o, f)::\n std.objectHasEx(o, f, false),\n\n objectHasAll(o, f)::\n std.objectHasEx(o, f, true),\n\n objectValues(o)::\n [o[k] for k in std.objectFields(o)],\n\n objectValuesAll(o)::\n [o[k] for k in std.objectFieldsAll(o)],\n\n equals:: $intrinsic(equals),\n\n resolvePath(f, r)::\n local arr = std.split(f, '/');\n std.join('/', std.makeArray(std.length(arr) - 1, function(i) arr[i]) + [r]),\n\n prune(a)::\n local isContent(b) =\n if b == null then\n false\n else if std.isArray(b) then\n std.length(b) > 0\n else if std.isObject(b) then\n std.length(b) > 0\n else\n true;\n if std.isArray(a) then\n [std.prune(x) for x in a if isContent($.prune(x))]\n else if std.isObject(a) then {\n [x]: $.prune(a[x])\n for x in std.objectFields(a)\n if isContent(std.prune(a[x]))\n } else\n a,\n\n findSubstr(pat, str)::\n if !std.isString(pat) then\n error 'findSubstr first parameter should be a string, got ' + std.type(pat)\n else if !std.isString(str) then\n error 'findSubstr second parameter should be a string, got ' + std.type(str)\n else\n local pat_len = std.length(pat);\n local str_len = std.length(str);\n if pat_len == 0 || str_len == 0 || pat_len > str_len then\n []\n else\n std.filter(function(i) str[i:i + pat_len] == pat, std.range(0, str_len - pat_len)),\n\n find(value, arr)::\n if !std.isArray(arr) then\n error 'find second parameter should be an array, got ' + std.type(arr)\n else\n std.filter(function(i) arr[i] == value, std.range(0, std.length(arr) - 1)),\n}\n" +--- +SOURCE_FILE@0..18978 + EXPR_OBJECT@0..18978 + OBJ_BODY_MEMBER_LIST@0..18978 + L_BRACE@0..1 "{" + WHITESPACE@1..4 "\n " + MEMBER_BIND_STMT@4..20 + OBJ_LOCAL@4..20 + LOCAL_KW@4..9 "local" + WHITESPACE@9..10 " " + BIND_DESTRUCT@10..20 + DESTRUCT_FULL@10..13 + NAME@10..13 + IDENT@10..13 "std" + WHITESPACE@13..14 " " + ASSIGN@14..15 "=" + WHITESPACE@15..16 " " + EXPR_LITERAL@16..20 + SELF_KW@16..20 "self" + COMMA@20..21 "," + WHITESPACE@21..24 "\n " + MEMBER_BIND_STMT@24..41 + OBJ_LOCAL@24..41 + LOCAL_KW@24..29 "local" + WHITESPACE@29..30 " " + BIND_DESTRUCT@30..41 + DESTRUCT_FULL@30..32 + NAME@30..32 + IDENT@30..32 "id" + WHITESPACE@32..33 " " + ASSIGN@33..34 "=" + WHITESPACE@34..35 " " + EXPR_INDEX@35..41 + EXPR_VAR@35..38 + NAME@35..38 + IDENT@35..38 "std" + DOT@38..39 "." + NAME@39..41 + IDENT@39..41 "id" + COMMA@41..42 "," + WHITESPACE@42..46 "\n\n " + SINGLE_LINE_HASH_COMMENT@46..67 "# Magic legacy field\n" + WHITESPACE@67..69 " " + MEMBER_FIELD@69..98 + FIELD_NORMAL@69..98 + FIELD_NAME_FIXED@69..77 + NAME@69..77 + IDENT@69..77 "thisFile" + COLONCOLON@77..79 "::" + WHITESPACE@79..80 " " + EXPR_INTRINSIC_THIS_FILE@80..98 + INTRINSIC_THIS_FILE@80..98 "$intrinsicThisFile" + COMMA@98..99 "," + WHITESPACE@99..102 "\n " + MEMBER_FIELD@102..119 + FIELD_NORMAL@102..119 + FIELD_NAME_FIXED@102..104 + NAME@102..104 + IDENT@102..104 "id" + COLONCOLON@104..106 "::" + WHITESPACE@106..107 " " + EXPR_INTRINSIC_ID@107..119 + INTRINSIC_ID@107..119 "$intrinsicId" + COMMA@119..120 "," + WHITESPACE@120..124 "\n\n " + SINGLE_LINE_HASH_COMMENT@124..176 "# Those functions are ..." + WHITESPACE@176..178 " " + MEMBER_FIELD@178..205 + FIELD_NORMAL@178..205 + FIELD_NAME_FIXED@178..184 + NAME@178..184 + IDENT@178..184 "length" + COLONCOLON@184..186 "::" + WHITESPACE@186..187 " " + EXPR_INTRINSIC@187..205 + INTRINSIC@187..197 "$intrinsic" + L_PAREN@197..198 "(" + NAME@198..204 + IDENT@198..204 "length" + R_PAREN@204..205 ")" + COMMA@205..206 "," + WHITESPACE@206..209 "\n " + MEMBER_FIELD@209..232 + FIELD_NORMAL@209..232 + FIELD_NAME_FIXED@209..213 + NAME@209..213 + IDENT@209..213 "type" + COLONCOLON@213..215 "::" + WHITESPACE@215..216 " " + EXPR_INTRINSIC@216..232 + INTRINSIC@216..226 "$intrinsic" + L_PAREN@226..227 "(" + NAME@227..231 + IDENT@227..231 "type" + R_PAREN@231..232 ")" + COMMA@232..233 "," + WHITESPACE@233..236 "\n " + MEMBER_FIELD@236..269 + FIELD_NORMAL@236..269 + FIELD_NAME_FIXED@236..245 + NAME@236..245 + IDENT@236..245 "makeArray" + COLONCOLON@245..247 "::" + WHITESPACE@247..248 " " + EXPR_INTRINSIC@248..269 + INTRINSIC@248..258 "$intrinsic" + L_PAREN@258..259 "(" + NAME@259..268 + IDENT@259..268 "makeArray" + R_PAREN@268..269 ")" + COMMA@269..270 "," + WHITESPACE@270..273 "\n " + MEMBER_FIELD@273..306 + FIELD_NORMAL@273..306 + FIELD_NAME_FIXED@273..282 + NAME@273..282 + IDENT@273..282 "codepoint" + COLONCOLON@282..284 "::" + WHITESPACE@284..285 " " + EXPR_INTRINSIC@285..306 + INTRINSIC@285..295 "$intrinsic" + L_PAREN@295..296 "(" + NAME@296..305 + IDENT@296..305 "codepoint" + R_PAREN@305..306 ")" + COMMA@306..307 "," + WHITESPACE@307..310 "\n " + MEMBER_FIELD@310..353 + FIELD_NORMAL@310..353 + FIELD_NAME_FIXED@310..324 + NAME@310..324 + IDENT@310..324 "objectFieldsEx" + COLONCOLON@324..326 "::" + WHITESPACE@326..327 " " + EXPR_INTRINSIC@327..353 + INTRINSIC@327..337 "$intrinsic" + L_PAREN@337..338 "(" + NAME@338..352 + IDENT@338..352 "objectFieldsEx" + R_PAREN@352..353 ")" + COMMA@353..354 "," + WHITESPACE@354..357 "\n " + MEMBER_FIELD@357..394 + FIELD_NORMAL@357..394 + FIELD_NAME_FIXED@357..368 + NAME@357..368 + IDENT@357..368 "objectHasEx" + COLONCOLON@368..370 "::" + WHITESPACE@370..371 " " + EXPR_INTRINSIC@371..394 + INTRINSIC@371..381 "$intrinsic" + L_PAREN@381..382 "(" + NAME@382..393 + IDENT@382..393 "objectHasEx" + R_PAREN@393..394 ")" + COMMA@394..395 "," + WHITESPACE@395..398 "\n " + MEMBER_FIELD@398..443 + FIELD_NORMAL@398..443 + FIELD_NAME_FIXED@398..413 + NAME@398..413 + IDENT@398..413 "primitiveEquals" + COLONCOLON@413..415 "::" + WHITESPACE@415..416 " " + EXPR_INTRINSIC@416..443 + INTRINSIC@416..426 "$intrinsic" + L_PAREN@426..427 "(" + NAME@427..442 + IDENT@427..442 "primitiveEquals" + R_PAREN@442..443 ")" + COMMA@443..444 "," + WHITESPACE@444..447 "\n " + MEMBER_FIELD@447..474 + FIELD_NORMAL@447..474 + FIELD_NAME_FIXED@447..453 + NAME@447..453 + IDENT@447..453 "modulo" + COLONCOLON@453..455 "::" + WHITESPACE@455..456 " " + EXPR_INTRINSIC@456..474 + INTRINSIC@456..466 "$intrinsic" + L_PAREN@466..467 "(" + NAME@467..473 + IDENT@467..473 "modulo" + R_PAREN@473..474 ")" + COMMA@474..475 "," + WHITESPACE@475..478 "\n " + MEMBER_FIELD@478..503 + FIELD_NORMAL@478..503 + FIELD_NAME_FIXED@478..483 + NAME@478..483 + IDENT@478..483 "floor" + COLONCOLON@483..485 "::" + WHITESPACE@485..486 " " + EXPR_INTRINSIC@486..503 + INTRINSIC@486..496 "$intrinsic" + L_PAREN@496..497 "(" + NAME@497..502 + IDENT@497..502 "floor" + R_PAREN@502..503 ")" + COMMA@503..504 "," + WHITESPACE@504..507 "\n " + MEMBER_FIELD@507..530 + FIELD_NORMAL@507..530 + FIELD_NAME_FIXED@507..511 + NAME@507..511 + IDENT@507..511 "ceil" + COLONCOLON@511..513 "::" + WHITESPACE@513..514 " " + EXPR_INTRINSIC@514..530 + INTRINSIC@514..524 "$intrinsic" + L_PAREN@524..525 "(" + NAME@525..529 + IDENT@525..529 "ceil" + R_PAREN@529..530 ")" + COMMA@530..531 "," + WHITESPACE@531..534 "\n " + MEMBER_FIELD@534..561 + FIELD_NORMAL@534..561 + FIELD_NAME_FIXED@534..540 + NAME@534..540 + IDENT@534..540 "extVar" + COLONCOLON@540..542 "::" + WHITESPACE@542..543 " " + EXPR_INTRINSIC@543..561 + INTRINSIC@543..553 "$intrinsic" + L_PAREN@553..554 "(" + NAME@554..560 + IDENT@554..560 "extVar" + R_PAREN@560..561 ")" + COMMA@561..562 "," + WHITESPACE@562..565 "\n " + MEMBER_FIELD@565..592 + FIELD_NORMAL@565..592 + FIELD_NAME_FIXED@565..571 + NAME@565..571 + IDENT@565..571 "native" + COLONCOLON@571..573 "::" + WHITESPACE@573..574 " " + EXPR_INTRINSIC@574..592 + INTRINSIC@574..584 "$intrinsic" + L_PAREN@584..585 "(" + NAME@585..591 + IDENT@585..591 "native" + R_PAREN@591..592 ")" + COMMA@592..593 "," + WHITESPACE@593..596 "\n " + MEMBER_FIELD@596..623 + FIELD_NORMAL@596..623 + FIELD_NAME_FIXED@596..602 + NAME@596..602 + IDENT@596..602 "filter" + COLONCOLON@602..604 "::" + WHITESPACE@604..605 " " + EXPR_INTRINSIC@605..623 + INTRINSIC@605..615 "$intrinsic" + L_PAREN@615..616 "(" + NAME@616..622 + IDENT@616..622 "filter" + R_PAREN@622..623 ")" + COMMA@623..624 "," + WHITESPACE@624..627 "\n " + MEMBER_FIELD@627..650 + FIELD_NORMAL@627..650 + FIELD_NAME_FIXED@627..631 + NAME@627..631 + IDENT@627..631 "char" + COLONCOLON@631..633 "::" + WHITESPACE@633..634 " " + EXPR_INTRINSIC@634..650 + INTRINSIC@634..644 "$intrinsic" + L_PAREN@644..645 "(" + NAME@645..649 + IDENT@645..649 "char" + R_PAREN@649..650 ")" + COMMA@650..651 "," + WHITESPACE@651..654 "\n " + MEMBER_FIELD@654..689 + FIELD_NORMAL@654..689 + FIELD_NAME_FIXED@654..664 + NAME@654..664 + IDENT@654..664 "encodeUTF8" + COLONCOLON@664..666 "::" + WHITESPACE@666..667 " " + EXPR_INTRINSIC@667..689 + INTRINSIC@667..677 "$intrinsic" + L_PAREN@677..678 "(" + NAME@678..688 + IDENT@678..688 "encodeUTF8" + R_PAREN@688..689 ")" + COMMA@689..690 "," + WHITESPACE@690..693 "\n " + MEMBER_FIELD@693..728 + FIELD_NORMAL@693..728 + FIELD_NAME_FIXED@693..703 + NAME@693..703 + IDENT@693..703 "decodeUTF8" + COLONCOLON@703..705 "::" + WHITESPACE@705..706 " " + EXPR_INTRINSIC@706..728 + INTRINSIC@706..716 "$intrinsic" + L_PAREN@716..717 "(" + NAME@717..727 + IDENT@717..727 "decodeUTF8" + R_PAREN@727..728 ")" + COMMA@728..729 "," + WHITESPACE@729..732 "\n " + MEMBER_FIELD@732..753 + FIELD_NORMAL@732..753 + FIELD_NAME_FIXED@732..735 + NAME@732..735 + IDENT@732..735 "md5" + COLONCOLON@735..737 "::" + WHITESPACE@737..738 " " + EXPR_INTRINSIC@738..753 + INTRINSIC@738..748 "$intrinsic" + L_PAREN@748..749 "(" + NAME@749..752 + IDENT@749..752 "md5" + R_PAREN@752..753 ")" + COMMA@753..754 "," + WHITESPACE@754..757 "\n " + MEMBER_FIELD@757..782 + FIELD_NORMAL@757..782 + FIELD_NAME_FIXED@757..762 + NAME@757..762 + IDENT@757..762 "trace" + COLONCOLON@762..764 "::" + WHITESPACE@764..765 " " + EXPR_INTRINSIC@765..782 + INTRINSIC@765..775 "$intrinsic" + L_PAREN@775..776 "(" + NAME@776..781 + IDENT@776..781 "trace" + R_PAREN@781..782 ")" + COMMA@782..783 "," + WHITESPACE@783..786 "\n " + MEMBER_FIELD@786..819 + FIELD_NORMAL@786..819 + FIELD_NAME_FIXED@786..795 + NAME@786..795 + IDENT@786..795 "parseJson" + COLONCOLON@795..797 "::" + WHITESPACE@797..798 " " + EXPR_INTRINSIC@798..819 + INTRINSIC@798..808 "$intrinsic" + L_PAREN@808..809 "(" + NAME@809..818 + IDENT@809..818 "parseJson" + R_PAREN@818..819 ")" + COMMA@819..820 "," + WHITESPACE@820..823 "\n " + MEMBER_FIELD@823..856 + FIELD_NORMAL@823..856 + FIELD_NAME_FIXED@823..832 + NAME@823..832 + IDENT@823..832 "parseYaml" + COLONCOLON@832..834 "::" + WHITESPACE@834..835 " " + EXPR_INTRINSIC@835..856 + INTRINSIC@835..845 "$intrinsic" + L_PAREN@845..846 "(" + NAME@846..855 + IDENT@846..855 "parseYaml" + R_PAREN@855..856 ")" + COMMA@856..857 "," + WHITESPACE@857..861 "\n\n " + MEMBER_FIELD@861..882 + FIELD_NORMAL@861..882 + FIELD_NAME_FIXED@861..864 + NAME@861..864 + IDENT@861..864 "log" + COLONCOLON@864..866 "::" + WHITESPACE@866..867 " " + EXPR_INTRINSIC@867..882 + INTRINSIC@867..877 "$intrinsic" + L_PAREN@877..878 "(" + NAME@878..881 + IDENT@878..881 "log" + R_PAREN@881..882 ")" + COMMA@882..883 "," + WHITESPACE@883..886 "\n " + MEMBER_FIELD@886..907 + FIELD_NORMAL@886..907 + FIELD_NAME_FIXED@886..889 + NAME@886..889 + IDENT@886..889 "pow" + COLONCOLON@889..891 "::" + WHITESPACE@891..892 " " + EXPR_INTRINSIC@892..907 + INTRINSIC@892..902 "$intrinsic" + L_PAREN@902..903 "(" + NAME@903..906 + IDENT@903..906 "pow" + R_PAREN@906..907 ")" + COMMA@907..908 "," + WHITESPACE@908..911 "\n " + MEMBER_FIELD@911..934 + FIELD_NORMAL@911..934 + FIELD_NAME_FIXED@911..915 + NAME@911..915 + IDENT@911..915 "sqrt" + COLONCOLON@915..917 "::" + WHITESPACE@917..918 " " + EXPR_INTRINSIC@918..934 + INTRINSIC@918..928 "$intrinsic" + L_PAREN@928..929 "(" + NAME@929..933 + IDENT@929..933 "sqrt" + R_PAREN@933..934 ")" + COMMA@934..935 "," + WHITESPACE@935..939 "\n\n " + MEMBER_FIELD@939..960 + FIELD_NORMAL@939..960 + FIELD_NAME_FIXED@939..942 + NAME@939..942 + IDENT@939..942 "sin" + COLONCOLON@942..944 "::" + WHITESPACE@944..945 " " + EXPR_INTRINSIC@945..960 + INTRINSIC@945..955 "$intrinsic" + L_PAREN@955..956 "(" + NAME@956..959 + IDENT@956..959 "sin" + R_PAREN@959..960 ")" + COMMA@960..961 "," + WHITESPACE@961..964 "\n " + MEMBER_FIELD@964..985 + FIELD_NORMAL@964..985 + FIELD_NAME_FIXED@964..967 + NAME@964..967 + IDENT@964..967 "cos" + COLONCOLON@967..969 "::" + WHITESPACE@969..970 " " + EXPR_INTRINSIC@970..985 + INTRINSIC@970..980 "$intrinsic" + L_PAREN@980..981 "(" + NAME@981..984 + IDENT@981..984 "cos" + R_PAREN@984..985 ")" + COMMA@985..986 "," + WHITESPACE@986..989 "\n " + MEMBER_FIELD@989..1010 + FIELD_NORMAL@989..1010 + FIELD_NAME_FIXED@989..992 + NAME@989..992 + IDENT@989..992 "tan" + COLONCOLON@992..994 "::" + WHITESPACE@994..995 " " + EXPR_INTRINSIC@995..1010 + INTRINSIC@995..1005 "$intrinsic" + L_PAREN@1005..1006 "(" + NAME@1006..1009 + IDENT@1006..1009 "tan" + R_PAREN@1009..1010 ")" + COMMA@1010..1011 "," + WHITESPACE@1011..1014 "\n " + MEMBER_FIELD@1014..1037 + FIELD_NORMAL@1014..1037 + FIELD_NAME_FIXED@1014..1018 + NAME@1014..1018 + IDENT@1014..1018 "asin" + COLONCOLON@1018..1020 "::" + WHITESPACE@1020..1021 " " + EXPR_INTRINSIC@1021..1037 + INTRINSIC@1021..1031 "$intrinsic" + L_PAREN@1031..1032 "(" + NAME@1032..1036 + IDENT@1032..1036 "asin" + R_PAREN@1036..1037 ")" + COMMA@1037..1038 "," + WHITESPACE@1038..1041 "\n " + MEMBER_FIELD@1041..1064 + FIELD_NORMAL@1041..1064 + FIELD_NAME_FIXED@1041..1045 + NAME@1041..1045 + IDENT@1041..1045 "acos" + COLONCOLON@1045..1047 "::" + WHITESPACE@1047..1048 " " + EXPR_INTRINSIC@1048..1064 + INTRINSIC@1048..1058 "$intrinsic" + L_PAREN@1058..1059 "(" + NAME@1059..1063 + IDENT@1059..1063 "acos" + R_PAREN@1063..1064 ")" + COMMA@1064..1065 "," + WHITESPACE@1065..1068 "\n " + MEMBER_FIELD@1068..1091 + FIELD_NORMAL@1068..1091 + FIELD_NAME_FIXED@1068..1072 + NAME@1068..1072 + IDENT@1068..1072 "atan" + COLONCOLON@1072..1074 "::" + WHITESPACE@1074..1075 " " + EXPR_INTRINSIC@1075..1091 + INTRINSIC@1075..1085 "$intrinsic" + L_PAREN@1085..1086 "(" + NAME@1086..1090 + IDENT@1086..1090 "atan" + R_PAREN@1090..1091 ")" + COMMA@1091..1092 "," + WHITESPACE@1092..1096 "\n\n " + MEMBER_FIELD@1096..1117 + FIELD_NORMAL@1096..1117 + FIELD_NAME_FIXED@1096..1099 + NAME@1096..1099 + IDENT@1096..1099 "exp" + COLONCOLON@1099..1101 "::" + WHITESPACE@1101..1102 " " + EXPR_INTRINSIC@1102..1117 + INTRINSIC@1102..1112 "$intrinsic" + L_PAREN@1112..1113 "(" + NAME@1113..1116 + IDENT@1113..1116 "exp" + R_PAREN@1116..1117 ")" + COMMA@1117..1118 "," + WHITESPACE@1118..1121 "\n " + MEMBER_FIELD@1121..1152 + FIELD_NORMAL@1121..1152 + FIELD_NAME_FIXED@1121..1129 + NAME@1121..1129 + IDENT@1121..1129 "mantissa" + COLONCOLON@1129..1131 "::" + WHITESPACE@1131..1132 " " + EXPR_INTRINSIC@1132..1152 + INTRINSIC@1132..1142 "$intrinsic" + L_PAREN@1142..1143 "(" + NAME@1143..1151 + IDENT@1143..1151 "mantissa" + R_PAREN@1151..1152 ")" + COMMA@1152..1153 "," + WHITESPACE@1153..1156 "\n " + MEMBER_FIELD@1156..1187 + FIELD_NORMAL@1156..1187 + FIELD_NAME_FIXED@1156..1164 + NAME@1156..1164 + IDENT@1156..1164 "exponent" + COLONCOLON@1164..1166 "::" + WHITESPACE@1166..1167 " " + EXPR_INTRINSIC@1167..1187 + INTRINSIC@1167..1177 "$intrinsic" + L_PAREN@1177..1178 "(" + NAME@1178..1186 + IDENT@1178..1186 "exponent" + R_PAREN@1186..1187 ")" + COMMA@1187..1188 "," + WHITESPACE@1188..1192 "\n\n " + MEMBER_FIELD@1192..1213 + FIELD_NORMAL@1192..1213 + FIELD_NAME_FIXED@1192..1195 + NAME@1192..1195 + IDENT@1192..1195 "any" + COLONCOLON@1195..1197 "::" + WHITESPACE@1197..1198 " " + EXPR_INTRINSIC@1198..1213 + INTRINSIC@1198..1208 "$intrinsic" + L_PAREN@1208..1209 "(" + NAME@1209..1212 + IDENT@1209..1212 "any" + R_PAREN@1212..1213 ")" + COMMA@1213..1214 "," + WHITESPACE@1214..1217 "\n " + MEMBER_FIELD@1217..1238 + FIELD_NORMAL@1217..1238 + FIELD_NAME_FIXED@1217..1220 + NAME@1217..1220 + IDENT@1217..1220 "all" + COLONCOLON@1220..1222 "::" + WHITESPACE@1222..1223 " " + EXPR_INTRINSIC@1223..1238 + INTRINSIC@1223..1233 "$intrinsic" + L_PAREN@1233..1234 "(" + NAME@1234..1237 + IDENT@1234..1237 "all" + R_PAREN@1237..1238 ")" + COMMA@1238..1239 "," + WHITESPACE@1239..1243 "\n\n " + MEMBER_FIELD@1243..1280 + FIELD_METHOD@1243..1280 + FIELD_NAME_FIXED@1243..1251 + NAME@1243..1251 + IDENT@1243..1251 "isString" + PARAMS_DESC@1251..1254 + L_PAREN@1251..1252 "(" + PARAM@1252..1253 + DESTRUCT_FULL@1252..1253 + NAME@1252..1253 + IDENT@1252..1253 "v" + R_PAREN@1253..1254 ")" + COLONCOLON@1254..1256 "::" + WHITESPACE@1256..1257 " " + EXPR_BINARY@1257..1280 + LHS_EXPR@1257..1268 + EXPR_APPLY@1257..1268 + EXPR_INDEX@1257..1265 + EXPR_VAR@1257..1260 + NAME@1257..1260 + IDENT@1257..1260 "std" + DOT@1260..1261 "." + NAME@1261..1265 + IDENT@1261..1265 "type" + ARGS_DESC@1265..1268 + L_PAREN@1265..1266 "(" + ARG@1266..1267 + EXPR_VAR@1266..1267 + NAME@1266..1267 + IDENT@1266..1267 "v" + R_PAREN@1267..1268 ")" + WHITESPACE@1268..1269 " " + EQ@1269..1271 "==" + WHITESPACE@1271..1272 " " + EXPR_STRING@1272..1280 + STRING_SINGLE@1272..1280 "'string'" + COMMA@1280..1281 "," + WHITESPACE@1281..1284 "\n " + MEMBER_FIELD@1284..1321 + FIELD_METHOD@1284..1321 + FIELD_NAME_FIXED@1284..1292 + NAME@1284..1292 + IDENT@1284..1292 "isNumber" + PARAMS_DESC@1292..1295 + L_PAREN@1292..1293 "(" + PARAM@1293..1294 + DESTRUCT_FULL@1293..1294 + NAME@1293..1294 + IDENT@1293..1294 "v" + R_PAREN@1294..1295 ")" + COLONCOLON@1295..1297 "::" + WHITESPACE@1297..1298 " " + EXPR_BINARY@1298..1321 + LHS_EXPR@1298..1309 + EXPR_APPLY@1298..1309 + EXPR_INDEX@1298..1306 + EXPR_VAR@1298..1301 + NAME@1298..1301 + IDENT@1298..1301 "std" + DOT@1301..1302 "." + NAME@1302..1306 + IDENT@1302..1306 "type" + ARGS_DESC@1306..1309 + L_PAREN@1306..1307 "(" + ARG@1307..1308 + EXPR_VAR@1307..1308 + NAME@1307..1308 + IDENT@1307..1308 "v" + R_PAREN@1308..1309 ")" + WHITESPACE@1309..1310 " " + EQ@1310..1312 "==" + WHITESPACE@1312..1313 " " + EXPR_STRING@1313..1321 + STRING_SINGLE@1313..1321 "'number'" + COMMA@1321..1322 "," + WHITESPACE@1322..1325 "\n " + MEMBER_FIELD@1325..1364 + FIELD_METHOD@1325..1364 + FIELD_NAME_FIXED@1325..1334 + NAME@1325..1334 + IDENT@1325..1334 "isBoolean" + PARAMS_DESC@1334..1337 + L_PAREN@1334..1335 "(" + PARAM@1335..1336 + DESTRUCT_FULL@1335..1336 + NAME@1335..1336 + IDENT@1335..1336 "v" + R_PAREN@1336..1337 ")" + COLONCOLON@1337..1339 "::" + WHITESPACE@1339..1340 " " + EXPR_BINARY@1340..1364 + LHS_EXPR@1340..1351 + EXPR_APPLY@1340..1351 + EXPR_INDEX@1340..1348 + EXPR_VAR@1340..1343 + NAME@1340..1343 + IDENT@1340..1343 "std" + DOT@1343..1344 "." + NAME@1344..1348 + IDENT@1344..1348 "type" + ARGS_DESC@1348..1351 + L_PAREN@1348..1349 "(" + ARG@1349..1350 + EXPR_VAR@1349..1350 + NAME@1349..1350 + IDENT@1349..1350 "v" + R_PAREN@1350..1351 ")" + WHITESPACE@1351..1352 " " + EQ@1352..1354 "==" + WHITESPACE@1354..1355 " " + EXPR_STRING@1355..1364 + STRING_SINGLE@1355..1364 "'boolean'" + COMMA@1364..1365 "," + WHITESPACE@1365..1368 "\n " + MEMBER_FIELD@1368..1405 + FIELD_METHOD@1368..1405 + FIELD_NAME_FIXED@1368..1376 + NAME@1368..1376 + IDENT@1368..1376 "isObject" + PARAMS_DESC@1376..1379 + L_PAREN@1376..1377 "(" + PARAM@1377..1378 + DESTRUCT_FULL@1377..1378 + NAME@1377..1378 + IDENT@1377..1378 "v" + R_PAREN@1378..1379 ")" + COLONCOLON@1379..1381 "::" + WHITESPACE@1381..1382 " " + EXPR_BINARY@1382..1405 + LHS_EXPR@1382..1393 + EXPR_APPLY@1382..1393 + EXPR_INDEX@1382..1390 + EXPR_VAR@1382..1385 + NAME@1382..1385 + IDENT@1382..1385 "std" + DOT@1385..1386 "." + NAME@1386..1390 + IDENT@1386..1390 "type" + ARGS_DESC@1390..1393 + L_PAREN@1390..1391 "(" + ARG@1391..1392 + EXPR_VAR@1391..1392 + NAME@1391..1392 + IDENT@1391..1392 "v" + R_PAREN@1392..1393 ")" + WHITESPACE@1393..1394 " " + EQ@1394..1396 "==" + WHITESPACE@1396..1397 " " + EXPR_STRING@1397..1405 + STRING_SINGLE@1397..1405 "'object'" + COMMA@1405..1406 "," + WHITESPACE@1406..1409 "\n " + MEMBER_FIELD@1409..1444 + FIELD_METHOD@1409..1444 + FIELD_NAME_FIXED@1409..1416 + NAME@1409..1416 + IDENT@1409..1416 "isArray" + PARAMS_DESC@1416..1419 + L_PAREN@1416..1417 "(" + PARAM@1417..1418 + DESTRUCT_FULL@1417..1418 + NAME@1417..1418 + IDENT@1417..1418 "v" + R_PAREN@1418..1419 ")" + COLONCOLON@1419..1421 "::" + WHITESPACE@1421..1422 " " + EXPR_BINARY@1422..1444 + LHS_EXPR@1422..1433 + EXPR_APPLY@1422..1433 + EXPR_INDEX@1422..1430 + EXPR_VAR@1422..1425 + NAME@1422..1425 + IDENT@1422..1425 "std" + DOT@1425..1426 "." + NAME@1426..1430 + IDENT@1426..1430 "type" + ARGS_DESC@1430..1433 + L_PAREN@1430..1431 "(" + ARG@1431..1432 + EXPR_VAR@1431..1432 + NAME@1431..1432 + IDENT@1431..1432 "v" + R_PAREN@1432..1433 ")" + WHITESPACE@1433..1434 " " + EQ@1434..1436 "==" + WHITESPACE@1436..1437 " " + EXPR_STRING@1437..1444 + STRING_SINGLE@1437..1444 "'array'" + COMMA@1444..1445 "," + WHITESPACE@1445..1448 "\n " + MEMBER_FIELD@1448..1489 + FIELD_METHOD@1448..1489 + FIELD_NAME_FIXED@1448..1458 + NAME@1448..1458 + IDENT@1448..1458 "isFunction" + PARAMS_DESC@1458..1461 + L_PAREN@1458..1459 "(" + PARAM@1459..1460 + DESTRUCT_FULL@1459..1460 + NAME@1459..1460 + IDENT@1459..1460 "v" + R_PAREN@1460..1461 ")" + COLONCOLON@1461..1463 "::" + WHITESPACE@1463..1464 " " + EXPR_BINARY@1464..1489 + LHS_EXPR@1464..1475 + EXPR_APPLY@1464..1475 + EXPR_INDEX@1464..1472 + EXPR_VAR@1464..1467 + NAME@1464..1467 + IDENT@1464..1467 "std" + DOT@1467..1468 "." + NAME@1468..1472 + IDENT@1468..1472 "type" + ARGS_DESC@1472..1475 + L_PAREN@1472..1473 "(" + ARG@1473..1474 + EXPR_VAR@1473..1474 + NAME@1473..1474 + IDENT@1473..1474 "v" + R_PAREN@1474..1475 ")" + WHITESPACE@1475..1476 " " + EQ@1476..1478 "==" + WHITESPACE@1478..1479 " " + EXPR_STRING@1479..1489 + STRING_SINGLE@1479..1489 "'function'" + COMMA@1489..1490 "," + WHITESPACE@1490..1494 "\n\n " + MEMBER_FIELD@1494..1557 + FIELD_METHOD@1494..1557 + FIELD_NAME_FIXED@1494..1502 + NAME@1494..1502 + IDENT@1494..1502 "toString" + PARAMS_DESC@1502..1505 + L_PAREN@1502..1503 "(" + PARAM@1503..1504 + DESTRUCT_FULL@1503..1504 + NAME@1503..1504 + IDENT@1503..1504 "a" + R_PAREN@1504..1505 ")" + COLONCOLON@1505..1507 "::" + WHITESPACE@1507..1512 "\n " + EXPR_IF_THEN_ELSE@1512..1557 + IF_KW@1512..1514 "if" + WHITESPACE@1514..1515 " " + EXPR_BINARY@1515..1538 + LHS_EXPR@1515..1526 + EXPR_APPLY@1515..1526 + EXPR_INDEX@1515..1523 + EXPR_VAR@1515..1518 + NAME@1515..1518 + IDENT@1515..1518 "std" + DOT@1518..1519 "." + NAME@1519..1523 + IDENT@1519..1523 "type" + ARGS_DESC@1523..1526 + L_PAREN@1523..1524 "(" + ARG@1524..1525 + EXPR_VAR@1524..1525 + NAME@1524..1525 + IDENT@1524..1525 "a" + R_PAREN@1525..1526 ")" + WHITESPACE@1526..1527 " " + EQ@1527..1529 "==" + WHITESPACE@1529..1530 " " + EXPR_STRING@1530..1538 + STRING_SINGLE@1530..1538 "'string'" + WHITESPACE@1538..1539 " " + THEN_KW@1539..1543 "then" + WHITESPACE@1543..1544 " " + TRUE_EXPR@1544..1545 + EXPR_VAR@1544..1545 + NAME@1544..1545 + IDENT@1544..1545 "a" + WHITESPACE@1545..1546 " " + ELSE_KW@1546..1550 "else" + WHITESPACE@1550..1551 " " + FALSE_EXPR@1551..1557 + EXPR_BINARY@1551..1557 + LHS_EXPR@1551..1553 + EXPR_STRING@1551..1553 + STRING_SINGLE@1551..1553 "''" + WHITESPACE@1553..1554 " " + PLUS@1554..1555 "+" + WHITESPACE@1555..1556 " " + EXPR_VAR@1556..1557 + NAME@1556..1557 + IDENT@1556..1557 "a" + COMMA@1557..1558 "," + WHITESPACE@1558..1562 "\n\n " + MEMBER_FIELD@1562..1589 + FIELD_NORMAL@1562..1589 + FIELD_NAME_FIXED@1562..1568 + NAME@1562..1568 + IDENT@1562..1568 "substr" + COLONCOLON@1568..1570 "::" + WHITESPACE@1570..1571 " " + EXPR_INTRINSIC@1571..1589 + INTRINSIC@1571..1581 "$intrinsic" + L_PAREN@1581..1582 "(" + NAME@1582..1588 + IDENT@1582..1588 "substr" + R_PAREN@1588..1589 ")" + COMMA@1589..1590 "," + WHITESPACE@1590..1594 "\n\n " + MEMBER_FIELD@1594..1718 + FIELD_METHOD@1594..1718 + FIELD_NAME_FIXED@1594..1604 + NAME@1594..1604 + IDENT@1594..1604 "startsWith" + PARAMS_DESC@1604..1610 + L_PAREN@1604..1605 "(" + PARAM@1605..1606 + DESTRUCT_FULL@1605..1606 + NAME@1605..1606 + IDENT@1605..1606 "a" + COMMA@1606..1607 "," + WHITESPACE@1607..1608 " " + PARAM@1608..1609 + DESTRUCT_FULL@1608..1609 + NAME@1608..1609 + IDENT@1608..1609 "b" + R_PAREN@1609..1610 ")" + COLONCOLON@1610..1612 "::" + WHITESPACE@1612..1617 "\n " + EXPR_IF_THEN_ELSE@1617..1718 + IF_KW@1617..1619 "if" + WHITESPACE@1619..1620 " " + EXPR_BINARY@1620..1649 + LHS_EXPR@1620..1633 + EXPR_APPLY@1620..1633 + EXPR_INDEX@1620..1630 + EXPR_VAR@1620..1623 + NAME@1620..1623 + IDENT@1620..1623 "std" + DOT@1623..1624 "." + NAME@1624..1630 + IDENT@1624..1630 "length" + ARGS_DESC@1630..1633 + L_PAREN@1630..1631 "(" + ARG@1631..1632 + EXPR_VAR@1631..1632 + NAME@1631..1632 + IDENT@1631..1632 "a" + R_PAREN@1632..1633 ")" + WHITESPACE@1633..1634 " " + LT@1634..1635 "<" + WHITESPACE@1635..1636 " " + EXPR_APPLY@1636..1649 + EXPR_INDEX@1636..1646 + EXPR_VAR@1636..1639 + NAME@1636..1639 + IDENT@1636..1639 "std" + DOT@1639..1640 "." + NAME@1640..1646 + IDENT@1640..1646 "length" + ARGS_DESC@1646..1649 + L_PAREN@1646..1647 "(" + ARG@1647..1648 + EXPR_VAR@1647..1648 + NAME@1647..1648 + IDENT@1647..1648 "b" + R_PAREN@1648..1649 ")" + WHITESPACE@1649..1650 " " + THEN_KW@1650..1654 "then" + WHITESPACE@1654..1661 "\n " + TRUE_EXPR@1661..1666 + EXPR_LITERAL@1661..1666 + FALSE_KW@1661..1666 "false" + WHITESPACE@1666..1671 "\n " + ELSE_KW@1671..1675 "else" + WHITESPACE@1675..1682 "\n " + FALSE_EXPR@1682..1718 + EXPR_BINARY@1682..1718 + LHS_EXPR@1682..1713 + EXPR_APPLY@1682..1713 + EXPR_INDEX@1682..1692 + EXPR_VAR@1682..1685 + NAME@1682..1685 + IDENT@1682..1685 "std" + DOT@1685..1686 "." + NAME@1686..1692 + IDENT@1686..1692 "substr" + ARGS_DESC@1692..1713 + L_PAREN@1692..1693 "(" + ARG@1693..1694 + EXPR_VAR@1693..1694 + NAME@1693..1694 + IDENT@1693..1694 "a" + COMMA@1694..1695 "," + WHITESPACE@1695..1696 " " + ARG@1696..1697 + EXPR_NUMBER@1696..1697 + FLOAT@1696..1697 "0" + COMMA@1697..1698 "," + WHITESPACE@1698..1699 " " + ARG@1699..1712 + EXPR_APPLY@1699..1712 + EXPR_INDEX@1699..1709 + EXPR_VAR@1699..1702 + NAME@1699..1702 + IDENT@1699..1702 "std" + DOT@1702..1703 "." + NAME@1703..1709 + IDENT@1703..1709 "length" + ARGS_DESC@1709..1712 + L_PAREN@1709..1710 "(" + ARG@1710..1711 + EXPR_VAR@1710..1711 + NAME@1710..1711 + IDENT@1710..1711 "b" + R_PAREN@1711..1712 ")" + R_PAREN@1712..1713 ")" + WHITESPACE@1713..1714 " " + EQ@1714..1716 "==" + WHITESPACE@1716..1717 " " + EXPR_VAR@1717..1718 + NAME@1717..1718 + IDENT@1717..1718 "b" + COMMA@1718..1719 "," + WHITESPACE@1719..1723 "\n\n " + MEMBER_FIELD@1723..1873 + FIELD_METHOD@1723..1873 + FIELD_NAME_FIXED@1723..1731 + NAME@1723..1731 + IDENT@1723..1731 "endsWith" + PARAMS_DESC@1731..1737 + L_PAREN@1731..1732 "(" + PARAM@1732..1733 + DESTRUCT_FULL@1732..1733 + NAME@1732..1733 + IDENT@1732..1733 "a" + COMMA@1733..1734 "," + WHITESPACE@1734..1735 " " + PARAM@1735..1736 + DESTRUCT_FULL@1735..1736 + NAME@1735..1736 + IDENT@1735..1736 "b" + R_PAREN@1736..1737 ")" + COLONCOLON@1737..1739 "::" + WHITESPACE@1739..1744 "\n " + EXPR_IF_THEN_ELSE@1744..1873 + IF_KW@1744..1746 "if" + WHITESPACE@1746..1747 " " + EXPR_BINARY@1747..1776 + LHS_EXPR@1747..1760 + EXPR_APPLY@1747..1760 + EXPR_INDEX@1747..1757 + EXPR_VAR@1747..1750 + NAME@1747..1750 + IDENT@1747..1750 "std" + DOT@1750..1751 "." + NAME@1751..1757 + IDENT@1751..1757 "length" + ARGS_DESC@1757..1760 + L_PAREN@1757..1758 "(" + ARG@1758..1759 + EXPR_VAR@1758..1759 + NAME@1758..1759 + IDENT@1758..1759 "a" + R_PAREN@1759..1760 ")" + WHITESPACE@1760..1761 " " + LT@1761..1762 "<" + WHITESPACE@1762..1763 " " + EXPR_APPLY@1763..1776 + EXPR_INDEX@1763..1773 + EXPR_VAR@1763..1766 + NAME@1763..1766 + IDENT@1763..1766 "std" + DOT@1766..1767 "." + NAME@1767..1773 + IDENT@1767..1773 "length" + ARGS_DESC@1773..1776 + L_PAREN@1773..1774 "(" + ARG@1774..1775 + EXPR_VAR@1774..1775 + NAME@1774..1775 + IDENT@1774..1775 "b" + R_PAREN@1775..1776 ")" + WHITESPACE@1776..1777 " " + THEN_KW@1777..1781 "then" + WHITESPACE@1781..1788 "\n " + TRUE_EXPR@1788..1793 + EXPR_LITERAL@1788..1793 + FALSE_KW@1788..1793 "false" + WHITESPACE@1793..1798 "\n " + ELSE_KW@1798..1802 "else" + WHITESPACE@1802..1809 "\n " + FALSE_EXPR@1809..1873 + EXPR_BINARY@1809..1873 + LHS_EXPR@1809..1868 + EXPR_APPLY@1809..1868 + EXPR_INDEX@1809..1819 + EXPR_VAR@1809..1812 + NAME@1809..1812 + IDENT@1809..1812 "std" + DOT@1812..1813 "." + NAME@1813..1819 + IDENT@1813..1819 "substr" + ARGS_DESC@1819..1868 + L_PAREN@1819..1820 "(" + ARG@1820..1821 + EXPR_VAR@1820..1821 + NAME@1820..1821 + IDENT@1820..1821 "a" + COMMA@1821..1822 "," + WHITESPACE@1822..1823 " " + ARG@1823..1852 + EXPR_BINARY@1823..1852 + LHS_EXPR@1823..1836 + EXPR_APPLY@1823..1836 + EXPR_INDEX@1823..1833 + EXPR_VAR@1823..1826 + NAME@1823..1826 + IDENT@1823..1826 "std" + DOT@1826..1827 "." + NAME@1827..1833 + IDENT@1827..1833 "length" + ARGS_DESC@1833..1836 + L_PAREN@1833..1834 "(" + ARG@1834..1835 + EXPR_VAR@1834..1835 + NAME@1834..1835 + IDENT@1834..1835 "a" + R_PAREN@1835..1836 ")" + WHITESPACE@1836..1837 " " + MINUS@1837..1838 "-" + WHITESPACE@1838..1839 " " + EXPR_APPLY@1839..1852 + EXPR_INDEX@1839..1849 + EXPR_VAR@1839..1842 + NAME@1839..1842 + IDENT@1839..1842 "std" + DOT@1842..1843 "." + NAME@1843..1849 + IDENT@1843..1849 "length" + ARGS_DESC@1849..1852 + L_PAREN@1849..1850 "(" + ARG@1850..1851 + EXPR_VAR@1850..1851 + NAME@1850..1851 + IDENT@1850..1851 "b" + R_PAREN@1851..1852 ")" + COMMA@1852..1853 "," + WHITESPACE@1853..1854 " " + ARG@1854..1867 + EXPR_APPLY@1854..1867 + EXPR_INDEX@1854..1864 + EXPR_VAR@1854..1857 + NAME@1854..1857 + IDENT@1854..1857 "std" + DOT@1857..1858 "." + NAME@1858..1864 + IDENT@1858..1864 "length" + ARGS_DESC@1864..1867 + L_PAREN@1864..1865 "(" + ARG@1865..1866 + EXPR_VAR@1865..1866 + NAME@1865..1866 + IDENT@1865..1866 "b" + R_PAREN@1866..1867 ")" + R_PAREN@1867..1868 ")" + WHITESPACE@1868..1869 " " + EQ@1869..1871 "==" + WHITESPACE@1871..1872 " " + EXPR_VAR@1872..1873 + NAME@1872..1873 + IDENT@1872..1873 "b" + COMMA@1873..1874 "," + WHITESPACE@1874..1878 "\n\n " + MEMBER_FIELD@1878..2021 + FIELD_METHOD@1878..2021 + FIELD_NAME_FIXED@1878..1889 + NAME@1878..1889 + IDENT@1878..1889 "lstripChars" + PARAMS_DESC@1889..1901 + L_PAREN@1889..1890 "(" + PARAM@1890..1893 + DESTRUCT_FULL@1890..1893 + NAME@1890..1893 + IDENT@1890..1893 "str" + COMMA@1893..1894 "," + WHITESPACE@1894..1895 " " + PARAM@1895..1900 + DESTRUCT_FULL@1895..1900 + NAME@1895..1900 + IDENT@1895..1900 "chars" + R_PAREN@1900..1901 ")" + COLONCOLON@1901..1903 "::" + WHITESPACE@1903..1908 "\n " + EXPR_IF_THEN_ELSE@1908..2021 + IF_KW@1908..1910 "if" + WHITESPACE@1910..1911 " " + EXPR_BINARY@1911..1959 + LHS_EXPR@1911..1930 + EXPR_BINARY@1911..1930 + LHS_EXPR@1911..1926 + EXPR_APPLY@1911..1926 + EXPR_INDEX@1911..1921 + EXPR_VAR@1911..1914 + NAME@1911..1914 + IDENT@1911..1914 "std" + DOT@1914..1915 "." + NAME@1915..1921 + IDENT@1915..1921 "length" + ARGS_DESC@1921..1926 + L_PAREN@1921..1922 "(" + ARG@1922..1925 + EXPR_VAR@1922..1925 + NAME@1922..1925 + IDENT@1922..1925 "str" + R_PAREN@1925..1926 ")" + WHITESPACE@1926..1927 " " + GT@1927..1928 ">" + WHITESPACE@1928..1929 " " + EXPR_NUMBER@1929..1930 + FLOAT@1929..1930 "0" + WHITESPACE@1930..1931 " " + AND@1931..1933 "&&" + WHITESPACE@1933..1934 " " + EXPR_APPLY@1934..1959 + EXPR_INDEX@1934..1944 + EXPR_VAR@1934..1937 + NAME@1934..1937 + IDENT@1934..1937 "std" + DOT@1937..1938 "." + NAME@1938..1944 + IDENT@1938..1944 "member" + ARGS_DESC@1944..1959 + L_PAREN@1944..1945 "(" + ARG@1945..1950 + EXPR_VAR@1945..1950 + NAME@1945..1950 + IDENT@1945..1950 "chars" + COMMA@1950..1951 "," + WHITESPACE@1951..1952 " " + ARG@1952..1958 + EXPR_INDEX_EXPR@1952..1958 + LHS_EXPR@1952..1955 + EXPR_VAR@1952..1955 + NAME@1952..1955 + IDENT@1952..1955 "str" + L_BRACK@1955..1956 "[" + EXPR_NUMBER@1956..1957 + FLOAT@1956..1957 "0" + R_BRACK@1957..1958 "]" + R_PAREN@1958..1959 ")" + WHITESPACE@1959..1960 " " + THEN_KW@1960..1964 "then" + WHITESPACE@1964..1971 "\n " + TRUE_EXPR@1971..2002 + EXPR_APPLY@1971..2002 + EXPR_INDEX@1971..1986 + EXPR_VAR@1971..1974 + NAME@1971..1974 + IDENT@1971..1974 "std" + DOT@1974..1975 "." + NAME@1975..1986 + IDENT@1975..1986 "lstripChars" + ARGS_DESC@1986..2002 + L_PAREN@1986..1987 "(" + ARG@1987..1994 + EXPR_SLICE@1987..1994 + EXPR_VAR@1987..1990 + NAME@1987..1990 + IDENT@1987..1990 "str" + SLICE_DESC@1990..1994 + L_BRACK@1990..1991 "[" + EXPR_NUMBER@1991..1992 + FLOAT@1991..1992 "1" + COLON@1992..1993 ":" + R_BRACK@1993..1994 "]" + COMMA@1994..1995 "," + WHITESPACE@1995..1996 " " + ARG@1996..2001 + EXPR_VAR@1996..2001 + NAME@1996..2001 + IDENT@1996..2001 "chars" + R_PAREN@2001..2002 ")" + WHITESPACE@2002..2007 "\n " + ELSE_KW@2007..2011 "else" + WHITESPACE@2011..2018 "\n " + FALSE_EXPR@2018..2021 + EXPR_VAR@2018..2021 + NAME@2018..2021 + IDENT@2018..2021 "str" + COMMA@2021..2022 "," + WHITESPACE@2022..2026 "\n\n " + MEMBER_FIELD@2026..2202 + FIELD_METHOD@2026..2202 + FIELD_NAME_FIXED@2026..2037 + NAME@2026..2037 + IDENT@2026..2037 "rstripChars" + PARAMS_DESC@2037..2049 + L_PAREN@2037..2038 "(" + PARAM@2038..2041 + DESTRUCT_FULL@2038..2041 + NAME@2038..2041 + IDENT@2038..2041 "str" + COMMA@2041..2042 "," + WHITESPACE@2042..2043 " " + PARAM@2043..2048 + DESTRUCT_FULL@2043..2048 + NAME@2043..2048 + IDENT@2043..2048 "chars" + R_PAREN@2048..2049 ")" + COLONCOLON@2049..2051 "::" + WHITESPACE@2051..2056 "\n " + EXPR_LOCAL@2056..2202 + LOCAL_KW@2056..2061 "local" + WHITESPACE@2061..2062 " " + BIND_DESTRUCT@2062..2083 + DESTRUCT_FULL@2062..2065 + NAME@2062..2065 + IDENT@2062..2065 "len" + WHITESPACE@2065..2066 " " + ASSIGN@2066..2067 "=" + WHITESPACE@2067..2068 " " + EXPR_APPLY@2068..2083 + EXPR_INDEX@2068..2078 + EXPR_VAR@2068..2071 + NAME@2068..2071 + IDENT@2068..2071 "std" + DOT@2071..2072 "." + NAME@2072..2078 + IDENT@2072..2078 "length" + ARGS_DESC@2078..2083 + L_PAREN@2078..2079 "(" + ARG@2079..2082 + EXPR_VAR@2079..2082 + NAME@2079..2082 + IDENT@2079..2082 "str" + R_PAREN@2082..2083 ")" + SEMI@2083..2084 ";" + WHITESPACE@2084..2089 "\n " + EXPR_IF_THEN_ELSE@2089..2202 + IF_KW@2089..2091 "if" + WHITESPACE@2091..2092 " " + EXPR_BINARY@2092..2134 + LHS_EXPR@2092..2099 + EXPR_BINARY@2092..2099 + LHS_EXPR@2092..2095 + EXPR_VAR@2092..2095 + NAME@2092..2095 + IDENT@2092..2095 "len" + WHITESPACE@2095..2096 " " + GT@2096..2097 ">" + WHITESPACE@2097..2098 " " + EXPR_NUMBER@2098..2099 + FLOAT@2098..2099 "0" + WHITESPACE@2099..2100 " " + AND@2100..2102 "&&" + WHITESPACE@2102..2103 " " + EXPR_APPLY@2103..2134 + EXPR_INDEX@2103..2113 + EXPR_VAR@2103..2106 + NAME@2103..2106 + IDENT@2103..2106 "std" + DOT@2106..2107 "." + NAME@2107..2113 + IDENT@2107..2113 "member" + ARGS_DESC@2113..2134 + L_PAREN@2113..2114 "(" + ARG@2114..2119 + EXPR_VAR@2114..2119 + NAME@2114..2119 + IDENT@2114..2119 "chars" + COMMA@2119..2120 "," + WHITESPACE@2120..2121 " " + ARG@2121..2133 + EXPR_INDEX_EXPR@2121..2133 + LHS_EXPR@2121..2124 + EXPR_VAR@2121..2124 + NAME@2121..2124 + IDENT@2121..2124 "str" + L_BRACK@2124..2125 "[" + EXPR_BINARY@2125..2132 + LHS_EXPR@2125..2128 + EXPR_VAR@2125..2128 + NAME@2125..2128 + IDENT@2125..2128 "len" + WHITESPACE@2128..2129 " " + MINUS@2129..2130 "-" + WHITESPACE@2130..2131 " " + EXPR_NUMBER@2131..2132 + FLOAT@2131..2132 "1" + R_BRACK@2132..2133 "]" + R_PAREN@2133..2134 ")" + WHITESPACE@2134..2135 " " + THEN_KW@2135..2139 "then" + WHITESPACE@2139..2146 "\n " + TRUE_EXPR@2146..2183 + EXPR_APPLY@2146..2183 + EXPR_INDEX@2146..2161 + EXPR_VAR@2146..2149 + NAME@2146..2149 + IDENT@2146..2149 "std" + DOT@2149..2150 "." + NAME@2150..2161 + IDENT@2150..2161 "rstripChars" + ARGS_DESC@2161..2183 + L_PAREN@2161..2162 "(" + ARG@2162..2175 + EXPR_SLICE@2162..2175 + EXPR_VAR@2162..2165 + NAME@2162..2165 + IDENT@2162..2165 "str" + SLICE_DESC@2165..2175 + L_BRACK@2165..2166 "[" + COLON@2166..2167 ":" + SLICE_DESC_END@2167..2174 + EXPR_BINARY@2167..2174 + LHS_EXPR@2167..2170 + EXPR_VAR@2167..2170 + NAME@2167..2170 + IDENT@2167..2170 "len" + WHITESPACE@2170..2171 " " + MINUS@2171..2172 "-" + WHITESPACE@2172..2173 " " + EXPR_NUMBER@2173..2174 + FLOAT@2173..2174 "1" + R_BRACK@2174..2175 "]" + COMMA@2175..2176 "," + WHITESPACE@2176..2177 " " + ARG@2177..2182 + EXPR_VAR@2177..2182 + NAME@2177..2182 + IDENT@2177..2182 "chars" + R_PAREN@2182..2183 ")" + WHITESPACE@2183..2188 "\n " + ELSE_KW@2188..2192 "else" + WHITESPACE@2192..2199 "\n " + FALSE_EXPR@2199..2202 + EXPR_VAR@2199..2202 + NAME@2199..2202 + IDENT@2199..2202 "str" + COMMA@2202..2203 "," + WHITESPACE@2203..2207 "\n\n " + MEMBER_FIELD@2207..2287 + FIELD_METHOD@2207..2287 + FIELD_NAME_FIXED@2207..2217 + NAME@2207..2217 + IDENT@2207..2217 "stripChars" + PARAMS_DESC@2217..2229 + L_PAREN@2217..2218 "(" + PARAM@2218..2221 + DESTRUCT_FULL@2218..2221 + NAME@2218..2221 + IDENT@2218..2221 "str" + COMMA@2221..2222 "," + WHITESPACE@2222..2223 " " + PARAM@2223..2228 + DESTRUCT_FULL@2223..2228 + NAME@2223..2228 + IDENT@2223..2228 "chars" + R_PAREN@2228..2229 ")" + COLONCOLON@2229..2231 "::" + WHITESPACE@2231..2236 "\n " + EXPR_APPLY@2236..2287 + EXPR_INDEX@2236..2251 + EXPR_VAR@2236..2239 + NAME@2236..2239 + IDENT@2236..2239 "std" + DOT@2239..2240 "." + NAME@2240..2251 + IDENT@2240..2251 "lstripChars" + ARGS_DESC@2251..2287 + L_PAREN@2251..2252 "(" + ARG@2252..2279 + EXPR_APPLY@2252..2279 + EXPR_INDEX@2252..2267 + EXPR_VAR@2252..2255 + NAME@2252..2255 + IDENT@2252..2255 "std" + DOT@2255..2256 "." + NAME@2256..2267 + IDENT@2256..2267 "rstripChars" + ARGS_DESC@2267..2279 + L_PAREN@2267..2268 "(" + ARG@2268..2271 + EXPR_VAR@2268..2271 + NAME@2268..2271 + IDENT@2268..2271 "str" + COMMA@2271..2272 "," + WHITESPACE@2272..2273 " " + ARG@2273..2278 + EXPR_VAR@2273..2278 + NAME@2273..2278 + IDENT@2273..2278 "chars" + R_PAREN@2278..2279 ")" + COMMA@2279..2280 "," + WHITESPACE@2280..2281 " " + ARG@2281..2286 + EXPR_VAR@2281..2286 + NAME@2281..2286 + IDENT@2281..2286 "chars" + R_PAREN@2286..2287 ")" + COMMA@2287..2288 "," + WHITESPACE@2288..2292 "\n\n " + MEMBER_FIELD@2292..2365 + FIELD_METHOD@2292..2365 + FIELD_NAME_FIXED@2292..2303 + NAME@2292..2303 + IDENT@2292..2303 "stringChars" + PARAMS_DESC@2303..2308 + L_PAREN@2303..2304 "(" + PARAM@2304..2307 + DESTRUCT_FULL@2304..2307 + NAME@2304..2307 + IDENT@2304..2307 "str" + R_PAREN@2307..2308 ")" + COLONCOLON@2308..2310 "::" + WHITESPACE@2310..2315 "\n " + EXPR_APPLY@2315..2365 + EXPR_INDEX@2315..2328 + EXPR_VAR@2315..2318 + NAME@2315..2318 + IDENT@2315..2318 "std" + DOT@2318..2319 "." + NAME@2319..2328 + IDENT@2319..2328 "makeArray" + ARGS_DESC@2328..2365 + L_PAREN@2328..2329 "(" + ARG@2329..2344 + EXPR_APPLY@2329..2344 + EXPR_INDEX@2329..2339 + EXPR_VAR@2329..2332 + NAME@2329..2332 + IDENT@2329..2332 "std" + DOT@2332..2333 "." + NAME@2333..2339 + IDENT@2333..2339 "length" + ARGS_DESC@2339..2344 + L_PAREN@2339..2340 "(" + ARG@2340..2343 + EXPR_VAR@2340..2343 + NAME@2340..2343 + IDENT@2340..2343 "str" + R_PAREN@2343..2344 ")" + COMMA@2344..2345 "," + WHITESPACE@2345..2346 " " + ARG@2346..2364 + EXPR_FUNCTION@2346..2364 + FUNCTION_KW@2346..2354 "function" + PARAMS_DESC@2354..2357 + L_PAREN@2354..2355 "(" + PARAM@2355..2356 + DESTRUCT_FULL@2355..2356 + NAME@2355..2356 + IDENT@2355..2356 "i" + R_PAREN@2356..2357 ")" + WHITESPACE@2357..2358 " " + EXPR_INDEX_EXPR@2358..2364 + LHS_EXPR@2358..2361 + EXPR_VAR@2358..2361 + NAME@2358..2361 + IDENT@2358..2361 "str" + L_BRACK@2361..2362 "[" + EXPR_VAR@2362..2363 + NAME@2362..2363 + IDENT@2362..2363 "i" + R_BRACK@2363..2364 "]" + R_PAREN@2364..2365 ")" + COMMA@2365..2366 "," + WHITESPACE@2366..2370 "\n\n " + MEMBER_BIND_STMT@2370..3086 + OBJ_LOCAL@2370..3086 + LOCAL_KW@2370..2375 "local" + WHITESPACE@2375..2376 " " + BIND_FUNCTION@2376..3086 + NAME@2376..2385 + IDENT@2376..2385 "parse_nat" + PARAMS_DESC@2385..2396 + L_PAREN@2385..2386 "(" + PARAM@2386..2389 + DESTRUCT_FULL@2386..2389 + NAME@2386..2389 + IDENT@2386..2389 "str" + COMMA@2389..2390 "," + WHITESPACE@2390..2391 " " + PARAM@2391..2395 + DESTRUCT_FULL@2391..2395 + NAME@2391..2395 + IDENT@2391..2395 "base" + R_PAREN@2395..2396 ")" + WHITESPACE@2396..2397 " " + ASSIGN@2397..2398 "=" + WHITESPACE@2398..2403 "\n " + EXPR_ASSERT@2403..3086 + ASSERTION@2403..2467 + ASSERT_KW@2403..2409 "assert" + WHITESPACE@2409..2410 " " + LHS_EXPR@2410..2432 + EXPR_BINARY@2410..2432 + LHS_EXPR@2410..2418 + EXPR_BINARY@2410..2418 + LHS_EXPR@2410..2414 + EXPR_VAR@2410..2414 + NAME@2410..2414 + IDENT@2410..2414 "base" + WHITESPACE@2414..2415 " " + GT@2415..2416 ">" + WHITESPACE@2416..2417 " " + EXPR_NUMBER@2417..2418 + FLOAT@2417..2418 "0" + WHITESPACE@2418..2419 " " + AND@2419..2421 "&&" + WHITESPACE@2421..2422 " " + EXPR_BINARY@2422..2432 + LHS_EXPR@2422..2426 + EXPR_VAR@2422..2426 + NAME@2422..2426 + IDENT@2422..2426 "base" + WHITESPACE@2426..2427 " " + LE@2427..2429 "<=" + WHITESPACE@2429..2430 " " + EXPR_NUMBER@2430..2432 + FLOAT@2430..2432 "16" + WHITESPACE@2432..2433 " " + COLON@2433..2434 ":" + WHITESPACE@2434..2435 " " + EXPR_BINARY@2435..2467 + LHS_EXPR@2435..2460 + EXPR_STRING@2435..2460 + STRING_SINGLE@2435..2460 "'integer base %d inva ..." + WHITESPACE@2460..2461 " " + MODULO@2461..2462 "%" + WHITESPACE@2462..2463 " " + EXPR_VAR@2463..2467 + NAME@2463..2467 + IDENT@2463..2467 "base" + SEMI@2467..2468 ";" + WHITESPACE@2468..2473 "\n " + SINGLE_LINE_SLASH_COMMENT@2473..2517 "// These codepoints a ..." + WHITESPACE@2517..2521 " " + EXPR_LOCAL@2521..3086 + LOCAL_KW@2521..2526 "local" + WHITESPACE@2526..2527 " " + BIND_DESTRUCT@2527..2557 + DESTRUCT_FULL@2527..2536 + NAME@2527..2536 + IDENT@2527..2536 "zero_code" + WHITESPACE@2536..2537 " " + ASSIGN@2537..2538 "=" + WHITESPACE@2538..2539 " " + EXPR_APPLY@2539..2557 + EXPR_INDEX@2539..2552 + EXPR_VAR@2539..2542 + NAME@2539..2542 + IDENT@2539..2542 "std" + DOT@2542..2543 "." + NAME@2543..2552 + IDENT@2543..2552 "codepoint" + ARGS_DESC@2552..2557 + L_PAREN@2552..2553 "(" + ARG@2553..2556 + EXPR_STRING@2553..2556 + STRING_SINGLE@2553..2556 "'0'" + R_PAREN@2556..2557 ")" + SEMI@2557..2558 ";" + WHITESPACE@2558..2563 "\n " + EXPR_LOCAL@2563..3086 + LOCAL_KW@2563..2568 "local" + WHITESPACE@2568..2569 " " + BIND_DESTRUCT@2569..2602 + DESTRUCT_FULL@2569..2581 + NAME@2569..2581 + IDENT@2569..2581 "upper_a_code" + WHITESPACE@2581..2582 " " + ASSIGN@2582..2583 "=" + WHITESPACE@2583..2584 " " + EXPR_APPLY@2584..2602 + EXPR_INDEX@2584..2597 + EXPR_VAR@2584..2587 + NAME@2584..2587 + IDENT@2584..2587 "std" + DOT@2587..2588 "." + NAME@2588..2597 + IDENT@2588..2597 "codepoint" + ARGS_DESC@2597..2602 + L_PAREN@2597..2598 "(" + ARG@2598..2601 + EXPR_STRING@2598..2601 + STRING_SINGLE@2598..2601 "'A'" + R_PAREN@2601..2602 ")" + SEMI@2602..2603 ";" + WHITESPACE@2603..2608 "\n " + EXPR_LOCAL@2608..3086 + LOCAL_KW@2608..2613 "local" + WHITESPACE@2613..2614 " " + BIND_DESTRUCT@2614..2647 + DESTRUCT_FULL@2614..2626 + NAME@2614..2626 + IDENT@2614..2626 "lower_a_code" + WHITESPACE@2626..2627 " " + ASSIGN@2627..2628 "=" + WHITESPACE@2628..2629 " " + EXPR_APPLY@2629..2647 + EXPR_INDEX@2629..2642 + EXPR_VAR@2629..2632 + NAME@2629..2632 + IDENT@2629..2632 "std" + DOT@2632..2633 "." + NAME@2633..2642 + IDENT@2633..2642 "codepoint" + ARGS_DESC@2642..2647 + L_PAREN@2642..2643 "(" + ARG@2643..2646 + EXPR_STRING@2643..2646 + STRING_SINGLE@2643..2646 "'a'" + R_PAREN@2646..2647 ")" + SEMI@2647..2648 ";" + WHITESPACE@2648..2653 "\n " + EXPR_LOCAL@2653..3086 + LOCAL_KW@2653..2658 "local" + WHITESPACE@2658..2659 " " + BIND_FUNCTION@2659..3036 + NAME@2659..2667 + IDENT@2659..2667 "addDigit" + PARAMS_DESC@2667..2684 + L_PAREN@2667..2668 "(" + PARAM@2668..2677 + DESTRUCT_FULL@2668..2677 + NAME@2668..2677 + IDENT@2668..2677 "aggregate" + COMMA@2677..2678 "," + WHITESPACE@2678..2679 " " + PARAM@2679..2683 + DESTRUCT_FULL@2679..2683 + NAME@2679..2683 + IDENT@2679..2683 "char" + R_PAREN@2683..2684 ")" + WHITESPACE@2684..2685 " " + ASSIGN@2685..2686 "=" + WHITESPACE@2686..2693 "\n " + EXPR_LOCAL@2693..3036 + LOCAL_KW@2693..2698 "local" + WHITESPACE@2698..2699 " " + BIND_DESTRUCT@2699..2725 + DESTRUCT_FULL@2699..2703 + NAME@2699..2703 + IDENT@2699..2703 "code" + WHITESPACE@2703..2704 " " + ASSIGN@2704..2705 "=" + WHITESPACE@2705..2706 " " + EXPR_APPLY@2706..2725 + EXPR_INDEX@2706..2719 + EXPR_VAR@2706..2709 + NAME@2706..2709 + IDENT@2706..2709 "std" + DOT@2709..2710 "." + NAME@2710..2719 + IDENT@2710..2719 "codepoint" + ARGS_DESC@2719..2725 + L_PAREN@2719..2720 "(" + ARG@2720..2724 + EXPR_VAR@2720..2724 + NAME@2720..2724 + IDENT@2720..2724 "char" + R_PAREN@2724..2725 ")" + SEMI@2725..2726 ";" + WHITESPACE@2726..2733 "\n " + EXPR_LOCAL@2733..3036 + LOCAL_KW@2733..2738 "local" + WHITESPACE@2738..2739 " " + BIND_DESTRUCT@2739..2917 + DESTRUCT_FULL@2739..2744 + NAME@2739..2744 + IDENT@2739..2744 "digit" + WHITESPACE@2744..2745 " " + ASSIGN@2745..2746 "=" + WHITESPACE@2746..2747 " " + EXPR_IF_THEN_ELSE@2747..2917 + IF_KW@2747..2749 "if" + WHITESPACE@2749..2750 " " + EXPR_BINARY@2750..2770 + LHS_EXPR@2750..2754 + EXPR_VAR@2750..2754 + NAME@2750..2754 + IDENT@2750..2754 "code" + WHITESPACE@2754..2755 " " + GE@2755..2757 ">=" + WHITESPACE@2757..2758 " " + EXPR_VAR@2758..2770 + NAME@2758..2770 + IDENT@2758..2770 "lower_a_code" + WHITESPACE@2770..2771 " " + THEN_KW@2771..2775 "then" + WHITESPACE@2775..2784 "\n " + TRUE_EXPR@2784..2808 + EXPR_BINARY@2784..2808 + LHS_EXPR@2784..2803 + EXPR_BINARY@2784..2803 + LHS_EXPR@2784..2788 + EXPR_VAR@2784..2788 + NAME@2784..2788 + IDENT@2784..2788 "code" + WHITESPACE@2788..2789 " " + MINUS@2789..2790 "-" + WHITESPACE@2790..2791 " " + EXPR_VAR@2791..2803 + NAME@2791..2803 + IDENT@2791..2803 "lower_a_code" + WHITESPACE@2803..2804 " " + PLUS@2804..2805 "+" + WHITESPACE@2805..2806 " " + EXPR_NUMBER@2806..2808 + FLOAT@2806..2808 "10" + WHITESPACE@2808..2815 "\n " + ELSE_KW@2815..2819 "else" + WHITESPACE@2819..2820 " " + FALSE_EXPR@2820..2917 + EXPR_IF_THEN_ELSE@2820..2917 + IF_KW@2820..2822 "if" + WHITESPACE@2822..2823 " " + EXPR_BINARY@2823..2843 + LHS_EXPR@2823..2827 + EXPR_VAR@2823..2827 + NAME@2823..2827 + IDENT@2823..2827 "code" + WHITESPACE@2827..2828 " " + GE@2828..2830 ">=" + WHITESPACE@2830..2831 " " + EXPR_VAR@2831..2843 + NAME@2831..2843 + IDENT@2831..2843 "upper_a_code" + WHITESPACE@2843..2844 " " + THEN_KW@2844..2848 "then" + WHITESPACE@2848..2857 "\n " + TRUE_EXPR@2857..2881 + EXPR_BINARY@2857..2881 + LHS_EXPR@2857..2876 + EXPR_BINARY@2857..2876 + LHS_EXPR@2857..2861 + EXPR_VAR@2857..2861 + NAME@2857..2861 + IDENT@2857..2861 "code" + WHITESPACE@2861..2862 " " + MINUS@2862..2863 "-" + WHITESPACE@2863..2864 " " + EXPR_VAR@2864..2876 + NAME@2864..2876 + IDENT@2864..2876 "upper_a_code" + WHITESPACE@2876..2877 " " + PLUS@2877..2878 "+" + WHITESPACE@2878..2879 " " + EXPR_NUMBER@2879..2881 + FLOAT@2879..2881 "10" + WHITESPACE@2881..2888 "\n " + ELSE_KW@2888..2892 "else" + WHITESPACE@2892..2901 "\n " + FALSE_EXPR@2901..2917 + EXPR_BINARY@2901..2917 + LHS_EXPR@2901..2905 + EXPR_VAR@2901..2905 + NAME@2901..2905 + IDENT@2901..2905 "code" + WHITESPACE@2905..2906 " " + MINUS@2906..2907 "-" + WHITESPACE@2907..2908 " " + EXPR_VAR@2908..2917 + NAME@2908..2917 + IDENT@2908..2917 "zero_code" + SEMI@2917..2918 ";" + WHITESPACE@2918..2925 "\n " + EXPR_ASSERT@2925..3036 + ASSERTION@2925..3004 + ASSERT_KW@2925..2931 "assert" + WHITESPACE@2931..2932 " " + LHS_EXPR@2932..2958 + EXPR_BINARY@2932..2958 + LHS_EXPR@2932..2942 + EXPR_BINARY@2932..2942 + LHS_EXPR@2932..2937 + EXPR_VAR@2932..2937 + NAME@2932..2937 + IDENT@2932..2937 "digit" + WHITESPACE@2937..2938 " " + GE@2938..2940 ">=" + WHITESPACE@2940..2941 " " + EXPR_NUMBER@2941..2942 + FLOAT@2941..2942 "0" + WHITESPACE@2942..2943 " " + AND@2943..2945 "&&" + WHITESPACE@2945..2946 " " + EXPR_BINARY@2946..2958 + LHS_EXPR@2946..2951 + EXPR_VAR@2946..2951 + NAME@2946..2951 + IDENT@2946..2951 "digit" + WHITESPACE@2951..2952 " " + LT@2952..2953 "<" + WHITESPACE@2953..2954 " " + EXPR_VAR@2954..2958 + NAME@2954..2958 + IDENT@2954..2958 "base" + WHITESPACE@2958..2959 " " + COLON@2959..2960 ":" + WHITESPACE@2960..2961 " " + EXPR_BINARY@2961..3004 + LHS_EXPR@2961..2990 + EXPR_STRING@2961..2990 + STRING_SINGLE@2961..2990 "'%s is not a base %d ..." + WHITESPACE@2990..2991 " " + MODULO@2991..2992 "%" + WHITESPACE@2992..2993 " " + EXPR_ARRAY@2993..3004 + L_BRACK@2993..2994 "[" + EXPR_VAR@2994..2997 + NAME@2994..2997 + IDENT@2994..2997 "str" + COMMA@2997..2998 "," + WHITESPACE@2998..2999 " " + EXPR_VAR@2999..3003 + NAME@2999..3003 + IDENT@2999..3003 "base" + R_BRACK@3003..3004 "]" + SEMI@3004..3005 ";" + WHITESPACE@3005..3012 "\n " + EXPR_BINARY@3012..3036 + LHS_EXPR@3012..3028 + EXPR_BINARY@3012..3028 + LHS_EXPR@3012..3016 + EXPR_VAR@3012..3016 + NAME@3012..3016 + IDENT@3012..3016 "base" + WHITESPACE@3016..3017 " " + MUL@3017..3018 "*" + WHITESPACE@3018..3019 " " + EXPR_VAR@3019..3028 + NAME@3019..3028 + IDENT@3019..3028 "aggregate" + WHITESPACE@3028..3029 " " + PLUS@3029..3030 "+" + WHITESPACE@3030..3031 " " + EXPR_VAR@3031..3036 + NAME@3031..3036 + IDENT@3031..3036 "digit" + SEMI@3036..3037 ";" + WHITESPACE@3037..3042 "\n " + EXPR_APPLY@3042..3086 + EXPR_INDEX@3042..3051 + EXPR_VAR@3042..3045 + NAME@3042..3045 + IDENT@3042..3045 "std" + DOT@3045..3046 "." + NAME@3046..3051 + IDENT@3046..3051 "foldl" + ARGS_DESC@3051..3086 + L_PAREN@3051..3052 "(" + ARG@3052..3060 + EXPR_VAR@3052..3060 + NAME@3052..3060 + IDENT@3052..3060 "addDigit" + COMMA@3060..3061 "," + WHITESPACE@3061..3062 " " + ARG@3062..3082 + EXPR_APPLY@3062..3082 + EXPR_INDEX@3062..3077 + EXPR_VAR@3062..3065 + NAME@3062..3065 + IDENT@3062..3065 "std" + DOT@3065..3066 "." + NAME@3066..3077 + IDENT@3066..3077 "stringChars" + ARGS_DESC@3077..3082 + L_PAREN@3077..3078 "(" + ARG@3078..3081 + EXPR_VAR@3078..3081 + NAME@3078..3081 + IDENT@3078..3081 "str" + R_PAREN@3081..3082 ")" + COMMA@3082..3083 "," + WHITESPACE@3083..3084 " " + ARG@3084..3085 + EXPR_NUMBER@3084..3085 + FLOAT@3084..3085 "0" + R_PAREN@3085..3086 ")" + COMMA@3086..3087 "," + WHITESPACE@3087..3091 "\n\n " + MEMBER_FIELD@3091..3347 + FIELD_METHOD@3091..3347 + FIELD_NAME_FIXED@3091..3099 + NAME@3091..3099 + IDENT@3091..3099 "parseInt" + PARAMS_DESC@3099..3104 + L_PAREN@3099..3100 "(" + PARAM@3100..3103 + DESTRUCT_FULL@3100..3103 + NAME@3100..3103 + IDENT@3100..3103 "str" + R_PAREN@3103..3104 ")" + COLONCOLON@3104..3106 "::" + WHITESPACE@3106..3111 "\n " + EXPR_ASSERT@3111..3347 + ASSERTION@3111..3177 + ASSERT_KW@3111..3117 "assert" + WHITESPACE@3117..3118 " " + LHS_EXPR@3118..3135 + EXPR_APPLY@3118..3135 + EXPR_INDEX@3118..3130 + EXPR_VAR@3118..3121 + NAME@3118..3121 + IDENT@3118..3121 "std" + DOT@3121..3122 "." + NAME@3122..3130 + IDENT@3122..3130 "isString" + ARGS_DESC@3130..3135 + L_PAREN@3130..3131 "(" + ARG@3131..3134 + EXPR_VAR@3131..3134 + NAME@3131..3134 + IDENT@3131..3134 "str" + R_PAREN@3134..3135 ")" + WHITESPACE@3135..3136 " " + COLON@3136..3137 ":" + WHITESPACE@3137..3138 " " + EXPR_BINARY@3138..3177 + LHS_EXPR@3138..3161 + EXPR_STRING@3138..3161 + STRING_SINGLE@3138..3161 "'Expected string, got '" + WHITESPACE@3161..3162 " " + PLUS@3162..3163 "+" + WHITESPACE@3163..3164 " " + EXPR_APPLY@3164..3177 + EXPR_INDEX@3164..3172 + EXPR_VAR@3164..3167 + NAME@3164..3167 + IDENT@3164..3167 "std" + DOT@3167..3168 "." + NAME@3168..3172 + IDENT@3168..3172 "type" + ARGS_DESC@3172..3177 + L_PAREN@3172..3173 "(" + ARG@3173..3176 + EXPR_VAR@3173..3176 + NAME@3173..3176 + IDENT@3173..3176 "str" + R_PAREN@3176..3177 ")" + SEMI@3177..3178 ";" + WHITESPACE@3178..3183 "\n " + EXPR_ASSERT@3183..3347 + ASSERTION@3183..3256 + ASSERT_KW@3183..3189 "assert" + WHITESPACE@3189..3190 " " + LHS_EXPR@3190..3223 + EXPR_BINARY@3190..3223 + LHS_EXPR@3190..3209 + EXPR_BINARY@3190..3209 + LHS_EXPR@3190..3205 + EXPR_APPLY@3190..3205 + EXPR_INDEX@3190..3200 + EXPR_VAR@3190..3193 + NAME@3190..3193 + IDENT@3190..3193 "std" + DOT@3193..3194 "." + NAME@3194..3200 + IDENT@3194..3200 "length" + ARGS_DESC@3200..3205 + L_PAREN@3200..3201 "(" + ARG@3201..3204 + EXPR_VAR@3201..3204 + NAME@3201..3204 + IDENT@3201..3204 "str" + R_PAREN@3204..3205 ")" + WHITESPACE@3205..3206 " " + GT@3206..3207 ">" + WHITESPACE@3207..3208 " " + EXPR_NUMBER@3208..3209 + FLOAT@3208..3209 "0" + WHITESPACE@3209..3210 " " + AND@3210..3212 "&&" + WHITESPACE@3212..3213 " " + EXPR_BINARY@3213..3223 + LHS_EXPR@3213..3216 + EXPR_VAR@3213..3216 + NAME@3213..3216 + IDENT@3213..3216 "str" + WHITESPACE@3216..3217 " " + NE@3217..3219 "!=" + WHITESPACE@3219..3220 " " + EXPR_STRING@3220..3223 + STRING_SINGLE@3220..3223 "'-'" + WHITESPACE@3223..3224 " " + COLON@3224..3225 ":" + WHITESPACE@3225..3226 " " + EXPR_BINARY@3226..3256 + LHS_EXPR@3226..3248 + EXPR_STRING@3226..3248 + STRING_SINGLE@3226..3248 "'Not an integer: \"%s\"'" + WHITESPACE@3248..3249 " " + MODULO@3249..3250 "%" + WHITESPACE@3250..3251 " " + EXPR_ARRAY@3251..3256 + L_BRACK@3251..3252 "[" + EXPR_VAR@3252..3255 + NAME@3252..3255 + IDENT@3252..3255 "str" + R_BRACK@3255..3256 "]" + SEMI@3256..3257 ";" + WHITESPACE@3257..3262 "\n " + EXPR_IF_THEN_ELSE@3262..3347 + IF_KW@3262..3264 "if" + WHITESPACE@3264..3265 " " + EXPR_BINARY@3265..3278 + LHS_EXPR@3265..3271 + EXPR_INDEX_EXPR@3265..3271 + LHS_EXPR@3265..3268 + EXPR_VAR@3265..3268 + NAME@3265..3268 + IDENT@3265..3268 "str" + L_BRACK@3268..3269 "[" + EXPR_NUMBER@3269..3270 + FLOAT@3269..3270 "0" + R_BRACK@3270..3271 "]" + WHITESPACE@3271..3272 " " + EQ@3272..3274 "==" + WHITESPACE@3274..3275 " " + EXPR_STRING@3275..3278 + STRING_SINGLE@3275..3278 "'-'" + WHITESPACE@3278..3279 " " + THEN_KW@3279..3283 "then" + WHITESPACE@3283..3290 "\n " + TRUE_EXPR@3290..3313 + EXPR_UNARY@3290..3313 + MINUS@3290..3291 "-" + EXPR_APPLY@3291..3313 + EXPR_VAR@3291..3300 + NAME@3291..3300 + IDENT@3291..3300 "parse_nat" + ARGS_DESC@3300..3313 + L_PAREN@3300..3301 "(" + ARG@3301..3308 + EXPR_SLICE@3301..3308 + EXPR_VAR@3301..3304 + NAME@3301..3304 + IDENT@3301..3304 "str" + SLICE_DESC@3304..3308 + L_BRACK@3304..3305 "[" + EXPR_NUMBER@3305..3306 + FLOAT@3305..3306 "1" + COLON@3306..3307 ":" + R_BRACK@3307..3308 "]" + COMMA@3308..3309 "," + WHITESPACE@3309..3310 " " + ARG@3310..3312 + EXPR_NUMBER@3310..3312 + FLOAT@3310..3312 "10" + R_PAREN@3312..3313 ")" + WHITESPACE@3313..3318 "\n " + ELSE_KW@3318..3322 "else" + WHITESPACE@3322..3329 "\n " + FALSE_EXPR@3329..3347 + EXPR_APPLY@3329..3347 + EXPR_VAR@3329..3338 + NAME@3329..3338 + IDENT@3329..3338 "parse_nat" + ARGS_DESC@3338..3347 + L_PAREN@3338..3339 "(" + ARG@3339..3342 + EXPR_VAR@3339..3342 + NAME@3339..3342 + IDENT@3339..3342 "str" + COMMA@3342..3343 "," + WHITESPACE@3343..3344 " " + ARG@3344..3346 + EXPR_NUMBER@3344..3346 + FLOAT@3344..3346 "10" + R_PAREN@3346..3347 ")" + COMMA@3347..3348 "," + WHITESPACE@3348..3352 "\n\n " + MEMBER_FIELD@3352..3523 + FIELD_METHOD@3352..3523 + FIELD_NAME_FIXED@3352..3362 + NAME@3352..3362 + IDENT@3352..3362 "parseOctal" + PARAMS_DESC@3362..3367 + L_PAREN@3362..3363 "(" + PARAM@3363..3366 + DESTRUCT_FULL@3363..3366 + NAME@3363..3366 + IDENT@3363..3366 "str" + R_PAREN@3366..3367 ")" + COLONCOLON@3367..3369 "::" + WHITESPACE@3369..3374 "\n " + EXPR_ASSERT@3374..3523 + ASSERTION@3374..3440 + ASSERT_KW@3374..3380 "assert" + WHITESPACE@3380..3381 " " + LHS_EXPR@3381..3398 + EXPR_APPLY@3381..3398 + EXPR_INDEX@3381..3393 + EXPR_VAR@3381..3384 + NAME@3381..3384 + IDENT@3381..3384 "std" + DOT@3384..3385 "." + NAME@3385..3393 + IDENT@3385..3393 "isString" + ARGS_DESC@3393..3398 + L_PAREN@3393..3394 "(" + ARG@3394..3397 + EXPR_VAR@3394..3397 + NAME@3394..3397 + IDENT@3394..3397 "str" + R_PAREN@3397..3398 ")" + WHITESPACE@3398..3399 " " + COLON@3399..3400 ":" + WHITESPACE@3400..3401 " " + EXPR_BINARY@3401..3440 + LHS_EXPR@3401..3424 + EXPR_STRING@3401..3424 + STRING_SINGLE@3401..3424 "'Expected string, got '" + WHITESPACE@3424..3425 " " + PLUS@3425..3426 "+" + WHITESPACE@3426..3427 " " + EXPR_APPLY@3427..3440 + EXPR_INDEX@3427..3435 + EXPR_VAR@3427..3430 + NAME@3427..3430 + IDENT@3427..3430 "std" + DOT@3430..3431 "." + NAME@3431..3435 + IDENT@3431..3435 "type" + ARGS_DESC@3435..3440 + L_PAREN@3435..3436 "(" + ARG@3436..3439 + EXPR_VAR@3436..3439 + NAME@3436..3439 + IDENT@3436..3439 "str" + R_PAREN@3439..3440 ")" + SEMI@3440..3441 ";" + WHITESPACE@3441..3446 "\n " + EXPR_ASSERT@3446..3523 + ASSERTION@3446..3500 + ASSERT_KW@3446..3452 "assert" + WHITESPACE@3452..3453 " " + LHS_EXPR@3453..3472 + EXPR_BINARY@3453..3472 + LHS_EXPR@3453..3468 + EXPR_APPLY@3453..3468 + EXPR_INDEX@3453..3463 + EXPR_VAR@3453..3456 + NAME@3453..3456 + IDENT@3453..3456 "std" + DOT@3456..3457 "." + NAME@3457..3463 + IDENT@3457..3463 "length" + ARGS_DESC@3463..3468 + L_PAREN@3463..3464 "(" + ARG@3464..3467 + EXPR_VAR@3464..3467 + NAME@3464..3467 + IDENT@3464..3467 "str" + R_PAREN@3467..3468 ")" + WHITESPACE@3468..3469 " " + GT@3469..3470 ">" + WHITESPACE@3470..3471 " " + EXPR_NUMBER@3471..3472 + FLOAT@3471..3472 "0" + WHITESPACE@3472..3473 " " + COLON@3473..3474 ":" + WHITESPACE@3474..3475 " " + EXPR_STRING@3475..3500 + STRING_SINGLE@3475..3500 "'Not an octal number: ..." + SEMI@3500..3501 ";" + WHITESPACE@3501..3506 "\n " + EXPR_APPLY@3506..3523 + EXPR_VAR@3506..3515 + NAME@3506..3515 + IDENT@3506..3515 "parse_nat" + ARGS_DESC@3515..3523 + L_PAREN@3515..3516 "(" + ARG@3516..3519 + EXPR_VAR@3516..3519 + NAME@3516..3519 + IDENT@3516..3519 "str" + COMMA@3519..3520 "," + WHITESPACE@3520..3521 " " + ARG@3521..3522 + EXPR_NUMBER@3521..3522 + FLOAT@3521..3522 "8" + R_PAREN@3522..3523 ")" + COMMA@3523..3524 "," + WHITESPACE@3524..3528 "\n\n " + MEMBER_FIELD@3528..3694 + FIELD_METHOD@3528..3694 + FIELD_NAME_FIXED@3528..3536 + NAME@3528..3536 + IDENT@3528..3536 "parseHex" + PARAMS_DESC@3536..3541 + L_PAREN@3536..3537 "(" + PARAM@3537..3540 + DESTRUCT_FULL@3537..3540 + NAME@3537..3540 + IDENT@3537..3540 "str" + R_PAREN@3540..3541 ")" + COLONCOLON@3541..3543 "::" + WHITESPACE@3543..3548 "\n " + EXPR_ASSERT@3548..3694 + ASSERTION@3548..3614 + ASSERT_KW@3548..3554 "assert" + WHITESPACE@3554..3555 " " + LHS_EXPR@3555..3572 + EXPR_APPLY@3555..3572 + EXPR_INDEX@3555..3567 + EXPR_VAR@3555..3558 + NAME@3555..3558 + IDENT@3555..3558 "std" + DOT@3558..3559 "." + NAME@3559..3567 + IDENT@3559..3567 "isString" + ARGS_DESC@3567..3572 + L_PAREN@3567..3568 "(" + ARG@3568..3571 + EXPR_VAR@3568..3571 + NAME@3568..3571 + IDENT@3568..3571 "str" + R_PAREN@3571..3572 ")" + WHITESPACE@3572..3573 " " + COLON@3573..3574 ":" + WHITESPACE@3574..3575 " " + EXPR_BINARY@3575..3614 + LHS_EXPR@3575..3598 + EXPR_STRING@3575..3598 + STRING_SINGLE@3575..3598 "'Expected string, got '" + WHITESPACE@3598..3599 " " + PLUS@3599..3600 "+" + WHITESPACE@3600..3601 " " + EXPR_APPLY@3601..3614 + EXPR_INDEX@3601..3609 + EXPR_VAR@3601..3604 + NAME@3601..3604 + IDENT@3601..3604 "std" + DOT@3604..3605 "." + NAME@3605..3609 + IDENT@3605..3609 "type" + ARGS_DESC@3609..3614 + L_PAREN@3609..3610 "(" + ARG@3610..3613 + EXPR_VAR@3610..3613 + NAME@3610..3613 + IDENT@3610..3613 "str" + R_PAREN@3613..3614 ")" + SEMI@3614..3615 ";" + WHITESPACE@3615..3620 "\n " + EXPR_ASSERT@3620..3694 + ASSERTION@3620..3670 + ASSERT_KW@3620..3626 "assert" + WHITESPACE@3626..3627 " " + LHS_EXPR@3627..3646 + EXPR_BINARY@3627..3646 + LHS_EXPR@3627..3642 + EXPR_APPLY@3627..3642 + EXPR_INDEX@3627..3637 + EXPR_VAR@3627..3630 + NAME@3627..3630 + IDENT@3627..3630 "std" + DOT@3630..3631 "." + NAME@3631..3637 + IDENT@3631..3637 "length" + ARGS_DESC@3637..3642 + L_PAREN@3637..3638 "(" + ARG@3638..3641 + EXPR_VAR@3638..3641 + NAME@3638..3641 + IDENT@3638..3641 "str" + R_PAREN@3641..3642 ")" + WHITESPACE@3642..3643 " " + GT@3643..3644 ">" + WHITESPACE@3644..3645 " " + EXPR_NUMBER@3645..3646 + FLOAT@3645..3646 "0" + WHITESPACE@3646..3647 " " + COLON@3647..3648 ":" + WHITESPACE@3648..3649 " " + EXPR_STRING@3649..3670 + STRING_SINGLE@3649..3670 "'Not hexadecimal: \"\"'" + SEMI@3670..3671 ";" + WHITESPACE@3671..3676 "\n " + EXPR_APPLY@3676..3694 + EXPR_VAR@3676..3685 + NAME@3676..3685 + IDENT@3676..3685 "parse_nat" + ARGS_DESC@3685..3694 + L_PAREN@3685..3686 "(" + ARG@3686..3689 + EXPR_VAR@3686..3689 + NAME@3686..3689 + IDENT@3686..3689 "str" + COMMA@3689..3690 "," + WHITESPACE@3690..3691 " " + ARG@3691..3693 + EXPR_NUMBER@3691..3693 + FLOAT@3691..3693 "16" + R_PAREN@3693..3694 ")" + COMMA@3694..3695 "," + WHITESPACE@3695..3699 "\n\n " + MEMBER_FIELD@3699..3741 + FIELD_METHOD@3699..3741 + FIELD_NAME_FIXED@3699..3704 + NAME@3699..3704 + IDENT@3699..3704 "split" + PARAMS_DESC@3704..3712 + L_PAREN@3704..3705 "(" + PARAM@3705..3708 + DESTRUCT_FULL@3705..3708 + NAME@3705..3708 + IDENT@3705..3708 "str" + COMMA@3708..3709 "," + WHITESPACE@3709..3710 " " + PARAM@3710..3711 + DESTRUCT_FULL@3710..3711 + NAME@3710..3711 + IDENT@3710..3711 "c" + R_PAREN@3711..3712 ")" + COLONCOLON@3712..3714 "::" + WHITESPACE@3714..3715 " " + EXPR_APPLY@3715..3741 + EXPR_INDEX@3715..3729 + EXPR_VAR@3715..3718 + NAME@3715..3718 + IDENT@3715..3718 "std" + DOT@3718..3719 "." + NAME@3719..3729 + IDENT@3719..3729 "splitLimit" + ARGS_DESC@3729..3741 + L_PAREN@3729..3730 "(" + ARG@3730..3733 + EXPR_VAR@3730..3733 + NAME@3730..3733 + IDENT@3730..3733 "str" + COMMA@3733..3734 "," + WHITESPACE@3734..3735 " " + ARG@3735..3736 + EXPR_VAR@3735..3736 + NAME@3735..3736 + IDENT@3735..3736 "c" + COMMA@3736..3737 "," + WHITESPACE@3737..3738 " " + ARG@3738..3740 + EXPR_UNARY@3738..3740 + MINUS@3738..3739 "-" + EXPR_NUMBER@3739..3740 + FLOAT@3739..3740 "1" + R_PAREN@3740..3741 ")" + COMMA@3741..3742 "," + WHITESPACE@3742..3746 "\n\n " + MEMBER_FIELD@3746..3781 + FIELD_NORMAL@3746..3781 + FIELD_NAME_FIXED@3746..3756 + NAME@3746..3756 + IDENT@3746..3756 "splitLimit" + COLONCOLON@3756..3758 "::" + WHITESPACE@3758..3759 " " + EXPR_INTRINSIC@3759..3781 + INTRINSIC@3759..3769 "$intrinsic" + L_PAREN@3769..3770 "(" + NAME@3770..3780 + IDENT@3770..3780 "splitLimit" + R_PAREN@3780..3781 ")" + COMMA@3781..3782 "," + WHITESPACE@3782..3786 "\n\n " + MEMBER_FIELD@3786..3821 + FIELD_NORMAL@3786..3821 + FIELD_NAME_FIXED@3786..3796 + NAME@3786..3796 + IDENT@3786..3796 "strReplace" + COLONCOLON@3796..3798 "::" + WHITESPACE@3798..3799 " " + EXPR_INTRINSIC@3799..3821 + INTRINSIC@3799..3809 "$intrinsic" + L_PAREN@3809..3810 "(" + NAME@3810..3820 + IDENT@3810..3820 "strReplace" + R_PAREN@3820..3821 ")" + COMMA@3821..3822 "," + WHITESPACE@3822..3826 "\n\n " + MEMBER_FIELD@3826..3861 + FIELD_NORMAL@3826..3861 + FIELD_NAME_FIXED@3826..3836 + NAME@3826..3836 + IDENT@3826..3836 "asciiUpper" + COLONCOLON@3836..3838 "::" + WHITESPACE@3838..3839 " " + EXPR_INTRINSIC@3839..3861 + INTRINSIC@3839..3849 "$intrinsic" + L_PAREN@3849..3850 "(" + NAME@3850..3860 + IDENT@3850..3860 "asciiUpper" + R_PAREN@3860..3861 ")" + COMMA@3861..3862 "," + WHITESPACE@3862..3866 "\n\n " + MEMBER_FIELD@3866..3901 + FIELD_NORMAL@3866..3901 + FIELD_NAME_FIXED@3866..3876 + NAME@3866..3876 + IDENT@3866..3876 "asciiLower" + COLONCOLON@3876..3878 "::" + WHITESPACE@3878..3879 " " + EXPR_INTRINSIC@3879..3901 + INTRINSIC@3879..3889 "$intrinsic" + L_PAREN@3889..3890 "(" + NAME@3890..3900 + IDENT@3890..3900 "asciiLower" + R_PAREN@3900..3901 ")" + COMMA@3901..3902 "," + WHITESPACE@3902..3906 "\n\n " + MEMBER_FIELD@3906..3931 + FIELD_NORMAL@3906..3931 + FIELD_NAME_FIXED@3906..3911 + NAME@3906..3911 + IDENT@3906..3911 "range" + COLONCOLON@3911..3913 "::" + WHITESPACE@3913..3914 " " + EXPR_INTRINSIC@3914..3931 + INTRINSIC@3914..3924 "$intrinsic" + L_PAREN@3924..3925 "(" + NAME@3925..3930 + IDENT@3925..3930 "range" + R_PAREN@3930..3931 ")" + COMMA@3931..3932 "," + WHITESPACE@3932..3936 "\n\n " + MEMBER_FIELD@3936..4188 + FIELD_METHOD@3936..4188 + FIELD_NAME_FIXED@3936..3942 + NAME@3936..3942 + IDENT@3936..3942 "repeat" + PARAMS_DESC@3942..3955 + L_PAREN@3942..3943 "(" + PARAM@3943..3947 + DESTRUCT_FULL@3943..3947 + NAME@3943..3947 + IDENT@3943..3947 "what" + COMMA@3947..3948 "," + WHITESPACE@3948..3949 " " + PARAM@3949..3954 + DESTRUCT_FULL@3949..3954 + NAME@3949..3954 + IDENT@3949..3954 "count" + R_PAREN@3954..3955 ")" + COLONCOLON@3955..3957 "::" + WHITESPACE@3957..3962 "\n " + EXPR_LOCAL@3962..4188 + LOCAL_KW@3962..3967 "local" + WHITESPACE@3967..3968 " " + BIND_DESTRUCT@3968..4126 + DESTRUCT_FULL@3968..3974 + NAME@3968..3974 + IDENT@3968..3974 "joiner" + WHITESPACE@3974..3975 " " + ASSIGN@3975..3976 "=" + WHITESPACE@3976..3983 "\n " + EXPR_IF_THEN_ELSE@3983..4126 + IF_KW@3983..3985 "if" + WHITESPACE@3985..3986 " " + EXPR_APPLY@3986..4004 + EXPR_INDEX@3986..3998 + EXPR_VAR@3986..3989 + NAME@3986..3989 + IDENT@3986..3989 "std" + DOT@3989..3990 "." + NAME@3990..3998 + IDENT@3990..3998 "isString" + ARGS_DESC@3998..4004 + L_PAREN@3998..3999 "(" + ARG@3999..4003 + EXPR_VAR@3999..4003 + NAME@3999..4003 + IDENT@3999..4003 "what" + R_PAREN@4003..4004 ")" + WHITESPACE@4004..4005 " " + THEN_KW@4005..4009 "then" + WHITESPACE@4009..4010 " " + TRUE_EXPR@4010..4012 + EXPR_STRING@4010..4012 + STRING_SINGLE@4010..4012 "''" + WHITESPACE@4012..4019 "\n " + ELSE_KW@4019..4023 "else" + WHITESPACE@4023..4024 " " + FALSE_EXPR@4024..4126 + EXPR_IF_THEN_ELSE@4024..4126 + IF_KW@4024..4026 "if" + WHITESPACE@4026..4027 " " + EXPR_APPLY@4027..4044 + EXPR_INDEX@4027..4038 + EXPR_VAR@4027..4030 + NAME@4027..4030 + IDENT@4027..4030 "std" + DOT@4030..4031 "." + NAME@4031..4038 + IDENT@4031..4038 "isArray" + ARGS_DESC@4038..4044 + L_PAREN@4038..4039 "(" + ARG@4039..4043 + EXPR_VAR@4039..4043 + NAME@4039..4043 + IDENT@4039..4043 "what" + R_PAREN@4043..4044 ")" + WHITESPACE@4044..4045 " " + THEN_KW@4045..4049 "then" + WHITESPACE@4049..4050 " " + TRUE_EXPR@4050..4052 + EXPR_ARRAY@4050..4052 + L_BRACK@4050..4051 "[" + R_BRACK@4051..4052 "]" + WHITESPACE@4052..4059 "\n " + ELSE_KW@4059..4063 "else" + WHITESPACE@4063..4064 " " + FALSE_EXPR@4064..4126 + EXPR_ERROR@4064..4126 + ERROR_KW@4064..4069 "error" + WHITESPACE@4069..4070 " " + EXPR_STRING@4070..4126 + STRING_SINGLE@4070..4126 "'std.repeat first arg ..." + SEMI@4126..4127 ";" + WHITESPACE@4127..4132 "\n " + EXPR_APPLY@4132..4188 + EXPR_INDEX@4132..4140 + EXPR_VAR@4132..4135 + NAME@4132..4135 + IDENT@4132..4135 "std" + DOT@4135..4136 "." + NAME@4136..4140 + IDENT@4136..4140 "join" + ARGS_DESC@4140..4188 + L_PAREN@4140..4141 "(" + ARG@4141..4147 + EXPR_VAR@4141..4147 + NAME@4141..4147 + IDENT@4141..4147 "joiner" + COMMA@4147..4148 "," + WHITESPACE@4148..4149 " " + ARG@4149..4187 + EXPR_APPLY@4149..4187 + EXPR_INDEX@4149..4162 + EXPR_VAR@4149..4152 + NAME@4149..4152 + IDENT@4149..4152 "std" + DOT@4152..4153 "." + NAME@4153..4162 + IDENT@4153..4162 "makeArray" + ARGS_DESC@4162..4187 + L_PAREN@4162..4163 "(" + ARG@4163..4168 + EXPR_VAR@4163..4168 + NAME@4163..4168 + IDENT@4163..4168 "count" + COMMA@4168..4169 "," + WHITESPACE@4169..4170 " " + ARG@4170..4186 + EXPR_FUNCTION@4170..4186 + FUNCTION_KW@4170..4178 "function" + PARAMS_DESC@4178..4181 + L_PAREN@4178..4179 "(" + PARAM@4179..4180 + DESTRUCT_FULL@4179..4180 + NAME@4179..4180 + IDENT@4179..4180 "i" + R_PAREN@4180..4181 ")" + WHITESPACE@4181..4182 " " + EXPR_VAR@4182..4186 + NAME@4182..4186 + IDENT@4182..4186 "what" + R_PAREN@4186..4187 ")" + R_PAREN@4187..4188 ")" + COMMA@4188..4189 "," + WHITESPACE@4189..4193 "\n\n " + MEMBER_FIELD@4193..4218 + FIELD_NORMAL@4193..4218 + FIELD_NAME_FIXED@4193..4198 + NAME@4193..4198 + IDENT@4193..4198 "slice" + COLONCOLON@4198..4200 "::" + WHITESPACE@4200..4201 " " + EXPR_INTRINSIC@4201..4218 + INTRINSIC@4201..4211 "$intrinsic" + L_PAREN@4211..4212 "(" + NAME@4212..4217 + IDENT@4212..4217 "slice" + R_PAREN@4217..4218 ")" + COMMA@4218..4219 "," + WHITESPACE@4219..4223 "\n\n " + MEMBER_FIELD@4223..4250 + FIELD_NORMAL@4223..4250 + FIELD_NAME_FIXED@4223..4229 + NAME@4223..4229 + IDENT@4223..4229 "member" + COLONCOLON@4229..4231 "::" + WHITESPACE@4231..4232 " " + EXPR_INTRINSIC@4232..4250 + INTRINSIC@4232..4242 "$intrinsic" + L_PAREN@4242..4243 "(" + NAME@4243..4249 + IDENT@4243..4249 "member" + R_PAREN@4249..4250 ")" + COMMA@4250..4251 "," + WHITESPACE@4251..4255 "\n\n " + MEMBER_FIELD@4255..4280 + FIELD_NORMAL@4255..4280 + FIELD_NAME_FIXED@4255..4260 + NAME@4255..4260 + IDENT@4255..4260 "count" + COLONCOLON@4260..4262 "::" + WHITESPACE@4262..4263 " " + EXPR_INTRINSIC@4263..4280 + INTRINSIC@4263..4273 "$intrinsic" + L_PAREN@4273..4274 "(" + NAME@4274..4279 + IDENT@4274..4279 "count" + R_PAREN@4279..4280 ")" + COMMA@4280..4281 "," + WHITESPACE@4281..4285 "\n\n " + MEMBER_FIELD@4285..4306 + FIELD_NORMAL@4285..4306 + FIELD_NAME_FIXED@4285..4288 + NAME@4285..4288 + IDENT@4285..4288 "mod" + COLONCOLON@4288..4290 "::" + WHITESPACE@4290..4291 " " + EXPR_INTRINSIC@4291..4306 + INTRINSIC@4291..4301 "$intrinsic" + L_PAREN@4301..4302 "(" + NAME@4302..4305 + IDENT@4302..4305 "mod" + R_PAREN@4305..4306 ")" + COMMA@4306..4307 "," + WHITESPACE@4307..4311 "\n\n " + MEMBER_FIELD@4311..4332 + FIELD_NORMAL@4311..4332 + FIELD_NAME_FIXED@4311..4314 + NAME@4311..4314 + IDENT@4311..4314 "map" + COLONCOLON@4314..4316 "::" + WHITESPACE@4316..4317 " " + EXPR_INTRINSIC@4317..4332 + INTRINSIC@4317..4327 "$intrinsic" + L_PAREN@4327..4328 "(" + NAME@4328..4331 + IDENT@4328..4331 "map" + R_PAREN@4331..4332 ")" + COMMA@4332..4333 "," + WHITESPACE@4333..4337 "\n\n " + MEMBER_FIELD@4337..4695 + FIELD_METHOD@4337..4695 + FIELD_NAME_FIXED@4337..4349 + NAME@4337..4349 + IDENT@4337..4349 "mapWithIndex" + PARAMS_DESC@4349..4360 + L_PAREN@4349..4350 "(" + PARAM@4350..4354 + DESTRUCT_FULL@4350..4354 + NAME@4350..4354 + IDENT@4350..4354 "func" + COMMA@4354..4355 "," + WHITESPACE@4355..4356 " " + PARAM@4356..4359 + DESTRUCT_FULL@4356..4359 + NAME@4356..4359 + IDENT@4356..4359 "arr" + R_PAREN@4359..4360 ")" + COLONCOLON@4360..4362 "::" + WHITESPACE@4362..4367 "\n " + EXPR_IF_THEN_ELSE@4367..4695 + IF_KW@4367..4369 "if" + WHITESPACE@4369..4370 " " + EXPR_UNARY@4370..4391 + NOT@4370..4371 "!" + EXPR_APPLY@4371..4391 + EXPR_INDEX@4371..4385 + EXPR_VAR@4371..4374 + NAME@4371..4374 + IDENT@4371..4374 "std" + DOT@4374..4375 "." + NAME@4375..4385 + IDENT@4375..4385 "isFunction" + ARGS_DESC@4385..4391 + L_PAREN@4385..4386 "(" + ARG@4386..4390 + EXPR_VAR@4386..4390 + NAME@4386..4390 + IDENT@4386..4390 "func" + R_PAREN@4390..4391 ")" + WHITESPACE@4391..4392 " " + THEN_KW@4392..4396 "then" + WHITESPACE@4396..4403 "\n " + TRUE_EXPR@4403..4481 + EXPR_ERROR@4403..4481 + ERROR_KW@4403..4408 "error" + WHITESPACE@4408..4409 " " + EXPR_PARENED@4409..4481 + L_PAREN@4409..4410 "(" + EXPR_BINARY@4410..4480 + LHS_EXPR@4410..4463 + EXPR_STRING@4410..4463 + STRING_SINGLE@4410..4463 "'std.mapWithIndex fir ..." + WHITESPACE@4463..4464 " " + PLUS@4464..4465 "+" + WHITESPACE@4465..4466 " " + EXPR_APPLY@4466..4480 + EXPR_INDEX@4466..4474 + EXPR_VAR@4466..4469 + NAME@4466..4469 + IDENT@4466..4469 "std" + DOT@4469..4470 "." + NAME@4470..4474 + IDENT@4470..4474 "type" + ARGS_DESC@4474..4480 + L_PAREN@4474..4475 "(" + ARG@4475..4479 + EXPR_VAR@4475..4479 + NAME@4475..4479 + IDENT@4475..4479 "func" + R_PAREN@4479..4480 ")" + R_PAREN@4480..4481 ")" + WHITESPACE@4481..4486 "\n " + ELSE_KW@4486..4490 "else" + WHITESPACE@4490..4491 " " + FALSE_EXPR@4491..4695 + EXPR_IF_THEN_ELSE@4491..4695 + IF_KW@4491..4493 "if" + WHITESPACE@4493..4494 " " + EXPR_BINARY@4494..4533 + LHS_EXPR@4494..4511 + EXPR_UNARY@4494..4511 + NOT@4494..4495 "!" + EXPR_APPLY@4495..4511 + EXPR_INDEX@4495..4506 + EXPR_VAR@4495..4498 + NAME@4495..4498 + IDENT@4495..4498 "std" + DOT@4498..4499 "." + NAME@4499..4506 + IDENT@4499..4506 "isArray" + ARGS_DESC@4506..4511 + L_PAREN@4506..4507 "(" + ARG@4507..4510 + EXPR_VAR@4507..4510 + NAME@4507..4510 + IDENT@4507..4510 "arr" + R_PAREN@4510..4511 ")" + WHITESPACE@4511..4512 " " + AND@4512..4514 "&&" + WHITESPACE@4514..4515 " " + EXPR_UNARY@4515..4533 + NOT@4515..4516 "!" + EXPR_APPLY@4516..4533 + EXPR_INDEX@4516..4528 + EXPR_VAR@4516..4519 + NAME@4516..4519 + IDENT@4516..4519 "std" + DOT@4519..4520 "." + NAME@4520..4528 + IDENT@4520..4528 "isString" + ARGS_DESC@4528..4533 + L_PAREN@4528..4529 "(" + ARG@4529..4532 + EXPR_VAR@4529..4532 + NAME@4529..4532 + IDENT@4529..4532 "arr" + R_PAREN@4532..4533 ")" + WHITESPACE@4533..4534 " " + THEN_KW@4534..4538 "then" + WHITESPACE@4538..4545 "\n " + TRUE_EXPR@4545..4620 + EXPR_ERROR@4545..4620 + ERROR_KW@4545..4550 "error" + WHITESPACE@4550..4551 " " + EXPR_PARENED@4551..4620 + L_PAREN@4551..4552 "(" + EXPR_BINARY@4552..4619 + LHS_EXPR@4552..4603 + EXPR_STRING@4552..4603 + STRING_SINGLE@4552..4603 "'std.mapWithIndex sec ..." + WHITESPACE@4603..4604 " " + PLUS@4604..4605 "+" + WHITESPACE@4605..4606 " " + EXPR_APPLY@4606..4619 + EXPR_INDEX@4606..4614 + EXPR_VAR@4606..4609 + NAME@4606..4609 + IDENT@4606..4609 "std" + DOT@4609..4610 "." + NAME@4610..4614 + IDENT@4610..4614 "type" + ARGS_DESC@4614..4619 + L_PAREN@4614..4615 "(" + ARG@4615..4618 + EXPR_VAR@4615..4618 + NAME@4615..4618 + IDENT@4615..4618 "arr" + R_PAREN@4618..4619 ")" + R_PAREN@4619..4620 ")" + WHITESPACE@4620..4625 "\n " + ELSE_KW@4625..4629 "else" + WHITESPACE@4629..4636 "\n " + FALSE_EXPR@4636..4695 + EXPR_APPLY@4636..4695 + EXPR_INDEX@4636..4649 + EXPR_VAR@4636..4639 + NAME@4636..4639 + IDENT@4636..4639 "std" + DOT@4639..4640 "." + NAME@4640..4649 + IDENT@4640..4649 "makeArray" + ARGS_DESC@4649..4695 + L_PAREN@4649..4650 "(" + ARG@4650..4665 + EXPR_APPLY@4650..4665 + EXPR_INDEX@4650..4660 + EXPR_VAR@4650..4653 + NAME@4650..4653 + IDENT@4650..4653 "std" + DOT@4653..4654 "." + NAME@4654..4660 + IDENT@4654..4660 "length" + ARGS_DESC@4660..4665 + L_PAREN@4660..4661 "(" + ARG@4661..4664 + EXPR_VAR@4661..4664 + NAME@4661..4664 + IDENT@4661..4664 "arr" + R_PAREN@4664..4665 ")" + COMMA@4665..4666 "," + WHITESPACE@4666..4667 " " + ARG@4667..4694 + EXPR_FUNCTION@4667..4694 + FUNCTION_KW@4667..4675 "function" + PARAMS_DESC@4675..4678 + L_PAREN@4675..4676 "(" + PARAM@4676..4677 + DESTRUCT_FULL@4676..4677 + NAME@4676..4677 + IDENT@4676..4677 "i" + R_PAREN@4677..4678 ")" + WHITESPACE@4678..4679 " " + EXPR_APPLY@4679..4694 + EXPR_VAR@4679..4683 + NAME@4679..4683 + IDENT@4679..4683 "func" + ARGS_DESC@4683..4694 + L_PAREN@4683..4684 "(" + ARG@4684..4685 + EXPR_VAR@4684..4685 + NAME@4684..4685 + IDENT@4684..4685 "i" + COMMA@4685..4686 "," + WHITESPACE@4686..4687 " " + ARG@4687..4693 + EXPR_INDEX_EXPR@4687..4693 + LHS_EXPR@4687..4690 + EXPR_VAR@4687..4690 + NAME@4687..4690 + IDENT@4687..4690 "arr" + L_BRACK@4690..4691 "[" + EXPR_VAR@4691..4692 + NAME@4691..4692 + IDENT@4691..4692 "i" + R_BRACK@4692..4693 "]" + R_PAREN@4693..4694 ")" + R_PAREN@4694..4695 ")" + COMMA@4695..4696 "," + WHITESPACE@4696..4700 "\n\n " + MEMBER_FIELD@4700..5028 + FIELD_METHOD@4700..5028 + FIELD_NAME_FIXED@4700..4710 + NAME@4700..4710 + IDENT@4700..4710 "mapWithKey" + PARAMS_DESC@4710..4721 + L_PAREN@4710..4711 "(" + PARAM@4711..4715 + DESTRUCT_FULL@4711..4715 + NAME@4711..4715 + IDENT@4711..4715 "func" + COMMA@4715..4716 "," + WHITESPACE@4716..4717 " " + PARAM@4717..4720 + DESTRUCT_FULL@4717..4720 + NAME@4717..4720 + IDENT@4717..4720 "obj" + R_PAREN@4720..4721 ")" + COLONCOLON@4721..4723 "::" + WHITESPACE@4723..4728 "\n " + EXPR_IF_THEN_ELSE@4728..5028 + IF_KW@4728..4730 "if" + WHITESPACE@4730..4731 " " + EXPR_UNARY@4731..4752 + NOT@4731..4732 "!" + EXPR_APPLY@4732..4752 + EXPR_INDEX@4732..4746 + EXPR_VAR@4732..4735 + NAME@4732..4735 + IDENT@4732..4735 "std" + DOT@4735..4736 "." + NAME@4736..4746 + IDENT@4736..4746 "isFunction" + ARGS_DESC@4746..4752 + L_PAREN@4746..4747 "(" + ARG@4747..4751 + EXPR_VAR@4747..4751 + NAME@4747..4751 + IDENT@4747..4751 "func" + R_PAREN@4751..4752 ")" + WHITESPACE@4752..4753 " " + THEN_KW@4753..4757 "then" + WHITESPACE@4757..4764 "\n " + TRUE_EXPR@4764..4840 + EXPR_ERROR@4764..4840 + ERROR_KW@4764..4769 "error" + WHITESPACE@4769..4770 " " + EXPR_PARENED@4770..4840 + L_PAREN@4770..4771 "(" + EXPR_BINARY@4771..4839 + LHS_EXPR@4771..4822 + EXPR_STRING@4771..4822 + STRING_SINGLE@4771..4822 "'std.mapWithKey first ..." + WHITESPACE@4822..4823 " " + PLUS@4823..4824 "+" + WHITESPACE@4824..4825 " " + EXPR_APPLY@4825..4839 + EXPR_INDEX@4825..4833 + EXPR_VAR@4825..4828 + NAME@4825..4828 + IDENT@4825..4828 "std" + DOT@4828..4829 "." + NAME@4829..4833 + IDENT@4829..4833 "type" + ARGS_DESC@4833..4839 + L_PAREN@4833..4834 "(" + ARG@4834..4838 + EXPR_VAR@4834..4838 + NAME@4834..4838 + IDENT@4834..4838 "func" + R_PAREN@4838..4839 ")" + R_PAREN@4839..4840 ")" + WHITESPACE@4840..4845 "\n " + ELSE_KW@4845..4849 "else" + WHITESPACE@4849..4850 " " + FALSE_EXPR@4850..5028 + EXPR_IF_THEN_ELSE@4850..5028 + IF_KW@4850..4852 "if" + WHITESPACE@4852..4853 " " + EXPR_UNARY@4853..4871 + NOT@4853..4854 "!" + EXPR_APPLY@4854..4871 + EXPR_INDEX@4854..4866 + EXPR_VAR@4854..4857 + NAME@4854..4857 + IDENT@4854..4857 "std" + DOT@4857..4858 "." + NAME@4858..4866 + IDENT@4858..4866 "isObject" + ARGS_DESC@4866..4871 + L_PAREN@4866..4867 "(" + ARG@4867..4870 + EXPR_VAR@4867..4870 + NAME@4867..4870 + IDENT@4867..4870 "obj" + R_PAREN@4870..4871 ")" + WHITESPACE@4871..4872 " " + THEN_KW@4872..4876 "then" + WHITESPACE@4876..4883 "\n " + TRUE_EXPR@4883..4957 + EXPR_ERROR@4883..4957 + ERROR_KW@4883..4888 "error" + WHITESPACE@4888..4889 " " + EXPR_PARENED@4889..4957 + L_PAREN@4889..4890 "(" + EXPR_BINARY@4890..4956 + LHS_EXPR@4890..4940 + EXPR_STRING@4890..4940 + STRING_SINGLE@4890..4940 "'std.mapWithKey secon ..." + WHITESPACE@4940..4941 " " + PLUS@4941..4942 "+" + WHITESPACE@4942..4943 " " + EXPR_APPLY@4943..4956 + EXPR_INDEX@4943..4951 + EXPR_VAR@4943..4946 + NAME@4943..4946 + IDENT@4943..4946 "std" + DOT@4946..4947 "." + NAME@4947..4951 + IDENT@4947..4951 "type" + ARGS_DESC@4951..4956 + L_PAREN@4951..4952 "(" + ARG@4952..4955 + EXPR_VAR@4952..4955 + NAME@4952..4955 + IDENT@4952..4955 "obj" + R_PAREN@4955..4956 ")" + R_PAREN@4956..4957 ")" + WHITESPACE@4957..4962 "\n " + ELSE_KW@4962..4966 "else" + WHITESPACE@4966..4973 "\n " + FALSE_EXPR@4973..5028 + EXPR_OBJECT@4973..5028 + OBJ_BODY_MEMBER_LIST@4973..5028 + L_BRACE@4973..4974 "{" + WHITESPACE@4974..4975 " " + MEMBER_FIELD@4975..5026 + FIELD_NORMAL@4975..4995 + FIELD_NAME_DYNAMIC@4975..4978 + L_BRACK@4975..4976 "[" + EXPR_VAR@4976..4977 + NAME@4976..4977 + IDENT@4976..4977 "k" + R_BRACK@4977..4978 "]" + COLON@4978..4979 ":" + WHITESPACE@4979..4980 " " + EXPR_APPLY@4980..4995 + EXPR_VAR@4980..4984 + NAME@4980..4984 + IDENT@4980..4984 "func" + ARGS_DESC@4984..4995 + L_PAREN@4984..4985 "(" + ARG@4985..4986 + EXPR_VAR@4985..4986 + NAME@4985..4986 + IDENT@4985..4986 "k" + COMMA@4986..4987 "," + WHITESPACE@4987..4988 " " + ARG@4988..4994 + EXPR_INDEX_EXPR@4988..4994 + LHS_EXPR@4988..4991 + EXPR_VAR@4988..4991 + NAME@4988..4991 + IDENT@4988..4991 "obj" + L_BRACK@4991..4992 "[" + EXPR_VAR@4992..4993 + NAME@4992..4993 + IDENT@4992..4993 "k" + R_BRACK@4993..4994 "]" + R_PAREN@4994..4995 ")" + WHITESPACE@4995..4996 " " + FOR_SPEC@4996..5026 + FOR_KW@4996..4999 "for" + WHITESPACE@4999..5000 " " + NAME@5000..5001 + IDENT@5000..5001 "k" + WHITESPACE@5001..5002 " " + IN_KW@5002..5004 "in" + WHITESPACE@5004..5005 " " + EXPR_APPLY@5005..5026 + EXPR_INDEX@5005..5021 + EXPR_VAR@5005..5008 + NAME@5005..5008 + IDENT@5005..5008 "std" + DOT@5008..5009 "." + NAME@5009..5021 + IDENT@5009..5021 "objectFields" + ARGS_DESC@5021..5026 + L_PAREN@5021..5022 "(" + ARG@5022..5025 + EXPR_VAR@5022..5025 + NAME@5022..5025 + IDENT@5022..5025 "obj" + R_PAREN@5025..5026 ")" + WHITESPACE@5026..5027 " " + R_BRACE@5027..5028 "}" + COMMA@5028..5029 "," + WHITESPACE@5029..5033 "\n\n " + MEMBER_FIELD@5033..5062 + FIELD_NORMAL@5033..5062 + FIELD_NAME_FIXED@5033..5040 + NAME@5033..5040 + IDENT@5033..5040 "flatMap" + COLONCOLON@5040..5042 "::" + WHITESPACE@5042..5043 " " + EXPR_INTRINSIC@5043..5062 + INTRINSIC@5043..5053 "$intrinsic" + L_PAREN@5053..5054 "(" + NAME@5054..5061 + IDENT@5054..5061 "flatMap" + R_PAREN@5061..5062 ")" + COMMA@5062..5063 "," + WHITESPACE@5063..5067 "\n\n " + MEMBER_FIELD@5067..5090 + FIELD_NORMAL@5067..5090 + FIELD_NAME_FIXED@5067..5071 + NAME@5067..5071 + IDENT@5067..5071 "join" + COLONCOLON@5071..5073 "::" + WHITESPACE@5073..5074 " " + EXPR_INTRINSIC@5074..5090 + INTRINSIC@5074..5084 "$intrinsic" + L_PAREN@5084..5085 "(" + NAME@5085..5089 + IDENT@5085..5089 "join" + R_PAREN@5089..5090 ")" + COMMA@5090..5091 "," + WHITESPACE@5091..5095 "\n\n " + MEMBER_FIELD@5095..5138 + FIELD_METHOD@5095..5138 + FIELD_NAME_FIXED@5095..5100 + NAME@5095..5100 + IDENT@5095..5100 "lines" + PARAMS_DESC@5100..5105 + L_PAREN@5100..5101 "(" + PARAM@5101..5104 + DESTRUCT_FULL@5101..5104 + NAME@5101..5104 + IDENT@5101..5104 "arr" + R_PAREN@5104..5105 ")" + COLONCOLON@5105..5107 "::" + WHITESPACE@5107..5112 "\n " + EXPR_APPLY@5112..5138 + EXPR_INDEX@5112..5120 + EXPR_VAR@5112..5115 + NAME@5112..5115 + IDENT@5112..5115 "std" + DOT@5115..5116 "." + NAME@5116..5120 + IDENT@5116..5120 "join" + ARGS_DESC@5120..5138 + L_PAREN@5120..5121 "(" + ARG@5121..5125 + EXPR_STRING@5121..5125 + STRING_SINGLE@5121..5125 "'\\n'" + COMMA@5125..5126 "," + WHITESPACE@5126..5127 " " + ARG@5127..5137 + EXPR_BINARY@5127..5137 + LHS_EXPR@5127..5130 + EXPR_VAR@5127..5130 + NAME@5127..5130 + IDENT@5127..5130 "arr" + WHITESPACE@5130..5131 " " + PLUS@5131..5132 "+" + WHITESPACE@5132..5133 " " + EXPR_ARRAY@5133..5137 + L_BRACK@5133..5134 "[" + EXPR_STRING@5134..5136 + STRING_SINGLE@5134..5136 "''" + R_BRACK@5136..5137 "]" + R_PAREN@5137..5138 ")" + COMMA@5138..5139 "," + WHITESPACE@5139..5143 "\n\n " + MEMBER_FIELD@5143..5355 + FIELD_METHOD@5143..5355 + FIELD_NAME_FIXED@5143..5151 + NAME@5143..5151 + IDENT@5143..5151 "deepJoin" + PARAMS_DESC@5151..5156 + L_PAREN@5151..5152 "(" + PARAM@5152..5155 + DESTRUCT_FULL@5152..5155 + NAME@5152..5155 + IDENT@5152..5155 "arr" + R_PAREN@5155..5156 ")" + COLONCOLON@5156..5158 "::" + WHITESPACE@5158..5163 "\n " + EXPR_IF_THEN_ELSE@5163..5355 + IF_KW@5163..5165 "if" + WHITESPACE@5165..5166 " " + EXPR_APPLY@5166..5183 + EXPR_INDEX@5166..5178 + EXPR_VAR@5166..5169 + NAME@5166..5169 + IDENT@5166..5169 "std" + DOT@5169..5170 "." + NAME@5170..5178 + IDENT@5170..5178 "isString" + ARGS_DESC@5178..5183 + L_PAREN@5178..5179 "(" + ARG@5179..5182 + EXPR_VAR@5179..5182 + NAME@5179..5182 + IDENT@5179..5182 "arr" + R_PAREN@5182..5183 ")" + WHITESPACE@5183..5184 " " + THEN_KW@5184..5188 "then" + WHITESPACE@5188..5195 "\n " + TRUE_EXPR@5195..5198 + EXPR_VAR@5195..5198 + NAME@5195..5198 + IDENT@5195..5198 "arr" + WHITESPACE@5198..5203 "\n " + ELSE_KW@5203..5207 "else" + WHITESPACE@5207..5208 " " + FALSE_EXPR@5208..5355 + EXPR_IF_THEN_ELSE@5208..5355 + IF_KW@5208..5210 "if" + WHITESPACE@5210..5211 " " + EXPR_APPLY@5211..5227 + EXPR_INDEX@5211..5222 + EXPR_VAR@5211..5214 + NAME@5211..5214 + IDENT@5211..5214 "std" + DOT@5214..5215 "." + NAME@5215..5222 + IDENT@5215..5222 "isArray" + ARGS_DESC@5222..5227 + L_PAREN@5222..5223 "(" + ARG@5223..5226 + EXPR_VAR@5223..5226 + NAME@5223..5226 + IDENT@5223..5226 "arr" + R_PAREN@5226..5227 ")" + WHITESPACE@5227..5228 " " + THEN_KW@5228..5232 "then" + WHITESPACE@5232..5239 "\n " + TRUE_EXPR@5239..5283 + EXPR_APPLY@5239..5283 + EXPR_INDEX@5239..5247 + EXPR_VAR@5239..5242 + NAME@5239..5242 + IDENT@5239..5242 "std" + DOT@5242..5243 "." + NAME@5243..5247 + IDENT@5243..5247 "join" + ARGS_DESC@5247..5283 + L_PAREN@5247..5248 "(" + ARG@5248..5250 + EXPR_STRING@5248..5250 + STRING_SINGLE@5248..5250 "''" + COMMA@5250..5251 "," + WHITESPACE@5251..5252 " " + ARG@5252..5282 + EXPR_ARRAY_COMP@5252..5282 + L_BRACK@5252..5253 "[" + EXPR_APPLY@5253..5268 + EXPR_INDEX@5253..5265 + EXPR_VAR@5253..5256 + NAME@5253..5256 + IDENT@5253..5256 "std" + DOT@5256..5257 "." + NAME@5257..5265 + IDENT@5257..5265 "deepJoin" + ARGS_DESC@5265..5268 + L_PAREN@5265..5266 "(" + ARG@5266..5267 + EXPR_VAR@5266..5267 + NAME@5266..5267 + IDENT@5266..5267 "x" + R_PAREN@5267..5268 ")" + WHITESPACE@5268..5269 " " + FOR_SPEC@5269..5281 + FOR_KW@5269..5272 "for" + WHITESPACE@5272..5273 " " + NAME@5273..5274 + IDENT@5273..5274 "x" + WHITESPACE@5274..5275 " " + IN_KW@5275..5277 "in" + WHITESPACE@5277..5278 " " + EXPR_VAR@5278..5281 + NAME@5278..5281 + IDENT@5278..5281 "arr" + R_BRACK@5281..5282 "]" + R_PAREN@5282..5283 ")" + WHITESPACE@5283..5288 "\n " + ELSE_KW@5288..5292 "else" + WHITESPACE@5292..5299 "\n " + FALSE_EXPR@5299..5355 + EXPR_ERROR@5299..5355 + ERROR_KW@5299..5304 "error" + WHITESPACE@5304..5305 " " + EXPR_BINARY@5305..5355 + LHS_EXPR@5305..5339 + EXPR_STRING@5305..5339 + STRING_SINGLE@5305..5339 "'Expected string or a ..." + WHITESPACE@5339..5340 " " + MODULO@5340..5341 "%" + WHITESPACE@5341..5342 " " + EXPR_APPLY@5342..5355 + EXPR_INDEX@5342..5350 + EXPR_VAR@5342..5345 + NAME@5342..5345 + IDENT@5342..5345 "std" + DOT@5345..5346 "." + NAME@5346..5350 + IDENT@5346..5350 "type" + ARGS_DESC@5350..5355 + L_PAREN@5350..5351 "(" + ARG@5351..5354 + EXPR_VAR@5351..5354 + NAME@5351..5354 + IDENT@5351..5354 "arr" + R_PAREN@5354..5355 ")" + COMMA@5355..5356 "," + WHITESPACE@5356..5361 "\n\n\n " + MEMBER_FIELD@5361..5388 + FIELD_NORMAL@5361..5388 + FIELD_NAME_FIXED@5361..5367 + NAME@5361..5367 + IDENT@5361..5367 "format" + COLONCOLON@5367..5369 "::" + WHITESPACE@5369..5370 " " + EXPR_INTRINSIC@5370..5388 + INTRINSIC@5370..5380 "$intrinsic" + L_PAREN@5380..5381 "(" + NAME@5381..5387 + IDENT@5381..5387 "format" + R_PAREN@5387..5388 ")" + COMMA@5388..5389 "," + WHITESPACE@5389..5393 "\n\n " + MEMBER_FIELD@5393..5418 + FIELD_NORMAL@5393..5418 + FIELD_NAME_FIXED@5393..5398 + NAME@5393..5398 + IDENT@5393..5398 "foldr" + COLONCOLON@5398..5400 "::" + WHITESPACE@5400..5401 " " + EXPR_INTRINSIC@5401..5418 + INTRINSIC@5401..5411 "$intrinsic" + L_PAREN@5411..5412 "(" + NAME@5412..5417 + IDENT@5412..5417 "foldr" + R_PAREN@5417..5418 ")" + COMMA@5418..5419 "," + WHITESPACE@5419..5423 "\n\n " + MEMBER_FIELD@5423..5448 + FIELD_NORMAL@5423..5448 + FIELD_NAME_FIXED@5423..5428 + NAME@5423..5428 + IDENT@5423..5428 "foldl" + COLONCOLON@5428..5430 "::" + WHITESPACE@5430..5431 " " + EXPR_INTRINSIC@5431..5448 + INTRINSIC@5431..5441 "$intrinsic" + L_PAREN@5441..5442 "(" + NAME@5442..5447 + IDENT@5442..5447 "foldl" + R_PAREN@5447..5448 ")" + COMMA@5448..5449 "," + WHITESPACE@5449..5453 "\n\n " + MEMBER_FIELD@5453..5928 + FIELD_METHOD@5453..5928 + FIELD_NAME_FIXED@5453..5462 + NAME@5453..5462 + IDENT@5453..5462 "filterMap" + PARAMS_DESC@5462..5490 + L_PAREN@5462..5463 "(" + PARAM@5463..5474 + DESTRUCT_FULL@5463..5474 + NAME@5463..5474 + IDENT@5463..5474 "filter_func" + COMMA@5474..5475 "," + WHITESPACE@5475..5476 " " + PARAM@5476..5484 + DESTRUCT_FULL@5476..5484 + NAME@5476..5484 + IDENT@5476..5484 "map_func" + COMMA@5484..5485 "," + WHITESPACE@5485..5486 " " + PARAM@5486..5489 + DESTRUCT_FULL@5486..5489 + NAME@5486..5489 + IDENT@5486..5489 "arr" + R_PAREN@5489..5490 ")" + COLONCOLON@5490..5492 "::" + WHITESPACE@5492..5497 "\n " + EXPR_IF_THEN_ELSE@5497..5928 + IF_KW@5497..5499 "if" + WHITESPACE@5499..5500 " " + EXPR_UNARY@5500..5528 + NOT@5500..5501 "!" + EXPR_APPLY@5501..5528 + EXPR_INDEX@5501..5515 + EXPR_VAR@5501..5504 + NAME@5501..5504 + IDENT@5501..5504 "std" + DOT@5504..5505 "." + NAME@5505..5515 + IDENT@5505..5515 "isFunction" + ARGS_DESC@5515..5528 + L_PAREN@5515..5516 "(" + ARG@5516..5527 + EXPR_VAR@5516..5527 + NAME@5516..5527 + IDENT@5516..5527 "filter_func" + R_PAREN@5527..5528 ")" + WHITESPACE@5528..5529 " " + THEN_KW@5529..5533 "then" + WHITESPACE@5533..5540 "\n " + TRUE_EXPR@5540..5622 + EXPR_ERROR@5540..5622 + ERROR_KW@5540..5545 "error" + WHITESPACE@5545..5546 " " + EXPR_PARENED@5546..5622 + L_PAREN@5546..5547 "(" + EXPR_BINARY@5547..5621 + LHS_EXPR@5547..5597 + EXPR_STRING@5547..5597 + STRING_SINGLE@5547..5597 "'std.filterMap first ..." + WHITESPACE@5597..5598 " " + PLUS@5598..5599 "+" + WHITESPACE@5599..5600 " " + EXPR_APPLY@5600..5621 + EXPR_INDEX@5600..5608 + EXPR_VAR@5600..5603 + NAME@5600..5603 + IDENT@5600..5603 "std" + DOT@5603..5604 "." + NAME@5604..5608 + IDENT@5604..5608 "type" + ARGS_DESC@5608..5621 + L_PAREN@5608..5609 "(" + ARG@5609..5620 + EXPR_VAR@5609..5620 + NAME@5609..5620 + IDENT@5609..5620 "filter_func" + R_PAREN@5620..5621 ")" + R_PAREN@5621..5622 ")" + WHITESPACE@5622..5627 "\n " + ELSE_KW@5627..5631 "else" + WHITESPACE@5631..5632 " " + FALSE_EXPR@5632..5928 + EXPR_IF_THEN_ELSE@5632..5928 + IF_KW@5632..5634 "if" + WHITESPACE@5634..5635 " " + EXPR_UNARY@5635..5660 + NOT@5635..5636 "!" + EXPR_APPLY@5636..5660 + EXPR_INDEX@5636..5650 + EXPR_VAR@5636..5639 + NAME@5636..5639 + IDENT@5636..5639 "std" + DOT@5639..5640 "." + NAME@5640..5650 + IDENT@5640..5650 "isFunction" + ARGS_DESC@5650..5660 + L_PAREN@5650..5651 "(" + ARG@5651..5659 + EXPR_VAR@5651..5659 + NAME@5651..5659 + IDENT@5651..5659 "map_func" + R_PAREN@5659..5660 ")" + WHITESPACE@5660..5661 " " + THEN_KW@5661..5665 "then" + WHITESPACE@5665..5672 "\n " + TRUE_EXPR@5672..5752 + EXPR_ERROR@5672..5752 + ERROR_KW@5672..5677 "error" + WHITESPACE@5677..5678 " " + EXPR_PARENED@5678..5752 + L_PAREN@5678..5679 "(" + EXPR_BINARY@5679..5751 + LHS_EXPR@5679..5730 + EXPR_STRING@5679..5730 + STRING_SINGLE@5679..5730 "'std.filterMap second ..." + WHITESPACE@5730..5731 " " + PLUS@5731..5732 "+" + WHITESPACE@5732..5733 " " + EXPR_APPLY@5733..5751 + EXPR_INDEX@5733..5741 + EXPR_VAR@5733..5736 + NAME@5733..5736 + IDENT@5733..5736 "std" + DOT@5736..5737 "." + NAME@5737..5741 + IDENT@5737..5741 "type" + ARGS_DESC@5741..5751 + L_PAREN@5741..5742 "(" + ARG@5742..5750 + EXPR_VAR@5742..5750 + NAME@5742..5750 + IDENT@5742..5750 "map_func" + R_PAREN@5750..5751 ")" + R_PAREN@5751..5752 ")" + WHITESPACE@5752..5757 "\n " + ELSE_KW@5757..5761 "else" + WHITESPACE@5761..5762 " " + FALSE_EXPR@5762..5928 + EXPR_IF_THEN_ELSE@5762..5928 + IF_KW@5762..5764 "if" + WHITESPACE@5764..5765 " " + EXPR_UNARY@5765..5782 + NOT@5765..5766 "!" + EXPR_APPLY@5766..5782 + EXPR_INDEX@5766..5777 + EXPR_VAR@5766..5769 + NAME@5766..5769 + IDENT@5766..5769 "std" + DOT@5769..5770 "." + NAME@5770..5777 + IDENT@5770..5777 "isArray" + ARGS_DESC@5777..5782 + L_PAREN@5777..5778 "(" + ARG@5778..5781 + EXPR_VAR@5778..5781 + NAME@5778..5781 + IDENT@5778..5781 "arr" + R_PAREN@5781..5782 ")" + WHITESPACE@5782..5783 " " + THEN_KW@5783..5787 "then" + WHITESPACE@5787..5794 "\n " + TRUE_EXPR@5794..5865 + EXPR_ERROR@5794..5865 + ERROR_KW@5794..5799 "error" + WHITESPACE@5799..5800 " " + EXPR_PARENED@5800..5865 + L_PAREN@5800..5801 "(" + EXPR_BINARY@5801..5864 + LHS_EXPR@5801..5848 + EXPR_STRING@5801..5848 + STRING_SINGLE@5801..5848 "'std.filterMap third ..." + WHITESPACE@5848..5849 " " + PLUS@5849..5850 "+" + WHITESPACE@5850..5851 " " + EXPR_APPLY@5851..5864 + EXPR_INDEX@5851..5859 + EXPR_VAR@5851..5854 + NAME@5851..5854 + IDENT@5851..5854 "std" + DOT@5854..5855 "." + NAME@5855..5859 + IDENT@5855..5859 "type" + ARGS_DESC@5859..5864 + L_PAREN@5859..5860 "(" + ARG@5860..5863 + EXPR_VAR@5860..5863 + NAME@5860..5863 + IDENT@5860..5863 "arr" + R_PAREN@5863..5864 ")" + R_PAREN@5864..5865 ")" + WHITESPACE@5865..5870 "\n " + ELSE_KW@5870..5874 "else" + WHITESPACE@5874..5881 "\n " + FALSE_EXPR@5881..5928 + EXPR_APPLY@5881..5928 + EXPR_INDEX@5881..5888 + EXPR_VAR@5881..5884 + NAME@5881..5884 + IDENT@5881..5884 "std" + DOT@5884..5885 "." + NAME@5885..5888 + IDENT@5885..5888 "map" + ARGS_DESC@5888..5928 + L_PAREN@5888..5889 "(" + ARG@5889..5897 + EXPR_VAR@5889..5897 + NAME@5889..5897 + IDENT@5889..5897 "map_func" + COMMA@5897..5898 "," + WHITESPACE@5898..5899 " " + ARG@5899..5927 + EXPR_APPLY@5899..5927 + EXPR_INDEX@5899..5909 + EXPR_VAR@5899..5902 + NAME@5899..5902 + IDENT@5899..5902 "std" + DOT@5902..5903 "." + NAME@5903..5909 + IDENT@5903..5909 "filter" + ARGS_DESC@5909..5927 + L_PAREN@5909..5910 "(" + ARG@5910..5921 + EXPR_VAR@5910..5921 + NAME@5910..5921 + IDENT@5910..5921 "filter_func" + COMMA@5921..5922 "," + WHITESPACE@5922..5923 " " + ARG@5923..5926 + EXPR_VAR@5923..5926 + NAME@5923..5926 + IDENT@5923..5926 "arr" + R_PAREN@5926..5927 ")" + R_PAREN@5927..5928 ")" + COMMA@5928..5929 "," + WHITESPACE@5929..5933 "\n\n " + MEMBER_FIELD@5933..6041 + FIELD_METHOD@5933..6041 + FIELD_NAME_FIXED@5933..5944 + NAME@5933..5944 + IDENT@5933..5944 "assertEqual" + PARAMS_DESC@5944..5950 + L_PAREN@5944..5945 "(" + PARAM@5945..5946 + DESTRUCT_FULL@5945..5946 + NAME@5945..5946 + IDENT@5945..5946 "a" + COMMA@5946..5947 "," + WHITESPACE@5947..5948 " " + PARAM@5948..5949 + DESTRUCT_FULL@5948..5949 + NAME@5948..5949 + IDENT@5948..5949 "b" + R_PAREN@5949..5950 ")" + COLONCOLON@5950..5952 "::" + WHITESPACE@5952..5957 "\n " + EXPR_IF_THEN_ELSE@5957..6041 + IF_KW@5957..5959 "if" + WHITESPACE@5959..5960 " " + EXPR_BINARY@5960..5966 + LHS_EXPR@5960..5961 + EXPR_VAR@5960..5961 + NAME@5960..5961 + IDENT@5960..5961 "a" + WHITESPACE@5961..5962 " " + EQ@5962..5964 "==" + WHITESPACE@5964..5965 " " + EXPR_VAR@5965..5966 + NAME@5965..5966 + IDENT@5965..5966 "b" + WHITESPACE@5966..5967 " " + THEN_KW@5967..5971 "then" + WHITESPACE@5971..5978 "\n " + TRUE_EXPR@5978..5982 + EXPR_LITERAL@5978..5982 + TRUE_KW@5978..5982 "true" + WHITESPACE@5982..5987 "\n " + ELSE_KW@5987..5991 "else" + WHITESPACE@5991..5998 "\n " + FALSE_EXPR@5998..6041 + EXPR_ERROR@5998..6041 + ERROR_KW@5998..6003 "error" + WHITESPACE@6003..6004 " " + EXPR_BINARY@6004..6041 + LHS_EXPR@6004..6037 + EXPR_BINARY@6004..6037 + LHS_EXPR@6004..6028 + EXPR_BINARY@6004..6028 + LHS_EXPR@6004..6024 + EXPR_STRING@6004..6024 + STRING_SINGLE@6004..6024 "'Assertion failed. '" + WHITESPACE@6024..6025 " " + PLUS@6025..6026 "+" + WHITESPACE@6026..6027 " " + EXPR_VAR@6027..6028 + NAME@6027..6028 + IDENT@6027..6028 "a" + WHITESPACE@6028..6029 " " + PLUS@6029..6030 "+" + WHITESPACE@6030..6031 " " + EXPR_STRING@6031..6037 + STRING_SINGLE@6031..6037 "' != '" + WHITESPACE@6037..6038 " " + PLUS@6038..6039 "+" + WHITESPACE@6039..6040 " " + EXPR_VAR@6040..6041 + NAME@6040..6041 + IDENT@6040..6041 "b" + COMMA@6041..6042 "," + WHITESPACE@6042..6046 "\n\n " + MEMBER_FIELD@6046..6180 + FIELD_METHOD@6046..6180 + FIELD_NAME_FIXED@6046..6049 + NAME@6046..6049 + IDENT@6046..6049 "abs" + PARAMS_DESC@6049..6052 + L_PAREN@6049..6050 "(" + PARAM@6050..6051 + DESTRUCT_FULL@6050..6051 + NAME@6050..6051 + IDENT@6050..6051 "n" + R_PAREN@6051..6052 ")" + COLONCOLON@6052..6054 "::" + WHITESPACE@6054..6059 "\n " + EXPR_IF_THEN_ELSE@6059..6180 + IF_KW@6059..6061 "if" + WHITESPACE@6061..6062 " " + EXPR_UNARY@6062..6078 + NOT@6062..6063 "!" + EXPR_APPLY@6063..6078 + EXPR_INDEX@6063..6075 + EXPR_VAR@6063..6066 + NAME@6063..6066 + IDENT@6063..6066 "std" + DOT@6066..6067 "." + NAME@6067..6075 + IDENT@6067..6075 "isNumber" + ARGS_DESC@6075..6078 + L_PAREN@6075..6076 "(" + ARG@6076..6077 + EXPR_VAR@6076..6077 + NAME@6076..6077 + IDENT@6076..6077 "n" + R_PAREN@6077..6078 ")" + WHITESPACE@6078..6079 " " + THEN_KW@6079..6083 "then" + WHITESPACE@6083..6090 "\n " + TRUE_EXPR@6090..6141 + EXPR_ERROR@6090..6141 + ERROR_KW@6090..6095 "error" + WHITESPACE@6095..6096 " " + EXPR_BINARY@6096..6141 + LHS_EXPR@6096..6127 + EXPR_STRING@6096..6127 + STRING_SINGLE@6096..6127 "'std.abs expected num ..." + WHITESPACE@6127..6128 " " + PLUS@6128..6129 "+" + WHITESPACE@6129..6130 " " + EXPR_APPLY@6130..6141 + EXPR_INDEX@6130..6138 + EXPR_VAR@6130..6133 + NAME@6130..6133 + IDENT@6130..6133 "std" + DOT@6133..6134 "." + NAME@6134..6138 + IDENT@6134..6138 "type" + ARGS_DESC@6138..6141 + L_PAREN@6138..6139 "(" + ARG@6139..6140 + EXPR_VAR@6139..6140 + NAME@6139..6140 + IDENT@6139..6140 "n" + R_PAREN@6140..6141 ")" + WHITESPACE@6141..6146 "\n " + ELSE_KW@6146..6150 "else" + WHITESPACE@6150..6157 "\n " + FALSE_EXPR@6157..6180 + EXPR_IF_THEN_ELSE@6157..6180 + IF_KW@6157..6159 "if" + WHITESPACE@6159..6160 " " + EXPR_BINARY@6160..6165 + LHS_EXPR@6160..6161 + EXPR_VAR@6160..6161 + NAME@6160..6161 + IDENT@6160..6161 "n" + WHITESPACE@6161..6162 " " + GT@6162..6163 ">" + WHITESPACE@6163..6164 " " + EXPR_NUMBER@6164..6165 + FLOAT@6164..6165 "0" + WHITESPACE@6165..6166 " " + THEN_KW@6166..6170 "then" + WHITESPACE@6170..6171 " " + TRUE_EXPR@6171..6172 + EXPR_VAR@6171..6172 + NAME@6171..6172 + IDENT@6171..6172 "n" + WHITESPACE@6172..6173 " " + ELSE_KW@6173..6177 "else" + WHITESPACE@6177..6178 " " + FALSE_EXPR@6178..6180 + EXPR_UNARY@6178..6180 + MINUS@6178..6179 "-" + EXPR_VAR@6179..6180 + NAME@6179..6180 + IDENT@6179..6180 "n" + COMMA@6180..6181 "," + WHITESPACE@6181..6185 "\n\n " + MEMBER_FIELD@6185..6370 + FIELD_METHOD@6185..6370 + FIELD_NAME_FIXED@6185..6189 + NAME@6185..6189 + IDENT@6185..6189 "sign" + PARAMS_DESC@6189..6192 + L_PAREN@6189..6190 "(" + PARAM@6190..6191 + DESTRUCT_FULL@6190..6191 + NAME@6190..6191 + IDENT@6190..6191 "n" + R_PAREN@6191..6192 ")" + COLONCOLON@6192..6194 "::" + WHITESPACE@6194..6199 "\n " + EXPR_IF_THEN_ELSE@6199..6370 + IF_KW@6199..6201 "if" + WHITESPACE@6201..6202 " " + EXPR_UNARY@6202..6218 + NOT@6202..6203 "!" + EXPR_APPLY@6203..6218 + EXPR_INDEX@6203..6215 + EXPR_VAR@6203..6206 + NAME@6203..6206 + IDENT@6203..6206 "std" + DOT@6206..6207 "." + NAME@6207..6215 + IDENT@6207..6215 "isNumber" + ARGS_DESC@6215..6218 + L_PAREN@6215..6216 "(" + ARG@6216..6217 + EXPR_VAR@6216..6217 + NAME@6216..6217 + IDENT@6216..6217 "n" + R_PAREN@6217..6218 ")" + WHITESPACE@6218..6219 " " + THEN_KW@6219..6223 "then" + WHITESPACE@6223..6230 "\n " + TRUE_EXPR@6230..6282 + EXPR_ERROR@6230..6282 + ERROR_KW@6230..6235 "error" + WHITESPACE@6235..6236 " " + EXPR_BINARY@6236..6282 + LHS_EXPR@6236..6268 + EXPR_STRING@6236..6268 + STRING_SINGLE@6236..6268 "'std.sign expected nu ..." + WHITESPACE@6268..6269 " " + PLUS@6269..6270 "+" + WHITESPACE@6270..6271 " " + EXPR_APPLY@6271..6282 + EXPR_INDEX@6271..6279 + EXPR_VAR@6271..6274 + NAME@6271..6274 + IDENT@6271..6274 "std" + DOT@6274..6275 "." + NAME@6275..6279 + IDENT@6275..6279 "type" + ARGS_DESC@6279..6282 + L_PAREN@6279..6280 "(" + ARG@6280..6281 + EXPR_VAR@6280..6281 + NAME@6280..6281 + IDENT@6280..6281 "n" + R_PAREN@6281..6282 ")" + WHITESPACE@6282..6287 "\n " + ELSE_KW@6287..6291 "else" + WHITESPACE@6291..6298 "\n " + FALSE_EXPR@6298..6370 + EXPR_IF_THEN_ELSE@6298..6370 + IF_KW@6298..6300 "if" + WHITESPACE@6300..6301 " " + EXPR_BINARY@6301..6306 + LHS_EXPR@6301..6302 + EXPR_VAR@6301..6302 + NAME@6301..6302 + IDENT@6301..6302 "n" + WHITESPACE@6302..6303 " " + GT@6303..6304 ">" + WHITESPACE@6304..6305 " " + EXPR_NUMBER@6305..6306 + FLOAT@6305..6306 "0" + WHITESPACE@6306..6307 " " + THEN_KW@6307..6311 "then" + WHITESPACE@6311..6320 "\n " + TRUE_EXPR@6320..6321 + EXPR_NUMBER@6320..6321 + FLOAT@6320..6321 "1" + WHITESPACE@6321..6328 "\n " + ELSE_KW@6328..6332 "else" + WHITESPACE@6332..6333 " " + FALSE_EXPR@6333..6370 + EXPR_IF_THEN_ELSE@6333..6370 + IF_KW@6333..6335 "if" + WHITESPACE@6335..6336 " " + EXPR_BINARY@6336..6341 + LHS_EXPR@6336..6337 + EXPR_VAR@6336..6337 + NAME@6336..6337 + IDENT@6336..6337 "n" + WHITESPACE@6337..6338 " " + LT@6338..6339 "<" + WHITESPACE@6339..6340 " " + EXPR_NUMBER@6340..6341 + FLOAT@6340..6341 "0" + WHITESPACE@6341..6342 " " + THEN_KW@6342..6346 "then" + WHITESPACE@6346..6355 "\n " + TRUE_EXPR@6355..6357 + EXPR_UNARY@6355..6357 + MINUS@6355..6356 "-" + EXPR_NUMBER@6356..6357 + FLOAT@6356..6357 "1" + WHITESPACE@6357..6364 "\n " + ELSE_KW@6364..6368 "else" + WHITESPACE@6368..6369 " " + FALSE_EXPR@6369..6370 + EXPR_NUMBER@6369..6370 + FLOAT@6369..6370 "0" + COMMA@6370..6371 "," + WHITESPACE@6371..6375 "\n\n " + MEMBER_FIELD@6375..6628 + FIELD_METHOD@6375..6628 + FIELD_NAME_FIXED@6375..6378 + NAME@6375..6378 + IDENT@6375..6378 "max" + PARAMS_DESC@6378..6384 + L_PAREN@6378..6379 "(" + PARAM@6379..6380 + DESTRUCT_FULL@6379..6380 + NAME@6379..6380 + IDENT@6379..6380 "a" + COMMA@6380..6381 "," + WHITESPACE@6381..6382 " " + PARAM@6382..6383 + DESTRUCT_FULL@6382..6383 + NAME@6382..6383 + IDENT@6382..6383 "b" + R_PAREN@6383..6384 ")" + COLONCOLON@6384..6386 "::" + WHITESPACE@6386..6391 "\n " + EXPR_IF_THEN_ELSE@6391..6628 + IF_KW@6391..6393 "if" + WHITESPACE@6393..6394 " " + EXPR_UNARY@6394..6410 + NOT@6394..6395 "!" + EXPR_APPLY@6395..6410 + EXPR_INDEX@6395..6407 + EXPR_VAR@6395..6398 + NAME@6395..6398 + IDENT@6395..6398 "std" + DOT@6398..6399 "." + NAME@6399..6407 + IDENT@6399..6407 "isNumber" + ARGS_DESC@6407..6410 + L_PAREN@6407..6408 "(" + ARG@6408..6409 + EXPR_VAR@6408..6409 + NAME@6408..6409 + IDENT@6408..6409 "a" + R_PAREN@6409..6410 ")" + WHITESPACE@6410..6411 " " + THEN_KW@6411..6415 "then" + WHITESPACE@6415..6422 "\n " + TRUE_EXPR@6422..6485 + EXPR_ERROR@6422..6485 + ERROR_KW@6422..6427 "error" + WHITESPACE@6427..6428 " " + EXPR_BINARY@6428..6485 + LHS_EXPR@6428..6471 + EXPR_STRING@6428..6471 + STRING_SINGLE@6428..6471 "'std.max first param ..." + WHITESPACE@6471..6472 " " + PLUS@6472..6473 "+" + WHITESPACE@6473..6474 " " + EXPR_APPLY@6474..6485 + EXPR_INDEX@6474..6482 + EXPR_VAR@6474..6477 + NAME@6474..6477 + IDENT@6474..6477 "std" + DOT@6477..6478 "." + NAME@6478..6482 + IDENT@6478..6482 "type" + ARGS_DESC@6482..6485 + L_PAREN@6482..6483 "(" + ARG@6483..6484 + EXPR_VAR@6483..6484 + NAME@6483..6484 + IDENT@6483..6484 "a" + R_PAREN@6484..6485 ")" + WHITESPACE@6485..6490 "\n " + ELSE_KW@6490..6494 "else" + WHITESPACE@6494..6495 " " + FALSE_EXPR@6495..6628 + EXPR_IF_THEN_ELSE@6495..6628 + IF_KW@6495..6497 "if" + WHITESPACE@6497..6498 " " + EXPR_UNARY@6498..6514 + NOT@6498..6499 "!" + EXPR_APPLY@6499..6514 + EXPR_INDEX@6499..6511 + EXPR_VAR@6499..6502 + NAME@6499..6502 + IDENT@6499..6502 "std" + DOT@6502..6503 "." + NAME@6503..6511 + IDENT@6503..6511 "isNumber" + ARGS_DESC@6511..6514 + L_PAREN@6511..6512 "(" + ARG@6512..6513 + EXPR_VAR@6512..6513 + NAME@6512..6513 + IDENT@6512..6513 "b" + R_PAREN@6513..6514 ")" + WHITESPACE@6514..6515 " " + THEN_KW@6515..6519 "then" + WHITESPACE@6519..6526 "\n " + TRUE_EXPR@6526..6590 + EXPR_ERROR@6526..6590 + ERROR_KW@6526..6531 "error" + WHITESPACE@6531..6532 " " + EXPR_BINARY@6532..6590 + LHS_EXPR@6532..6576 + EXPR_STRING@6532..6576 + STRING_SINGLE@6532..6576 "'std.max second param ..." + WHITESPACE@6576..6577 " " + PLUS@6577..6578 "+" + WHITESPACE@6578..6579 " " + EXPR_APPLY@6579..6590 + EXPR_INDEX@6579..6587 + EXPR_VAR@6579..6582 + NAME@6579..6582 + IDENT@6579..6582 "std" + DOT@6582..6583 "." + NAME@6583..6587 + IDENT@6583..6587 "type" + ARGS_DESC@6587..6590 + L_PAREN@6587..6588 "(" + ARG@6588..6589 + EXPR_VAR@6588..6589 + NAME@6588..6589 + IDENT@6588..6589 "b" + R_PAREN@6589..6590 ")" + WHITESPACE@6590..6595 "\n " + ELSE_KW@6595..6599 "else" + WHITESPACE@6599..6606 "\n " + FALSE_EXPR@6606..6628 + EXPR_IF_THEN_ELSE@6606..6628 + IF_KW@6606..6608 "if" + WHITESPACE@6608..6609 " " + EXPR_BINARY@6609..6614 + LHS_EXPR@6609..6610 + EXPR_VAR@6609..6610 + NAME@6609..6610 + IDENT@6609..6610 "a" + WHITESPACE@6610..6611 " " + GT@6611..6612 ">" + WHITESPACE@6612..6613 " " + EXPR_VAR@6613..6614 + NAME@6613..6614 + IDENT@6613..6614 "b" + WHITESPACE@6614..6615 " " + THEN_KW@6615..6619 "then" + WHITESPACE@6619..6620 " " + TRUE_EXPR@6620..6621 + EXPR_VAR@6620..6621 + NAME@6620..6621 + IDENT@6620..6621 "a" + WHITESPACE@6621..6622 " " + ELSE_KW@6622..6626 "else" + WHITESPACE@6626..6627 " " + FALSE_EXPR@6627..6628 + EXPR_VAR@6627..6628 + NAME@6627..6628 + IDENT@6627..6628 "b" + COMMA@6628..6629 "," + WHITESPACE@6629..6633 "\n\n " + MEMBER_FIELD@6633..6886 + FIELD_METHOD@6633..6886 + FIELD_NAME_FIXED@6633..6636 + NAME@6633..6636 + IDENT@6633..6636 "min" + PARAMS_DESC@6636..6642 + L_PAREN@6636..6637 "(" + PARAM@6637..6638 + DESTRUCT_FULL@6637..6638 + NAME@6637..6638 + IDENT@6637..6638 "a" + COMMA@6638..6639 "," + WHITESPACE@6639..6640 " " + PARAM@6640..6641 + DESTRUCT_FULL@6640..6641 + NAME@6640..6641 + IDENT@6640..6641 "b" + R_PAREN@6641..6642 ")" + COLONCOLON@6642..6644 "::" + WHITESPACE@6644..6649 "\n " + EXPR_IF_THEN_ELSE@6649..6886 + IF_KW@6649..6651 "if" + WHITESPACE@6651..6652 " " + EXPR_UNARY@6652..6668 + NOT@6652..6653 "!" + EXPR_APPLY@6653..6668 + EXPR_INDEX@6653..6665 + EXPR_VAR@6653..6656 + NAME@6653..6656 + IDENT@6653..6656 "std" + DOT@6656..6657 "." + NAME@6657..6665 + IDENT@6657..6665 "isNumber" + ARGS_DESC@6665..6668 + L_PAREN@6665..6666 "(" + ARG@6666..6667 + EXPR_VAR@6666..6667 + NAME@6666..6667 + IDENT@6666..6667 "a" + R_PAREN@6667..6668 ")" + WHITESPACE@6668..6669 " " + THEN_KW@6669..6673 "then" + WHITESPACE@6673..6680 "\n " + TRUE_EXPR@6680..6743 + EXPR_ERROR@6680..6743 + ERROR_KW@6680..6685 "error" + WHITESPACE@6685..6686 " " + EXPR_BINARY@6686..6743 + LHS_EXPR@6686..6729 + EXPR_STRING@6686..6729 + STRING_SINGLE@6686..6729 "'std.min first param ..." + WHITESPACE@6729..6730 " " + PLUS@6730..6731 "+" + WHITESPACE@6731..6732 " " + EXPR_APPLY@6732..6743 + EXPR_INDEX@6732..6740 + EXPR_VAR@6732..6735 + NAME@6732..6735 + IDENT@6732..6735 "std" + DOT@6735..6736 "." + NAME@6736..6740 + IDENT@6736..6740 "type" + ARGS_DESC@6740..6743 + L_PAREN@6740..6741 "(" + ARG@6741..6742 + EXPR_VAR@6741..6742 + NAME@6741..6742 + IDENT@6741..6742 "a" + R_PAREN@6742..6743 ")" + WHITESPACE@6743..6748 "\n " + ELSE_KW@6748..6752 "else" + WHITESPACE@6752..6753 " " + FALSE_EXPR@6753..6886 + EXPR_IF_THEN_ELSE@6753..6886 + IF_KW@6753..6755 "if" + WHITESPACE@6755..6756 " " + EXPR_UNARY@6756..6772 + NOT@6756..6757 "!" + EXPR_APPLY@6757..6772 + EXPR_INDEX@6757..6769 + EXPR_VAR@6757..6760 + NAME@6757..6760 + IDENT@6757..6760 "std" + DOT@6760..6761 "." + NAME@6761..6769 + IDENT@6761..6769 "isNumber" + ARGS_DESC@6769..6772 + L_PAREN@6769..6770 "(" + ARG@6770..6771 + EXPR_VAR@6770..6771 + NAME@6770..6771 + IDENT@6770..6771 "b" + R_PAREN@6771..6772 ")" + WHITESPACE@6772..6773 " " + THEN_KW@6773..6777 "then" + WHITESPACE@6777..6784 "\n " + TRUE_EXPR@6784..6848 + EXPR_ERROR@6784..6848 + ERROR_KW@6784..6789 "error" + WHITESPACE@6789..6790 " " + EXPR_BINARY@6790..6848 + LHS_EXPR@6790..6834 + EXPR_STRING@6790..6834 + STRING_SINGLE@6790..6834 "'std.min second param ..." + WHITESPACE@6834..6835 " " + PLUS@6835..6836 "+" + WHITESPACE@6836..6837 " " + EXPR_APPLY@6837..6848 + EXPR_INDEX@6837..6845 + EXPR_VAR@6837..6840 + NAME@6837..6840 + IDENT@6837..6840 "std" + DOT@6840..6841 "." + NAME@6841..6845 + IDENT@6841..6845 "type" + ARGS_DESC@6845..6848 + L_PAREN@6845..6846 "(" + ARG@6846..6847 + EXPR_VAR@6846..6847 + NAME@6846..6847 + IDENT@6846..6847 "b" + R_PAREN@6847..6848 ")" + WHITESPACE@6848..6853 "\n " + ELSE_KW@6853..6857 "else" + WHITESPACE@6857..6864 "\n " + FALSE_EXPR@6864..6886 + EXPR_IF_THEN_ELSE@6864..6886 + IF_KW@6864..6866 "if" + WHITESPACE@6866..6867 " " + EXPR_BINARY@6867..6872 + LHS_EXPR@6867..6868 + EXPR_VAR@6867..6868 + NAME@6867..6868 + IDENT@6867..6868 "a" + WHITESPACE@6868..6869 " " + LT@6869..6870 "<" + WHITESPACE@6870..6871 " " + EXPR_VAR@6871..6872 + NAME@6871..6872 + IDENT@6871..6872 "b" + WHITESPACE@6872..6873 " " + THEN_KW@6873..6877 "then" + WHITESPACE@6877..6878 " " + TRUE_EXPR@6878..6879 + EXPR_VAR@6878..6879 + NAME@6878..6879 + IDENT@6878..6879 "a" + WHITESPACE@6879..6880 " " + ELSE_KW@6880..6884 "else" + WHITESPACE@6884..6885 " " + FALSE_EXPR@6885..6886 + EXPR_VAR@6885..6886 + NAME@6885..6886 + IDENT@6885..6886 "b" + COMMA@6886..6887 "," + WHITESPACE@6887..6891 "\n\n " + MEMBER_FIELD@6891..6993 + FIELD_METHOD@6891..6993 + FIELD_NAME_FIXED@6891..6896 + NAME@6891..6896 + IDENT@6891..6896 "clamp" + PARAMS_DESC@6896..6915 + L_PAREN@6896..6897 "(" + PARAM@6897..6898 + DESTRUCT_FULL@6897..6898 + NAME@6897..6898 + IDENT@6897..6898 "x" + COMMA@6898..6899 "," + WHITESPACE@6899..6900 " " + PARAM@6900..6906 + DESTRUCT_FULL@6900..6906 + NAME@6900..6906 + IDENT@6900..6906 "minVal" + COMMA@6906..6907 "," + WHITESPACE@6907..6908 " " + PARAM@6908..6914 + DESTRUCT_FULL@6908..6914 + NAME@6908..6914 + IDENT@6908..6914 "maxVal" + R_PAREN@6914..6915 ")" + COLONCOLON@6915..6917 "::" + WHITESPACE@6917..6922 "\n " + EXPR_IF_THEN_ELSE@6922..6993 + IF_KW@6922..6924 "if" + WHITESPACE@6924..6925 " " + EXPR_BINARY@6925..6935 + LHS_EXPR@6925..6926 + EXPR_VAR@6925..6926 + NAME@6925..6926 + IDENT@6925..6926 "x" + WHITESPACE@6926..6927 " " + LT@6927..6928 "<" + WHITESPACE@6928..6929 " " + EXPR_VAR@6929..6935 + NAME@6929..6935 + IDENT@6929..6935 "minVal" + WHITESPACE@6935..6936 " " + THEN_KW@6936..6940 "then" + WHITESPACE@6940..6941 " " + TRUE_EXPR@6941..6947 + EXPR_VAR@6941..6947 + NAME@6941..6947 + IDENT@6941..6947 "minVal" + WHITESPACE@6947..6952 "\n " + ELSE_KW@6952..6956 "else" + WHITESPACE@6956..6957 " " + FALSE_EXPR@6957..6993 + EXPR_IF_THEN_ELSE@6957..6993 + IF_KW@6957..6959 "if" + WHITESPACE@6959..6960 " " + EXPR_BINARY@6960..6970 + LHS_EXPR@6960..6961 + EXPR_VAR@6960..6961 + NAME@6960..6961 + IDENT@6960..6961 "x" + WHITESPACE@6961..6962 " " + GT@6962..6963 ">" + WHITESPACE@6963..6964 " " + EXPR_VAR@6964..6970 + NAME@6964..6970 + IDENT@6964..6970 "maxVal" + WHITESPACE@6970..6971 " " + THEN_KW@6971..6975 "then" + WHITESPACE@6975..6976 " " + TRUE_EXPR@6976..6982 + EXPR_VAR@6976..6982 + NAME@6976..6982 + IDENT@6976..6982 "maxVal" + WHITESPACE@6982..6987 "\n " + ELSE_KW@6987..6991 "else" + WHITESPACE@6991..6992 " " + FALSE_EXPR@6992..6993 + EXPR_VAR@6992..6993 + NAME@6992..6993 + IDENT@6992..6993 "x" + COMMA@6993..6994 "," + WHITESPACE@6994..6998 "\n\n " + MEMBER_FIELD@6998..7065 + FIELD_METHOD@6998..7065 + FIELD_NAME_FIXED@6998..7011 + NAME@6998..7011 + IDENT@6998..7011 "flattenArrays" + PARAMS_DESC@7011..7017 + L_PAREN@7011..7012 "(" + PARAM@7012..7016 + DESTRUCT_FULL@7012..7016 + NAME@7012..7016 + IDENT@7012..7016 "arrs" + R_PAREN@7016..7017 ")" + COLONCOLON@7017..7019 "::" + WHITESPACE@7019..7024 "\n " + EXPR_APPLY@7024..7065 + EXPR_INDEX@7024..7033 + EXPR_VAR@7024..7027 + NAME@7024..7027 + IDENT@7024..7027 "std" + DOT@7027..7028 "." + NAME@7028..7033 + IDENT@7028..7033 "foldl" + ARGS_DESC@7033..7065 + L_PAREN@7033..7034 "(" + ARG@7034..7054 + EXPR_FUNCTION@7034..7054 + FUNCTION_KW@7034..7042 "function" + PARAMS_DESC@7042..7048 + L_PAREN@7042..7043 "(" + PARAM@7043..7044 + DESTRUCT_FULL@7043..7044 + NAME@7043..7044 + IDENT@7043..7044 "a" + COMMA@7044..7045 "," + WHITESPACE@7045..7046 " " + PARAM@7046..7047 + DESTRUCT_FULL@7046..7047 + NAME@7046..7047 + IDENT@7046..7047 "b" + R_PAREN@7047..7048 ")" + WHITESPACE@7048..7049 " " + EXPR_BINARY@7049..7054 + LHS_EXPR@7049..7050 + EXPR_VAR@7049..7050 + NAME@7049..7050 + IDENT@7049..7050 "a" + WHITESPACE@7050..7051 " " + PLUS@7051..7052 "+" + WHITESPACE@7052..7053 " " + EXPR_VAR@7053..7054 + NAME@7053..7054 + IDENT@7053..7054 "b" + COMMA@7054..7055 "," + WHITESPACE@7055..7056 " " + ARG@7056..7060 + EXPR_VAR@7056..7060 + NAME@7056..7060 + IDENT@7056..7060 "arrs" + COMMA@7060..7061 "," + WHITESPACE@7061..7062 " " + ARG@7062..7064 + EXPR_ARRAY@7062..7064 + L_BRACK@7062..7063 "[" + R_BRACK@7063..7064 "]" + R_PAREN@7064..7065 ")" + COMMA@7065..7066 "," + WHITESPACE@7066..7070 "\n\n " + MEMBER_FIELD@7070..7756 + FIELD_METHOD@7070..7756 + FIELD_NAME_FIXED@7070..7081 + NAME@7070..7081 + IDENT@7070..7081 "manifestIni" + PARAMS_DESC@7081..7086 + L_PAREN@7081..7082 "(" + PARAM@7082..7085 + DESTRUCT_FULL@7082..7085 + NAME@7082..7085 + IDENT@7082..7085 "ini" + R_PAREN@7085..7086 ")" + COLONCOLON@7086..7088 "::" + WHITESPACE@7088..7093 "\n " + EXPR_LOCAL@7093..7756 + LOCAL_KW@7093..7098 "local" + WHITESPACE@7098..7099 " " + BIND_FUNCTION@7099..7396 + NAME@7099..7109 + IDENT@7099..7109 "body_lines" + PARAMS_DESC@7109..7115 + L_PAREN@7109..7110 "(" + PARAM@7110..7114 + DESTRUCT_FULL@7110..7114 + NAME@7110..7114 + IDENT@7110..7114 "body" + R_PAREN@7114..7115 ")" + WHITESPACE@7115..7116 " " + ASSIGN@7116..7117 "=" + WHITESPACE@7117..7124 "\n " + EXPR_APPLY@7124..7396 + EXPR_INDEX@7124..7132 + EXPR_VAR@7124..7127 + NAME@7124..7127 + IDENT@7124..7127 "std" + DOT@7127..7128 "." + NAME@7128..7132 + IDENT@7128..7132 "join" + ARGS_DESC@7132..7396 + L_PAREN@7132..7133 "(" + ARG@7133..7135 + EXPR_ARRAY@7133..7135 + L_BRACK@7133..7134 "[" + R_BRACK@7134..7135 "]" + COMMA@7135..7136 "," + WHITESPACE@7136..7137 " " + ARG@7137..7395 + EXPR_ARRAY_COMP@7137..7395 + L_BRACK@7137..7138 "[" + WHITESPACE@7138..7147 "\n " + EXPR_LOCAL@7147..7346 + LOCAL_KW@7147..7152 "local" + WHITESPACE@7152..7153 " " + BIND_DESTRUCT@7153..7178 + DESTRUCT_FULL@7153..7168 + NAME@7153..7168 + IDENT@7153..7168 "value_or_values" + WHITESPACE@7168..7169 " " + ASSIGN@7169..7170 "=" + WHITESPACE@7170..7171 " " + EXPR_INDEX_EXPR@7171..7178 + LHS_EXPR@7171..7175 + EXPR_VAR@7171..7175 + NAME@7171..7175 + IDENT@7171..7175 "body" + L_BRACK@7175..7176 "[" + EXPR_VAR@7176..7177 + NAME@7176..7177 + IDENT@7176..7177 "k" + R_BRACK@7177..7178 "]" + SEMI@7178..7179 ";" + WHITESPACE@7179..7188 "\n " + EXPR_IF_THEN_ELSE@7188..7346 + IF_KW@7188..7190 "if" + WHITESPACE@7190..7191 " " + EXPR_APPLY@7191..7219 + EXPR_INDEX@7191..7202 + EXPR_VAR@7191..7194 + NAME@7191..7194 + IDENT@7191..7194 "std" + DOT@7194..7195 "." + NAME@7195..7202 + IDENT@7195..7202 "isArray" + ARGS_DESC@7202..7219 + L_PAREN@7202..7203 "(" + ARG@7203..7218 + EXPR_VAR@7203..7218 + NAME@7203..7218 + IDENT@7203..7218 "value_or_values" + R_PAREN@7218..7219 ")" + WHITESPACE@7219..7220 " " + THEN_KW@7220..7224 "then" + WHITESPACE@7224..7235 "\n " + TRUE_EXPR@7235..7288 + EXPR_ARRAY_COMP@7235..7288 + L_BRACK@7235..7236 "[" + EXPR_BINARY@7236..7258 + LHS_EXPR@7236..7245 + EXPR_STRING@7236..7245 + STRING_SINGLE@7236..7245 "'%s = %s'" + WHITESPACE@7245..7246 " " + MODULO@7246..7247 "%" + WHITESPACE@7247..7248 " " + EXPR_ARRAY@7248..7258 + L_BRACK@7248..7249 "[" + EXPR_VAR@7249..7250 + NAME@7249..7250 + IDENT@7249..7250 "k" + COMMA@7250..7251 "," + WHITESPACE@7251..7252 " " + EXPR_VAR@7252..7257 + NAME@7252..7257 + IDENT@7252..7257 "value" + R_BRACK@7257..7258 "]" + WHITESPACE@7258..7259 " " + FOR_SPEC@7259..7287 + FOR_KW@7259..7262 "for" + WHITESPACE@7262..7263 " " + NAME@7263..7268 + IDENT@7263..7268 "value" + WHITESPACE@7268..7269 " " + IN_KW@7269..7271 "in" + WHITESPACE@7271..7272 " " + EXPR_VAR@7272..7287 + NAME@7272..7287 + IDENT@7272..7287 "value_or_values" + R_BRACK@7287..7288 "]" + WHITESPACE@7288..7297 "\n " + ELSE_KW@7297..7301 "else" + WHITESPACE@7301..7312 "\n " + FALSE_EXPR@7312..7346 + EXPR_ARRAY@7312..7346 + L_BRACK@7312..7313 "[" + EXPR_BINARY@7313..7345 + LHS_EXPR@7313..7322 + EXPR_STRING@7313..7322 + STRING_SINGLE@7313..7322 "'%s = %s'" + WHITESPACE@7322..7323 " " + MODULO@7323..7324 "%" + WHITESPACE@7324..7325 " " + EXPR_ARRAY@7325..7345 + L_BRACK@7325..7326 "[" + EXPR_VAR@7326..7327 + NAME@7326..7327 + IDENT@7326..7327 "k" + COMMA@7327..7328 "," + WHITESPACE@7328..7329 " " + EXPR_VAR@7329..7344 + NAME@7329..7344 + IDENT@7329..7344 "value_or_values" + R_BRACK@7344..7345 "]" + R_BRACK@7345..7346 "]" + WHITESPACE@7346..7356 "\n\n " + FOR_SPEC@7356..7387 + FOR_KW@7356..7359 "for" + WHITESPACE@7359..7360 " " + NAME@7360..7361 + IDENT@7360..7361 "k" + WHITESPACE@7361..7362 " " + IN_KW@7362..7364 "in" + WHITESPACE@7364..7365 " " + EXPR_APPLY@7365..7387 + EXPR_INDEX@7365..7381 + EXPR_VAR@7365..7368 + NAME@7365..7368 + IDENT@7365..7368 "std" + DOT@7368..7369 "." + NAME@7369..7381 + IDENT@7369..7381 "objectFields" + ARGS_DESC@7381..7387 + L_PAREN@7381..7382 "(" + ARG@7382..7386 + EXPR_VAR@7382..7386 + NAME@7382..7386 + IDENT@7382..7386 "body" + R_PAREN@7386..7387 ")" + WHITESPACE@7387..7394 "\n " + R_BRACK@7394..7395 "]" + R_PAREN@7395..7396 ")" + SEMI@7396..7397 ";" + WHITESPACE@7397..7403 "\n\n " + EXPR_LOCAL@7403..7756 + LOCAL_KW@7403..7408 "local" + WHITESPACE@7408..7409 " " + BIND_FUNCTION@7409..7477 + NAME@7409..7422 + IDENT@7409..7422 "section_lines" + PARAMS_DESC@7422..7436 + L_PAREN@7422..7423 "(" + PARAM@7423..7428 + DESTRUCT_FULL@7423..7428 + NAME@7423..7428 + IDENT@7423..7428 "sname" + COMMA@7428..7429 "," + WHITESPACE@7429..7430 " " + PARAM@7430..7435 + DESTRUCT_FULL@7430..7435 + NAME@7430..7435 + IDENT@7430..7435 "sbody" + R_PAREN@7435..7436 ")" + WHITESPACE@7436..7437 " " + ASSIGN@7437..7438 "=" + WHITESPACE@7438..7439 " " + EXPR_BINARY@7439..7477 + LHS_EXPR@7439..7457 + EXPR_ARRAY@7439..7457 + L_BRACK@7439..7440 "[" + EXPR_BINARY@7440..7456 + LHS_EXPR@7440..7446 + EXPR_STRING@7440..7446 + STRING_SINGLE@7440..7446 "'[%s]'" + WHITESPACE@7446..7447 " " + MODULO@7447..7448 "%" + WHITESPACE@7448..7449 " " + EXPR_ARRAY@7449..7456 + L_BRACK@7449..7450 "[" + EXPR_VAR@7450..7455 + NAME@7450..7455 + IDENT@7450..7455 "sname" + R_BRACK@7455..7456 "]" + R_BRACK@7456..7457 "]" + WHITESPACE@7457..7458 " " + PLUS@7458..7459 "+" + WHITESPACE@7459..7460 " " + EXPR_APPLY@7460..7477 + EXPR_VAR@7460..7470 + NAME@7460..7470 + IDENT@7460..7470 "body_lines" + ARGS_DESC@7470..7477 + L_PAREN@7470..7471 "(" + ARG@7471..7476 + EXPR_VAR@7471..7476 + NAME@7471..7476 + IDENT@7471..7476 "sbody" + R_PAREN@7476..7477 ")" + COMMA@7477..7478 "," + WHITESPACE@7478..7489 "\n " + BIND_DESTRUCT@7489..7564 + DESTRUCT_FULL@7489..7498 + NAME@7489..7498 + IDENT@7489..7498 "main_body" + WHITESPACE@7498..7499 " " + ASSIGN@7499..7500 "=" + WHITESPACE@7500..7501 " " + EXPR_IF_THEN_ELSE@7501..7564 + IF_KW@7501..7503 "if" + WHITESPACE@7503..7504 " " + EXPR_APPLY@7504..7530 + EXPR_INDEX@7504..7517 + EXPR_VAR@7504..7507 + NAME@7504..7507 + IDENT@7504..7507 "std" + DOT@7507..7508 "." + NAME@7508..7517 + IDENT@7508..7517 "objectHas" + ARGS_DESC@7517..7530 + L_PAREN@7517..7518 "(" + ARG@7518..7521 + EXPR_VAR@7518..7521 + NAME@7518..7521 + IDENT@7518..7521 "ini" + COMMA@7521..7522 "," + WHITESPACE@7522..7523 " " + ARG@7523..7529 + EXPR_STRING@7523..7529 + STRING_SINGLE@7523..7529 "'main'" + R_PAREN@7529..7530 ")" + WHITESPACE@7530..7531 " " + THEN_KW@7531..7535 "then" + WHITESPACE@7535..7536 " " + TRUE_EXPR@7536..7556 + EXPR_APPLY@7536..7556 + EXPR_VAR@7536..7546 + NAME@7536..7546 + IDENT@7536..7546 "body_lines" + ARGS_DESC@7546..7556 + L_PAREN@7546..7547 "(" + ARG@7547..7555 + EXPR_INDEX@7547..7555 + EXPR_VAR@7547..7550 + NAME@7547..7550 + IDENT@7547..7550 "ini" + DOT@7550..7551 "." + NAME@7551..7555 + IDENT@7551..7555 "main" + R_PAREN@7555..7556 ")" + WHITESPACE@7556..7557 " " + ELSE_KW@7557..7561 "else" + WHITESPACE@7561..7562 " " + FALSE_EXPR@7562..7564 + EXPR_ARRAY@7562..7564 + L_BRACK@7562..7563 "[" + R_BRACK@7563..7564 "]" + COMMA@7564..7565 "," + WHITESPACE@7565..7576 "\n " + BIND_DESTRUCT@7576..7684 + DESTRUCT_FULL@7576..7588 + NAME@7576..7588 + IDENT@7576..7588 "all_sections" + WHITESPACE@7588..7589 " " + ASSIGN@7589..7590 "=" + WHITESPACE@7590..7591 " " + EXPR_ARRAY_COMP@7591..7684 + L_BRACK@7591..7592 "[" + WHITESPACE@7592..7599 "\n " + EXPR_APPLY@7599..7632 + EXPR_VAR@7599..7612 + NAME@7599..7612 + IDENT@7599..7612 "section_lines" + ARGS_DESC@7612..7632 + L_PAREN@7612..7613 "(" + ARG@7613..7614 + EXPR_VAR@7613..7614 + NAME@7613..7614 + IDENT@7613..7614 "k" + COMMA@7614..7615 "," + WHITESPACE@7615..7616 " " + ARG@7616..7631 + EXPR_INDEX_EXPR@7616..7631 + LHS_EXPR@7616..7628 + EXPR_INDEX@7616..7628 + EXPR_VAR@7616..7619 + NAME@7616..7619 + IDENT@7616..7619 "ini" + DOT@7619..7620 "." + NAME@7620..7628 + IDENT@7620..7628 "sections" + L_BRACK@7628..7629 "[" + EXPR_VAR@7629..7630 + NAME@7629..7630 + IDENT@7629..7630 "k" + R_BRACK@7630..7631 "]" + R_PAREN@7631..7632 ")" + WHITESPACE@7632..7639 "\n " + FOR_SPEC@7639..7678 + FOR_KW@7639..7642 "for" + WHITESPACE@7642..7643 " " + NAME@7643..7644 + IDENT@7643..7644 "k" + WHITESPACE@7644..7645 " " + IN_KW@7645..7647 "in" + WHITESPACE@7647..7648 " " + EXPR_APPLY@7648..7678 + EXPR_INDEX@7648..7664 + EXPR_VAR@7648..7651 + NAME@7648..7651 + IDENT@7648..7651 "std" + DOT@7651..7652 "." + NAME@7652..7664 + IDENT@7652..7664 "objectFields" + ARGS_DESC@7664..7678 + L_PAREN@7664..7665 "(" + ARG@7665..7677 + EXPR_INDEX@7665..7677 + EXPR_VAR@7665..7668 + NAME@7665..7668 + IDENT@7665..7668 "ini" + DOT@7668..7669 "." + NAME@7669..7677 + IDENT@7669..7677 "sections" + R_PAREN@7677..7678 ")" + WHITESPACE@7678..7683 "\n " + R_BRACK@7683..7684 "]" + SEMI@7684..7685 ";" + WHITESPACE@7685..7690 "\n " + EXPR_APPLY@7690..7756 + EXPR_INDEX@7690..7698 + EXPR_VAR@7690..7693 + NAME@7690..7693 + IDENT@7690..7693 "std" + DOT@7693..7694 "." + NAME@7694..7698 + IDENT@7694..7698 "join" + ARGS_DESC@7698..7756 + L_PAREN@7698..7699 "(" + ARG@7699..7703 + EXPR_STRING@7699..7703 + STRING_SINGLE@7699..7703 "'\\n'" + COMMA@7703..7704 "," + WHITESPACE@7704..7705 " " + ARG@7705..7755 + EXPR_BINARY@7705..7755 + LHS_EXPR@7705..7748 + EXPR_BINARY@7705..7748 + LHS_EXPR@7705..7714 + EXPR_VAR@7705..7714 + NAME@7705..7714 + IDENT@7705..7714 "main_body" + WHITESPACE@7714..7715 " " + PLUS@7715..7716 "+" + WHITESPACE@7716..7717 " " + EXPR_APPLY@7717..7748 + EXPR_INDEX@7717..7734 + EXPR_VAR@7717..7720 + NAME@7717..7720 + IDENT@7717..7720 "std" + DOT@7720..7721 "." + NAME@7721..7734 + IDENT@7721..7734 "flattenArrays" + ARGS_DESC@7734..7748 + L_PAREN@7734..7735 "(" + ARG@7735..7747 + EXPR_VAR@7735..7747 + NAME@7735..7747 + IDENT@7735..7747 "all_sections" + R_PAREN@7747..7748 ")" + WHITESPACE@7748..7749 " " + PLUS@7749..7750 "+" + WHITESPACE@7750..7751 " " + EXPR_ARRAY@7751..7755 + L_BRACK@7751..7752 "[" + EXPR_STRING@7752..7754 + STRING_SINGLE@7752..7754 "''" + R_BRACK@7754..7755 "]" + R_PAREN@7755..7756 ")" + COMMA@7756..7757 "," + WHITESPACE@7757..7761 "\n\n " + MEMBER_FIELD@7761..7814 + FIELD_METHOD@7761..7814 + FIELD_NAME_FIXED@7761..7773 + NAME@7761..7773 + IDENT@7761..7773 "manifestToml" + PARAMS_DESC@7773..7780 + L_PAREN@7773..7774 "(" + PARAM@7774..7779 + DESTRUCT_FULL@7774..7779 + NAME@7774..7779 + IDENT@7774..7779 "value" + R_PAREN@7779..7780 ")" + COLONCOLON@7780..7782 "::" + WHITESPACE@7782..7783 " " + EXPR_APPLY@7783..7814 + EXPR_INDEX@7783..7801 + EXPR_VAR@7783..7786 + NAME@7783..7786 + IDENT@7783..7786 "std" + DOT@7786..7787 "." + NAME@7787..7801 + IDENT@7787..7801 "manifestTomlEx" + ARGS_DESC@7801..7814 + L_PAREN@7801..7802 "(" + ARG@7802..7807 + EXPR_VAR@7802..7807 + NAME@7802..7807 + IDENT@7802..7807 "value" + COMMA@7807..7808 "," + WHITESPACE@7808..7809 " " + ARG@7809..7813 + EXPR_STRING@7809..7813 + STRING_SINGLE@7809..7813 "' '" + R_PAREN@7813..7814 ")" + COMMA@7814..7815 "," + WHITESPACE@7815..7819 "\n\n " + MEMBER_FIELD@7819..11476 + FIELD_METHOD@7819..11476 + FIELD_NAME_FIXED@7819..7833 + NAME@7819..7833 + IDENT@7819..7833 "manifestTomlEx" + PARAMS_DESC@7833..7848 + L_PAREN@7833..7834 "(" + PARAM@7834..7839 + DESTRUCT_FULL@7834..7839 + NAME@7834..7839 + IDENT@7834..7839 "value" + COMMA@7839..7840 "," + WHITESPACE@7840..7841 " " + PARAM@7841..7847 + DESTRUCT_FULL@7841..7847 + NAME@7841..7847 + IDENT@7841..7847 "indent" + R_PAREN@7847..7848 ")" + COLONCOLON@7848..7850 "::" + WHITESPACE@7850..7855 "\n " + EXPR_LOCAL@7855..11476 + LOCAL_KW@7855..7860 "local" + WHITESPACE@7860..7867 "\n " + BIND_DESTRUCT@7867..7906 + DESTRUCT_FULL@7867..7883 + NAME@7867..7883 + IDENT@7867..7883 "escapeStringToml" + WHITESPACE@7883..7884 " " + ASSIGN@7884..7885 "=" + WHITESPACE@7885..7886 " " + EXPR_INDEX@7886..7906 + EXPR_VAR@7886..7889 + NAME@7886..7889 + IDENT@7886..7889 "std" + DOT@7889..7890 "." + NAME@7890..7906 + IDENT@7890..7906 "escapeStringJson" + COMMA@7906..7907 "," + WHITESPACE@7907..7914 "\n " + BIND_FUNCTION@7914..8178 + NAME@7914..7927 + IDENT@7914..7927 "escapeKeyToml" + PARAMS_DESC@7927..7932 + L_PAREN@7927..7928 "(" + PARAM@7928..7931 + DESTRUCT_FULL@7928..7931 + NAME@7928..7931 + IDENT@7928..7931 "key" + R_PAREN@7931..7932 ")" + WHITESPACE@7932..7933 " " + ASSIGN@7933..7934 "=" + WHITESPACE@7934..7943 "\n " + EXPR_LOCAL@7943..8178 + LOCAL_KW@7943..7948 "local" + WHITESPACE@7948..7949 " " + BIND_DESTRUCT@7949..8056 + DESTRUCT_FULL@7949..7961 + NAME@7949..7961 + IDENT@7949..7961 "bare_allowed" + WHITESPACE@7961..7962 " " + ASSIGN@7962..7963 "=" + WHITESPACE@7963..7964 " " + EXPR_APPLY@7964..8056 + EXPR_INDEX@7964..7971 + EXPR_VAR@7964..7967 + NAME@7964..7967 + IDENT@7964..7967 "std" + DOT@7967..7968 "." + NAME@7968..7971 + IDENT@7968..7971 "set" + ARGS_DESC@7971..8056 + L_PAREN@7971..7972 "(" + ARG@7972..8055 + EXPR_APPLY@7972..8055 + EXPR_INDEX@7972..7987 + EXPR_VAR@7972..7975 + NAME@7972..7975 + IDENT@7972..7975 "std" + DOT@7975..7976 "." + NAME@7976..7987 + IDENT@7976..7987 "stringChars" + ARGS_DESC@7987..8055 + L_PAREN@7987..7988 "(" + ARG@7988..8054 + EXPR_STRING@7988..8054 + STRING_SINGLE@7988..8054 "'ABCDEFGHIJKLMNOPQRST ..." + R_PAREN@8054..8055 ")" + R_PAREN@8055..8056 ")" + SEMI@8056..8057 ";" + WHITESPACE@8057..8066 "\n " + EXPR_IF_THEN_ELSE@8066..8178 + IF_KW@8066..8068 "if" + WHITESPACE@8068..8069 " " + EXPR_BINARY@8069..8142 + LHS_EXPR@8069..8126 + EXPR_APPLY@8069..8126 + EXPR_INDEX@8069..8081 + EXPR_VAR@8069..8072 + NAME@8069..8072 + IDENT@8069..8072 "std" + DOT@8072..8073 "." + NAME@8073..8081 + IDENT@8073..8081 "setUnion" + ARGS_DESC@8081..8126 + L_PAREN@8081..8082 "(" + ARG@8082..8111 + EXPR_APPLY@8082..8111 + EXPR_INDEX@8082..8089 + EXPR_VAR@8082..8085 + NAME@8082..8085 + IDENT@8082..8085 "std" + DOT@8085..8086 "." + NAME@8086..8089 + IDENT@8086..8089 "set" + ARGS_DESC@8089..8111 + L_PAREN@8089..8090 "(" + ARG@8090..8110 + EXPR_APPLY@8090..8110 + EXPR_INDEX@8090..8105 + EXPR_VAR@8090..8093 + NAME@8090..8093 + IDENT@8090..8093 "std" + DOT@8093..8094 "." + NAME@8094..8105 + IDENT@8094..8105 "stringChars" + ARGS_DESC@8105..8110 + L_PAREN@8105..8106 "(" + ARG@8106..8109 + EXPR_VAR@8106..8109 + NAME@8106..8109 + IDENT@8106..8109 "key" + R_PAREN@8109..8110 ")" + R_PAREN@8110..8111 ")" + COMMA@8111..8112 "," + WHITESPACE@8112..8113 " " + ARG@8113..8125 + EXPR_VAR@8113..8125 + NAME@8113..8125 + IDENT@8113..8125 "bare_allowed" + R_PAREN@8125..8126 ")" + WHITESPACE@8126..8127 " " + EQ@8127..8129 "==" + WHITESPACE@8129..8130 " " + EXPR_VAR@8130..8142 + NAME@8130..8142 + IDENT@8130..8142 "bare_allowed" + WHITESPACE@8142..8143 " " + THEN_KW@8143..8147 "then" + WHITESPACE@8147..8148 " " + TRUE_EXPR@8148..8151 + EXPR_VAR@8148..8151 + NAME@8148..8151 + IDENT@8148..8151 "key" + WHITESPACE@8151..8152 " " + ELSE_KW@8152..8156 "else" + WHITESPACE@8156..8157 " " + FALSE_EXPR@8157..8178 + EXPR_APPLY@8157..8178 + EXPR_VAR@8157..8173 + NAME@8157..8173 + IDENT@8157..8173 "escapeStringToml" + ARGS_DESC@8173..8178 + L_PAREN@8173..8174 "(" + ARG@8174..8177 + EXPR_VAR@8174..8177 + NAME@8174..8177 + IDENT@8174..8177 "key" + R_PAREN@8177..8178 ")" + COMMA@8178..8179 "," + WHITESPACE@8179..8186 "\n " + BIND_FUNCTION@8186..8298 + NAME@8186..8198 + IDENT@8186..8198 "isTableArray" + PARAMS_DESC@8198..8201 + L_PAREN@8198..8199 "(" + PARAM@8199..8200 + DESTRUCT_FULL@8199..8200 + NAME@8199..8200 + IDENT@8199..8200 "v" + R_PAREN@8200..8201 ")" + WHITESPACE@8201..8202 " " + ASSIGN@8202..8203 "=" + WHITESPACE@8203..8204 " " + EXPR_BINARY@8204..8298 + LHS_EXPR@8204..8239 + EXPR_BINARY@8204..8239 + LHS_EXPR@8204..8218 + EXPR_APPLY@8204..8218 + EXPR_INDEX@8204..8215 + EXPR_VAR@8204..8207 + NAME@8204..8207 + IDENT@8204..8207 "std" + DOT@8207..8208 "." + NAME@8208..8215 + IDENT@8208..8215 "isArray" + ARGS_DESC@8215..8218 + L_PAREN@8215..8216 "(" + ARG@8216..8217 + EXPR_VAR@8216..8217 + NAME@8216..8217 + IDENT@8216..8217 "v" + R_PAREN@8217..8218 ")" + WHITESPACE@8218..8219 " " + AND@8219..8221 "&&" + WHITESPACE@8221..8222 " " + EXPR_BINARY@8222..8239 + LHS_EXPR@8222..8235 + EXPR_APPLY@8222..8235 + EXPR_INDEX@8222..8232 + EXPR_VAR@8222..8225 + NAME@8222..8225 + IDENT@8222..8225 "std" + DOT@8225..8226 "." + NAME@8226..8232 + IDENT@8226..8232 "length" + ARGS_DESC@8232..8235 + L_PAREN@8232..8233 "(" + ARG@8233..8234 + EXPR_VAR@8233..8234 + NAME@8233..8234 + IDENT@8233..8234 "v" + R_PAREN@8234..8235 ")" + WHITESPACE@8235..8236 " " + GT@8236..8237 ">" + WHITESPACE@8237..8238 " " + EXPR_NUMBER@8238..8239 + FLOAT@8238..8239 "0" + WHITESPACE@8239..8240 " " + AND@8240..8242 "&&" + WHITESPACE@8242..8243 " " + EXPR_APPLY@8243..8298 + EXPR_INDEX@8243..8252 + EXPR_VAR@8243..8246 + NAME@8243..8246 + IDENT@8243..8246 "std" + DOT@8246..8247 "." + NAME@8247..8252 + IDENT@8247..8252 "foldl" + ARGS_DESC@8252..8298 + L_PAREN@8252..8253 "(" + ARG@8253..8288 + EXPR_FUNCTION@8253..8288 + FUNCTION_KW@8253..8261 "function" + PARAMS_DESC@8261..8267 + L_PAREN@8261..8262 "(" + PARAM@8262..8263 + DESTRUCT_FULL@8262..8263 + NAME@8262..8263 + IDENT@8262..8263 "a" + COMMA@8263..8264 "," + WHITESPACE@8264..8265 " " + PARAM@8265..8266 + DESTRUCT_FULL@8265..8266 + NAME@8265..8266 + IDENT@8265..8266 "b" + R_PAREN@8266..8267 ")" + WHITESPACE@8267..8268 " " + EXPR_BINARY@8268..8288 + LHS_EXPR@8268..8269 + EXPR_VAR@8268..8269 + NAME@8268..8269 + IDENT@8268..8269 "a" + WHITESPACE@8269..8270 " " + AND@8270..8272 "&&" + WHITESPACE@8272..8273 " " + EXPR_APPLY@8273..8288 + EXPR_INDEX@8273..8285 + EXPR_VAR@8273..8276 + NAME@8273..8276 + IDENT@8273..8276 "std" + DOT@8276..8277 "." + NAME@8277..8285 + IDENT@8277..8285 "isObject" + ARGS_DESC@8285..8288 + L_PAREN@8285..8286 "(" + ARG@8286..8287 + EXPR_VAR@8286..8287 + NAME@8286..8287 + IDENT@8286..8287 "b" + R_PAREN@8287..8288 ")" + COMMA@8288..8289 "," + WHITESPACE@8289..8290 " " + ARG@8290..8291 + EXPR_VAR@8290..8291 + NAME@8290..8291 + IDENT@8290..8291 "v" + COMMA@8291..8292 "," + WHITESPACE@8292..8293 " " + ARG@8293..8297 + EXPR_LITERAL@8293..8297 + TRUE_KW@8293..8297 "true" + R_PAREN@8297..8298 ")" + COMMA@8298..8299 "," + WHITESPACE@8299..8306 "\n " + BIND_FUNCTION@8306..8355 + NAME@8306..8315 + IDENT@8306..8315 "isSection" + PARAMS_DESC@8315..8318 + L_PAREN@8315..8316 "(" + PARAM@8316..8317 + DESTRUCT_FULL@8316..8317 + NAME@8316..8317 + IDENT@8316..8317 "v" + R_PAREN@8317..8318 ")" + WHITESPACE@8318..8319 " " + ASSIGN@8319..8320 "=" + WHITESPACE@8320..8321 " " + EXPR_BINARY@8321..8355 + LHS_EXPR@8321..8336 + EXPR_APPLY@8321..8336 + EXPR_INDEX@8321..8333 + EXPR_VAR@8321..8324 + NAME@8321..8324 + IDENT@8321..8324 "std" + DOT@8324..8325 "." + NAME@8325..8333 + IDENT@8325..8333 "isObject" + ARGS_DESC@8333..8336 + L_PAREN@8333..8334 "(" + ARG@8334..8335 + EXPR_VAR@8334..8335 + NAME@8334..8335 + IDENT@8334..8335 "v" + R_PAREN@8335..8336 ")" + WHITESPACE@8336..8337 " " + OR@8337..8339 "||" + WHITESPACE@8339..8340 " " + EXPR_APPLY@8340..8355 + EXPR_VAR@8340..8352 + NAME@8340..8352 + IDENT@8340..8352 "isTableArray" + ARGS_DESC@8352..8355 + L_PAREN@8352..8353 "(" + ARG@8353..8354 + EXPR_VAR@8353..8354 + NAME@8353..8354 + IDENT@8353..8354 "v" + R_PAREN@8354..8355 ")" + COMMA@8355..8356 "," + WHITESPACE@8356..8363 "\n " + BIND_FUNCTION@8363..9990 + NAME@8363..8374 + IDENT@8363..8374 "renderValue" + PARAMS_DESC@8374..8407 + L_PAREN@8374..8375 "(" + PARAM@8375..8376 + DESTRUCT_FULL@8375..8376 + NAME@8375..8376 + IDENT@8375..8376 "v" + COMMA@8376..8377 "," + WHITESPACE@8377..8378 " " + PARAM@8378..8389 + DESTRUCT_FULL@8378..8389 + NAME@8378..8389 + IDENT@8378..8389 "indexedPath" + COMMA@8389..8390 "," + WHITESPACE@8390..8391 " " + PARAM@8391..8397 + DESTRUCT_FULL@8391..8397 + NAME@8391..8397 + IDENT@8391..8397 "inline" + COMMA@8397..8398 "," + WHITESPACE@8398..8399 " " + PARAM@8399..8406 + DESTRUCT_FULL@8399..8406 + NAME@8399..8406 + IDENT@8399..8406 "cindent" + R_PAREN@8406..8407 ")" + WHITESPACE@8407..8408 " " + ASSIGN@8408..8409 "=" + WHITESPACE@8409..8418 "\n " + EXPR_IF_THEN_ELSE@8418..9990 + IF_KW@8418..8420 "if" + WHITESPACE@8420..8421 " " + EXPR_BINARY@8421..8430 + LHS_EXPR@8421..8422 + EXPR_VAR@8421..8422 + NAME@8421..8422 + IDENT@8421..8422 "v" + WHITESPACE@8422..8423 " " + EQ@8423..8425 "==" + WHITESPACE@8425..8426 " " + EXPR_LITERAL@8426..8430 + TRUE_KW@8426..8430 "true" + WHITESPACE@8430..8431 " " + THEN_KW@8431..8435 "then" + WHITESPACE@8435..8446 "\n " + TRUE_EXPR@8446..8452 + EXPR_STRING@8446..8452 + STRING_SINGLE@8446..8452 "'true'" + WHITESPACE@8452..8461 "\n " + ELSE_KW@8461..8465 "else" + WHITESPACE@8465..8466 " " + FALSE_EXPR@8466..9990 + EXPR_IF_THEN_ELSE@8466..9990 + IF_KW@8466..8468 "if" + WHITESPACE@8468..8469 " " + EXPR_BINARY@8469..8479 + LHS_EXPR@8469..8470 + EXPR_VAR@8469..8470 + NAME@8469..8470 + IDENT@8469..8470 "v" + WHITESPACE@8470..8471 " " + EQ@8471..8473 "==" + WHITESPACE@8473..8474 " " + EXPR_LITERAL@8474..8479 + FALSE_KW@8474..8479 "false" + WHITESPACE@8479..8480 " " + THEN_KW@8480..8484 "then" + WHITESPACE@8484..8495 "\n " + TRUE_EXPR@8495..8502 + EXPR_STRING@8495..8502 + STRING_SINGLE@8495..8502 "'false'" + WHITESPACE@8502..8511 "\n " + ELSE_KW@8511..8515 "else" + WHITESPACE@8515..8516 " " + FALSE_EXPR@8516..9990 + EXPR_IF_THEN_ELSE@8516..9990 + IF_KW@8516..8518 "if" + WHITESPACE@8518..8519 " " + EXPR_BINARY@8519..8528 + LHS_EXPR@8519..8520 + EXPR_VAR@8519..8520 + NAME@8519..8520 + IDENT@8519..8520 "v" + WHITESPACE@8520..8521 " " + EQ@8521..8523 "==" + WHITESPACE@8523..8524 " " + EXPR_LITERAL@8524..8528 + NULL_KW@8524..8528 "null" + WHITESPACE@8528..8529 " " + THEN_KW@8529..8533 "then" + WHITESPACE@8533..8544 "\n " + TRUE_EXPR@8544..8594 + EXPR_ERROR@8544..8594 + ERROR_KW@8544..8549 "error" + WHITESPACE@8549..8550 " " + EXPR_BINARY@8550..8594 + LHS_EXPR@8550..8580 + EXPR_STRING@8550..8580 + STRING_SINGLE@8550..8580 "'Tried to manifest \"n ..." + WHITESPACE@8580..8581 " " + PLUS@8581..8582 "+" + WHITESPACE@8582..8583 " " + EXPR_VAR@8583..8594 + NAME@8583..8594 + IDENT@8583..8594 "indexedPath" + WHITESPACE@8594..8603 "\n " + ELSE_KW@8603..8607 "else" + WHITESPACE@8607..8608 " " + FALSE_EXPR@8608..9990 + EXPR_IF_THEN_ELSE@8608..9990 + IF_KW@8608..8610 "if" + WHITESPACE@8610..8611 " " + EXPR_APPLY@8611..8626 + EXPR_INDEX@8611..8623 + EXPR_VAR@8611..8614 + NAME@8611..8614 + IDENT@8611..8614 "std" + DOT@8614..8615 "." + NAME@8615..8623 + IDENT@8615..8623 "isNumber" + ARGS_DESC@8623..8626 + L_PAREN@8623..8624 "(" + ARG@8624..8625 + EXPR_VAR@8624..8625 + NAME@8624..8625 + IDENT@8624..8625 "v" + R_PAREN@8625..8626 ")" + WHITESPACE@8626..8627 " " + THEN_KW@8627..8631 "then" + WHITESPACE@8631..8642 "\n " + TRUE_EXPR@8642..8648 + EXPR_BINARY@8642..8648 + LHS_EXPR@8642..8644 + EXPR_STRING@8642..8644 + STRING_SINGLE@8642..8644 "''" + WHITESPACE@8644..8645 " " + PLUS@8645..8646 "+" + WHITESPACE@8646..8647 " " + EXPR_VAR@8647..8648 + NAME@8647..8648 + IDENT@8647..8648 "v" + WHITESPACE@8648..8657 "\n " + ELSE_KW@8657..8661 "else" + WHITESPACE@8661..8662 " " + FALSE_EXPR@8662..9990 + EXPR_IF_THEN_ELSE@8662..9990 + IF_KW@8662..8664 "if" + WHITESPACE@8664..8665 " " + EXPR_APPLY@8665..8680 + EXPR_INDEX@8665..8677 + EXPR_VAR@8665..8668 + NAME@8665..8668 + IDENT@8665..8668 "std" + DOT@8668..8669 "." + NAME@8669..8677 + IDENT@8669..8677 "isString" + ARGS_DESC@8677..8680 + L_PAREN@8677..8678 "(" + ARG@8678..8679 + EXPR_VAR@8678..8679 + NAME@8678..8679 + IDENT@8678..8679 "v" + R_PAREN@8679..8680 ")" + WHITESPACE@8680..8681 " " + THEN_KW@8681..8685 "then" + WHITESPACE@8685..8696 "\n " + TRUE_EXPR@8696..8715 + EXPR_APPLY@8696..8715 + EXPR_VAR@8696..8712 + NAME@8696..8712 + IDENT@8696..8712 "escapeStringToml" + ARGS_DESC@8712..8715 + L_PAREN@8712..8713 "(" + ARG@8713..8714 + EXPR_VAR@8713..8714 + NAME@8713..8714 + IDENT@8713..8714 "v" + R_PAREN@8714..8715 ")" + WHITESPACE@8715..8724 "\n " + ELSE_KW@8724..8728 "else" + WHITESPACE@8728..8729 " " + FALSE_EXPR@8729..9990 + EXPR_IF_THEN_ELSE@8729..9990 + IF_KW@8729..8731 "if" + WHITESPACE@8731..8732 " " + EXPR_APPLY@8732..8749 + EXPR_INDEX@8732..8746 + EXPR_VAR@8732..8735 + NAME@8732..8735 + IDENT@8732..8735 "std" + DOT@8735..8736 "." + NAME@8736..8746 + IDENT@8736..8746 "isFunction" + ARGS_DESC@8746..8749 + L_PAREN@8746..8747 "(" + ARG@8747..8748 + EXPR_VAR@8747..8748 + NAME@8747..8748 + IDENT@8747..8748 "v" + R_PAREN@8748..8749 ")" + WHITESPACE@8749..8750 " " + THEN_KW@8750..8754 "then" + WHITESPACE@8754..8765 "\n " + TRUE_EXPR@8765..8817 + EXPR_ERROR@8765..8817 + ERROR_KW@8765..8770 "error" + WHITESPACE@8770..8771 " " + EXPR_BINARY@8771..8817 + LHS_EXPR@8771..8803 + EXPR_STRING@8771..8803 + STRING_SINGLE@8771..8803 "'Tried to manifest fu ..." + WHITESPACE@8803..8804 " " + PLUS@8804..8805 "+" + WHITESPACE@8805..8806 " " + EXPR_VAR@8806..8817 + NAME@8806..8817 + IDENT@8806..8817 "indexedPath" + WHITESPACE@8817..8826 "\n " + ELSE_KW@8826..8830 "else" + WHITESPACE@8830..8831 " " + FALSE_EXPR@8831..9990 + EXPR_IF_THEN_ELSE@8831..9990 + IF_KW@8831..8833 "if" + WHITESPACE@8833..8834 " " + EXPR_APPLY@8834..8848 + EXPR_INDEX@8834..8845 + EXPR_VAR@8834..8837 + NAME@8834..8837 + IDENT@8834..8837 "std" + DOT@8837..8838 "." + NAME@8838..8845 + IDENT@8838..8845 "isArray" + ARGS_DESC@8845..8848 + L_PAREN@8845..8846 "(" + ARG@8846..8847 + EXPR_VAR@8846..8847 + NAME@8846..8847 + IDENT@8846..8847 "v" + R_PAREN@8847..8848 ")" + WHITESPACE@8848..8849 " " + THEN_KW@8849..8853 "then" + WHITESPACE@8853..8864 "\n " + TRUE_EXPR@8864..9561 + EXPR_IF_THEN_ELSE@8864..9561 + IF_KW@8864..8866 "if" + WHITESPACE@8866..8867 " " + EXPR_BINARY@8867..8885 + LHS_EXPR@8867..8880 + EXPR_APPLY@8867..8880 + EXPR_INDEX@8867..8877 + EXPR_VAR@8867..8870 + NAME@8867..8870 + IDENT@8867..8870 "std" + DOT@8870..8871 "." + NAME@8871..8877 + IDENT@8871..8877 "length" + ARGS_DESC@8877..8880 + L_PAREN@8877..8878 "(" + ARG@8878..8879 + EXPR_VAR@8878..8879 + NAME@8878..8879 + IDENT@8878..8879 "v" + R_PAREN@8879..8880 ")" + WHITESPACE@8880..8881 " " + EQ@8881..8883 "==" + WHITESPACE@8883..8884 " " + EXPR_NUMBER@8884..8885 + FLOAT@8884..8885 "0" + WHITESPACE@8885..8886 " " + THEN_KW@8886..8890 "then" + WHITESPACE@8890..8903 "\n " + TRUE_EXPR@8903..8907 + EXPR_STRING@8903..8907 + STRING_SINGLE@8903..8907 "'[]'" + WHITESPACE@8907..8918 "\n " + ELSE_KW@8918..8922 "else" + WHITESPACE@8922..8935 "\n " + FALSE_EXPR@8935..9561 + EXPR_LOCAL@8935..9561 + LOCAL_KW@8935..8940 "local" + WHITESPACE@8940..8941 " " + BIND_DESTRUCT@8941..8980 + DESTRUCT_FULL@8941..8946 + NAME@8941..8946 + IDENT@8941..8946 "range" + WHITESPACE@8946..8947 " " + ASSIGN@8947..8948 "=" + WHITESPACE@8948..8949 " " + EXPR_APPLY@8949..8980 + EXPR_INDEX@8949..8958 + EXPR_VAR@8949..8952 + NAME@8949..8952 + IDENT@8949..8952 "std" + DOT@8952..8953 "." + NAME@8953..8958 + IDENT@8953..8958 "range" + ARGS_DESC@8958..8980 + L_PAREN@8958..8959 "(" + ARG@8959..8960 + EXPR_NUMBER@8959..8960 + FLOAT@8959..8960 "0" + COMMA@8960..8961 "," + WHITESPACE@8961..8962 " " + ARG@8962..8979 + EXPR_BINARY@8962..8979 + LHS_EXPR@8962..8975 + EXPR_APPLY@8962..8975 + EXPR_INDEX@8962..8972 + EXPR_VAR@8962..8965 + NAME@8962..8965 + IDENT@8962..8965 "std" + DOT@8965..8966 "." + NAME@8966..8972 + IDENT@8966..8972 "length" + ARGS_DESC@8972..8975 + L_PAREN@8972..8973 "(" + ARG@8973..8974 + EXPR_VAR@8973..8974 + NAME@8973..8974 + IDENT@8973..8974 "v" + R_PAREN@8974..8975 ")" + WHITESPACE@8975..8976 " " + MINUS@8976..8977 "-" + WHITESPACE@8977..8978 " " + EXPR_NUMBER@8978..8979 + FLOAT@8978..8979 "1" + R_PAREN@8979..8980 ")" + SEMI@8980..8981 ";" + WHITESPACE@8981..8994 "\n " + EXPR_LOCAL@8994..9561 + LOCAL_KW@8994..8999 "local" + WHITESPACE@8999..9000 " " + BIND_DESTRUCT@9000..9052 + DESTRUCT_FULL@9000..9010 + NAME@9000..9010 + IDENT@9000..9010 "new_indent" + WHITESPACE@9010..9011 " " + ASSIGN@9011..9012 "=" + WHITESPACE@9012..9013 " " + EXPR_IF_THEN_ELSE@9013..9052 + IF_KW@9013..9015 "if" + WHITESPACE@9015..9016 " " + EXPR_VAR@9016..9022 + NAME@9016..9022 + IDENT@9016..9022 "inline" + WHITESPACE@9022..9023 " " + THEN_KW@9023..9027 "then" + WHITESPACE@9027..9028 " " + TRUE_EXPR@9028..9030 + EXPR_STRING@9028..9030 + STRING_SINGLE@9028..9030 "''" + WHITESPACE@9030..9031 " " + ELSE_KW@9031..9035 "else" + WHITESPACE@9035..9036 " " + FALSE_EXPR@9036..9052 + EXPR_BINARY@9036..9052 + LHS_EXPR@9036..9043 + EXPR_VAR@9036..9043 + NAME@9036..9043 + IDENT@9036..9043 "cindent" + WHITESPACE@9043..9044 " " + PLUS@9044..9045 "+" + WHITESPACE@9045..9046 " " + EXPR_VAR@9046..9052 + NAME@9046..9052 + IDENT@9046..9052 "indent" + SEMI@9052..9053 ";" + WHITESPACE@9053..9066 "\n " + EXPR_LOCAL@9066..9561 + LOCAL_KW@9066..9071 "local" + WHITESPACE@9071..9072 " " + BIND_DESTRUCT@9072..9112 + DESTRUCT_FULL@9072..9081 + NAME@9072..9081 + IDENT@9072..9081 "separator" + WHITESPACE@9081..9082 " " + ASSIGN@9082..9083 "=" + WHITESPACE@9083..9084 " " + EXPR_IF_THEN_ELSE@9084..9112 + IF_KW@9084..9086 "if" + WHITESPACE@9086..9087 " " + EXPR_VAR@9087..9093 + NAME@9087..9093 + IDENT@9087..9093 "inline" + WHITESPACE@9093..9094 " " + THEN_KW@9094..9098 "then" + WHITESPACE@9098..9099 " " + TRUE_EXPR@9099..9102 + EXPR_STRING@9099..9102 + STRING_SINGLE@9099..9102 "' '" + WHITESPACE@9102..9103 " " + ELSE_KW@9103..9107 "else" + WHITESPACE@9107..9108 " " + FALSE_EXPR@9108..9112 + EXPR_STRING@9108..9112 + STRING_SINGLE@9108..9112 "'\\n'" + SEMI@9112..9113 ";" + WHITESPACE@9113..9126 "\n " + EXPR_LOCAL@9126..9561 + LOCAL_KW@9126..9131 "local" + WHITESPACE@9131..9132 " " + BIND_DESTRUCT@9132..9528 + DESTRUCT_FULL@9132..9137 + NAME@9132..9137 + IDENT@9132..9137 "lines" + WHITESPACE@9137..9138 " " + ASSIGN@9138..9139 "=" + WHITESPACE@9139..9140 " " + EXPR_BINARY@9140..9528 + LHS_EXPR@9140..9447 + EXPR_BINARY@9140..9447 + LHS_EXPR@9140..9157 + EXPR_ARRAY@9140..9157 + L_BRACK@9140..9141 "[" + EXPR_BINARY@9141..9156 + LHS_EXPR@9141..9144 + EXPR_STRING@9141..9144 + STRING_SINGLE@9141..9144 "'['" + WHITESPACE@9144..9145 " " + PLUS@9145..9146 "+" + WHITESPACE@9146..9147 " " + EXPR_VAR@9147..9156 + NAME@9147..9156 + IDENT@9147..9156 "separator" + R_BRACK@9156..9157 "]" + WHITESPACE@9157..9184 "\n ..." + PLUS@9184..9185 "+" + WHITESPACE@9185..9186 " " + EXPR_APPLY@9186..9447 + EXPR_INDEX@9186..9194 + EXPR_VAR@9186..9189 + NAME@9186..9189 + IDENT@9186..9189 "std" + DOT@9189..9190 "." + NAME@9190..9194 + IDENT@9190..9194 "join" + ARGS_DESC@9194..9447 + L_PAREN@9194..9195 "(" + ARG@9195..9212 + EXPR_ARRAY@9195..9212 + L_BRACK@9195..9196 "[" + EXPR_BINARY@9196..9211 + LHS_EXPR@9196..9199 + EXPR_STRING@9196..9199 + STRING_SINGLE@9196..9199 "','" + WHITESPACE@9199..9200 " " + PLUS@9200..9201 "+" + WHITESPACE@9201..9202 " " + EXPR_VAR@9202..9211 + NAME@9202..9211 + IDENT@9202..9211 "separator" + R_BRACK@9211..9212 "]" + COMMA@9212..9213 "," + WHITESPACE@9213..9251 "\n ..." + ARG@9251..9446 + EXPR_ARRAY_COMP@9251..9446 + L_BRACK@9251..9252 "[" + WHITESPACE@9252..9292 "\n ..." + EXPR_ARRAY@9292..9353 + L_BRACK@9292..9293 "[" + EXPR_BINARY@9293..9352 + LHS_EXPR@9293..9303 + EXPR_VAR@9293..9303 + NAME@9293..9303 + IDENT@9293..9303 "new_indent" + WHITESPACE@9303..9304 " " + PLUS@9304..9305 "+" + WHITESPACE@9305..9306 " " + EXPR_APPLY@9306..9352 + EXPR_VAR@9306..9317 + NAME@9306..9317 + IDENT@9306..9317 "renderValue" + ARGS_DESC@9317..9352 + L_PAREN@9317..9318 "(" + ARG@9318..9322 + EXPR_INDEX_EXPR@9318..9322 + LHS_EXPR@9318..9319 + EXPR_VAR@9318..9319 + NAME@9318..9319 + IDENT@9318..9319 "v" + L_BRACK@9319..9320 "[" + EXPR_VAR@9320..9321 + NAME@9320..9321 + IDENT@9320..9321 "i" + R_BRACK@9321..9322 "]" + COMMA@9322..9323 "," + WHITESPACE@9323..9324 " " + ARG@9324..9341 + EXPR_BINARY@9324..9341 + LHS_EXPR@9324..9335 + EXPR_VAR@9324..9335 + NAME@9324..9335 + IDENT@9324..9335 "indexedPath" + WHITESPACE@9335..9336 " " + PLUS@9336..9337 "+" + WHITESPACE@9337..9338 " " + EXPR_ARRAY@9338..9341 + L_BRACK@9338..9339 "[" + EXPR_VAR@9339..9340 + NAME@9339..9340 + IDENT@9339..9340 "i" + R_BRACK@9340..9341 "]" + COMMA@9341..9342 "," + WHITESPACE@9342..9343 " " + ARG@9343..9347 + EXPR_LITERAL@9343..9347 + TRUE_KW@9343..9347 "true" + COMMA@9347..9348 "," + WHITESPACE@9348..9349 " " + ARG@9349..9351 + EXPR_STRING@9349..9351 + STRING_SINGLE@9349..9351 "''" + R_PAREN@9351..9352 ")" + R_BRACK@9352..9353 "]" + WHITESPACE@9353..9393 "\n ..." + FOR_SPEC@9393..9407 + FOR_KW@9393..9396 "for" + WHITESPACE@9396..9397 " " + NAME@9397..9398 + IDENT@9397..9398 "i" + WHITESPACE@9398..9399 " " + IN_KW@9399..9401 "in" + WHITESPACE@9401..9402 " " + EXPR_VAR@9402..9407 + NAME@9402..9407 + IDENT@9402..9407 "range" + WHITESPACE@9407..9445 "\n ..." + R_BRACK@9445..9446 "]" + R_PAREN@9446..9447 ")" + WHITESPACE@9447..9474 "\n ..." + PLUS@9474..9475 "+" + WHITESPACE@9475..9476 " " + EXPR_ARRAY@9476..9528 + L_BRACK@9476..9477 "[" + EXPR_BINARY@9477..9527 + LHS_EXPR@9477..9521 + EXPR_BINARY@9477..9521 + LHS_EXPR@9477..9486 + EXPR_VAR@9477..9486 + NAME@9477..9486 + IDENT@9477..9486 "separator" + WHITESPACE@9486..9487 " " + PLUS@9487..9488 "+" + WHITESPACE@9488..9489 " " + EXPR_PARENED@9489..9521 + L_PAREN@9489..9490 "(" + EXPR_IF_THEN_ELSE@9490..9520 + IF_KW@9490..9492 "if" + WHITESPACE@9492..9493 " " + EXPR_VAR@9493..9499 + NAME@9493..9499 + IDENT@9493..9499 "inline" + WHITESPACE@9499..9500 " " + THEN_KW@9500..9504 "then" + WHITESPACE@9504..9505 " " + TRUE_EXPR@9505..9507 + EXPR_STRING@9505..9507 + STRING_SINGLE@9505..9507 "''" + WHITESPACE@9507..9508 " " + ELSE_KW@9508..9512 "else" + WHITESPACE@9512..9513 " " + FALSE_EXPR@9513..9520 + EXPR_VAR@9513..9520 + NAME@9513..9520 + IDENT@9513..9520 "cindent" + R_PAREN@9520..9521 ")" + WHITESPACE@9521..9522 " " + PLUS@9522..9523 "+" + WHITESPACE@9523..9524 " " + EXPR_STRING@9524..9527 + STRING_SINGLE@9524..9527 "']'" + R_BRACK@9527..9528 "]" + SEMI@9528..9529 ";" + WHITESPACE@9529..9542 "\n " + EXPR_APPLY@9542..9561 + EXPR_INDEX@9542..9550 + EXPR_VAR@9542..9545 + NAME@9542..9545 + IDENT@9542..9545 "std" + DOT@9545..9546 "." + NAME@9546..9550 + IDENT@9546..9550 "join" + ARGS_DESC@9550..9561 + L_PAREN@9550..9551 "(" + ARG@9551..9553 + EXPR_STRING@9551..9553 + STRING_SINGLE@9551..9553 "''" + COMMA@9553..9554 "," + WHITESPACE@9554..9555 " " + ARG@9555..9560 + EXPR_VAR@9555..9560 + NAME@9555..9560 + IDENT@9555..9560 "lines" + R_PAREN@9560..9561 ")" + WHITESPACE@9561..9570 "\n " + ELSE_KW@9570..9574 "else" + WHITESPACE@9574..9575 " " + FALSE_EXPR@9575..9990 + EXPR_IF_THEN_ELSE@9575..9990 + IF_KW@9575..9577 "if" + WHITESPACE@9577..9578 " " + EXPR_APPLY@9578..9593 + EXPR_INDEX@9578..9590 + EXPR_VAR@9578..9581 + NAME@9578..9581 + IDENT@9578..9581 "std" + DOT@9581..9582 "." + NAME@9582..9590 + IDENT@9582..9590 "isObject" + ARGS_DESC@9590..9593 + L_PAREN@9590..9591 "(" + ARG@9591..9592 + EXPR_VAR@9591..9592 + NAME@9591..9592 + IDENT@9591..9592 "v" + R_PAREN@9592..9593 ")" + WHITESPACE@9593..9594 " " + THEN_KW@9594..9598 "then" + WHITESPACE@9598..9609 "\n " + TRUE_EXPR@9609..9990 + EXPR_LOCAL@9609..9990 + LOCAL_KW@9609..9614 "local" + WHITESPACE@9614..9615 " " + BIND_DESTRUCT@9615..9959 + DESTRUCT_FULL@9615..9620 + NAME@9615..9620 + IDENT@9615..9620 "lines" + WHITESPACE@9620..9621 " " + ASSIGN@9621..9622 "=" + WHITESPACE@9622..9623 " " + EXPR_BINARY@9623..9959 + LHS_EXPR@9623..9926 + EXPR_BINARY@9623..9926 + LHS_EXPR@9623..9629 + EXPR_ARRAY@9623..9629 + L_BRACK@9623..9624 "[" + EXPR_STRING@9624..9628 + STRING_SINGLE@9624..9628 "'{ '" + R_BRACK@9628..9629 "]" + WHITESPACE@9629..9654 "\n ..." + PLUS@9654..9655 "+" + WHITESPACE@9655..9656 " " + EXPR_APPLY@9656..9926 + EXPR_INDEX@9656..9664 + EXPR_VAR@9656..9659 + NAME@9656..9659 + IDENT@9656..9659 "std" + DOT@9659..9660 "." + NAME@9660..9664 + IDENT@9660..9664 "join" + ARGS_DESC@9664..9926 + L_PAREN@9664..9665 "(" + ARG@9665..9671 + EXPR_ARRAY@9665..9671 + L_BRACK@9665..9666 "[" + EXPR_STRING@9666..9670 + STRING_SINGLE@9666..9670 "', '" + R_BRACK@9670..9671 "]" + COMMA@9671..9672 "," + WHITESPACE@9672..9708 "\n ..." + ARG@9708..9925 + EXPR_ARRAY_COMP@9708..9925 + L_BRACK@9708..9709 "[" + WHITESPACE@9709..9747 "\n ..." + EXPR_ARRAY@9747..9822 + L_BRACK@9747..9748 "[" + EXPR_BINARY@9748..9821 + LHS_EXPR@9748..9772 + EXPR_BINARY@9748..9772 + LHS_EXPR@9748..9764 + EXPR_APPLY@9748..9764 + EXPR_VAR@9748..9761 + NAME@9748..9761 + IDENT@9748..9761 "escapeKeyToml" + ARGS_DESC@9761..9764 + L_PAREN@9761..9762 "(" + ARG@9762..9763 + EXPR_VAR@9762..9763 + NAME@9762..9763 + IDENT@9762..9763 "k" + R_PAREN@9763..9764 ")" + WHITESPACE@9764..9765 " " + PLUS@9765..9766 "+" + WHITESPACE@9766..9767 " " + EXPR_STRING@9767..9772 + STRING_SINGLE@9767..9772 "' = '" + WHITESPACE@9772..9773 " " + PLUS@9773..9774 "+" + WHITESPACE@9774..9775 " " + EXPR_APPLY@9775..9821 + EXPR_VAR@9775..9786 + NAME@9775..9786 + IDENT@9775..9786 "renderValue" + ARGS_DESC@9786..9821 + L_PAREN@9786..9787 "(" + ARG@9787..9791 + EXPR_INDEX_EXPR@9787..9791 + LHS_EXPR@9787..9788 + EXPR_VAR@9787..9788 + NAME@9787..9788 + IDENT@9787..9788 "v" + L_BRACK@9788..9789 "[" + EXPR_VAR@9789..9790 + NAME@9789..9790 + IDENT@9789..9790 "k" + R_BRACK@9790..9791 "]" + COMMA@9791..9792 "," + WHITESPACE@9792..9793 " " + ARG@9793..9810 + EXPR_BINARY@9793..9810 + LHS_EXPR@9793..9804 + EXPR_VAR@9793..9804 + NAME@9793..9804 + IDENT@9793..9804 "indexedPath" + WHITESPACE@9804..9805 " " + PLUS@9805..9806 "+" + WHITESPACE@9806..9807 " " + EXPR_ARRAY@9807..9810 + L_BRACK@9807..9808 "[" + EXPR_VAR@9808..9809 + NAME@9808..9809 + IDENT@9808..9809 "k" + R_BRACK@9809..9810 "]" + COMMA@9810..9811 "," + WHITESPACE@9811..9812 " " + ARG@9812..9816 + EXPR_LITERAL@9812..9816 + TRUE_KW@9812..9816 "true" + COMMA@9816..9817 "," + WHITESPACE@9817..9818 " " + ARG@9818..9820 + EXPR_STRING@9818..9820 + STRING_SINGLE@9818..9820 "''" + R_PAREN@9820..9821 ")" + R_BRACK@9821..9822 "]" + WHITESPACE@9822..9860 "\n ..." + FOR_SPEC@9860..9888 + FOR_KW@9860..9863 "for" + WHITESPACE@9863..9864 " " + NAME@9864..9865 + IDENT@9864..9865 "k" + WHITESPACE@9865..9866 " " + IN_KW@9866..9868 "in" + WHITESPACE@9868..9869 " " + EXPR_APPLY@9869..9888 + EXPR_INDEX@9869..9885 + EXPR_VAR@9869..9872 + NAME@9869..9872 + IDENT@9869..9872 "std" + DOT@9872..9873 "." + NAME@9873..9885 + IDENT@9873..9885 "objectFields" + ARGS_DESC@9885..9888 + L_PAREN@9885..9886 "(" + ARG@9886..9887 + EXPR_VAR@9886..9887 + NAME@9886..9887 + IDENT@9886..9887 "v" + R_PAREN@9887..9888 ")" + WHITESPACE@9888..9924 "\n ..." + R_BRACK@9924..9925 "]" + R_PAREN@9925..9926 ")" + WHITESPACE@9926..9951 "\n ..." + PLUS@9951..9952 "+" + WHITESPACE@9952..9953 " " + EXPR_ARRAY@9953..9959 + L_BRACK@9953..9954 "[" + EXPR_STRING@9954..9958 + STRING_SINGLE@9954..9958 "' }'" + R_BRACK@9958..9959 "]" + SEMI@9959..9960 ";" + WHITESPACE@9960..9971 "\n " + EXPR_APPLY@9971..9990 + EXPR_INDEX@9971..9979 + EXPR_VAR@9971..9974 + NAME@9971..9974 + IDENT@9971..9974 "std" + DOT@9974..9975 "." + NAME@9975..9979 + IDENT@9975..9979 "join" + ARGS_DESC@9979..9990 + L_PAREN@9979..9980 "(" + ARG@9980..9982 + EXPR_STRING@9980..9982 + STRING_SINGLE@9980..9982 "''" + COMMA@9982..9983 "," + WHITESPACE@9983..9984 " " + ARG@9984..9989 + EXPR_VAR@9984..9989 + NAME@9984..9989 + IDENT@9984..9989 "lines" + R_PAREN@9989..9990 ")" + COMMA@9990..9991 "," + WHITESPACE@9991..9998 "\n " + BIND_FUNCTION@9998..10667 + NAME@9998..10017 + IDENT@9998..10017 "renderTableInternal" + PARAMS_DESC@10017..10048 + L_PAREN@10017..10018 "(" + PARAM@10018..10019 + DESTRUCT_FULL@10018..10019 + NAME@10018..10019 + IDENT@10018..10019 "v" + COMMA@10019..10020 "," + WHITESPACE@10020..10021 " " + PARAM@10021..10025 + DESTRUCT_FULL@10021..10025 + NAME@10021..10025 + IDENT@10021..10025 "path" + COMMA@10025..10026 "," + WHITESPACE@10026..10027 " " + PARAM@10027..10038 + DESTRUCT_FULL@10027..10038 + NAME@10027..10038 + IDENT@10027..10038 "indexedPath" + COMMA@10038..10039 "," + WHITESPACE@10039..10040 " " + PARAM@10040..10047 + DESTRUCT_FULL@10040..10047 + NAME@10040..10047 + IDENT@10040..10047 "cindent" + R_PAREN@10047..10048 ")" + WHITESPACE@10048..10049 " " + ASSIGN@10049..10050 "=" + WHITESPACE@10050..10059 "\n " + EXPR_LOCAL@10059..10667 + LOCAL_KW@10059..10064 "local" + WHITESPACE@10064..10065 " " + BIND_DESTRUCT@10065..10272 + DESTRUCT_FULL@10065..10068 + NAME@10065..10068 + IDENT@10065..10068 "kvp" + WHITESPACE@10068..10069 " " + ASSIGN@10069..10070 "=" + WHITESPACE@10070..10071 " " + EXPR_APPLY@10071..10272 + EXPR_INDEX@10071..10088 + EXPR_VAR@10071..10074 + NAME@10071..10074 + IDENT@10071..10074 "std" + DOT@10074..10075 "." + NAME@10075..10088 + IDENT@10075..10088 "flattenArrays" + ARGS_DESC@10088..10272 + L_PAREN@10088..10089 "(" + ARG@10089..10271 + EXPR_ARRAY_COMP@10089..10271 + L_BRACK@10089..10090 "[" + WHITESPACE@10090..10101 "\n " + EXPR_ARRAY@10101..10192 + L_BRACK@10101..10102 "[" + EXPR_BINARY@10102..10191 + LHS_EXPR@10102..10136 + EXPR_BINARY@10102..10136 + LHS_EXPR@10102..10128 + EXPR_BINARY@10102..10128 + LHS_EXPR@10102..10109 + EXPR_VAR@10102..10109 + NAME@10102..10109 + IDENT@10102..10109 "cindent" + WHITESPACE@10109..10110 " " + PLUS@10110..10111 "+" + WHITESPACE@10111..10112 " " + EXPR_APPLY@10112..10128 + EXPR_VAR@10112..10125 + NAME@10112..10125 + IDENT@10112..10125 "escapeKeyToml" + ARGS_DESC@10125..10128 + L_PAREN@10125..10126 "(" + ARG@10126..10127 + EXPR_VAR@10126..10127 + NAME@10126..10127 + IDENT@10126..10127 "k" + R_PAREN@10127..10128 ")" + WHITESPACE@10128..10129 " " + PLUS@10129..10130 "+" + WHITESPACE@10130..10131 " " + EXPR_STRING@10131..10136 + STRING_SINGLE@10131..10136 "' = '" + WHITESPACE@10136..10137 " " + PLUS@10137..10138 "+" + WHITESPACE@10138..10139 " " + EXPR_APPLY@10139..10191 + EXPR_VAR@10139..10150 + NAME@10139..10150 + IDENT@10139..10150 "renderValue" + ARGS_DESC@10150..10191 + L_PAREN@10150..10151 "(" + ARG@10151..10155 + EXPR_INDEX_EXPR@10151..10155 + LHS_EXPR@10151..10152 + EXPR_VAR@10151..10152 + NAME@10151..10152 + IDENT@10151..10152 "v" + L_BRACK@10152..10153 "[" + EXPR_VAR@10153..10154 + NAME@10153..10154 + IDENT@10153..10154 "k" + R_BRACK@10154..10155 "]" + COMMA@10155..10156 "," + WHITESPACE@10156..10157 " " + ARG@10157..10174 + EXPR_BINARY@10157..10174 + LHS_EXPR@10157..10168 + EXPR_VAR@10157..10168 + NAME@10157..10168 + IDENT@10157..10168 "indexedPath" + WHITESPACE@10168..10169 " " + PLUS@10169..10170 "+" + WHITESPACE@10170..10171 " " + EXPR_ARRAY@10171..10174 + L_BRACK@10171..10172 "[" + EXPR_VAR@10172..10173 + NAME@10172..10173 + IDENT@10172..10173 "k" + R_BRACK@10173..10174 "]" + COMMA@10174..10175 "," + WHITESPACE@10175..10176 " " + ARG@10176..10181 + EXPR_LITERAL@10176..10181 + FALSE_KW@10176..10181 "false" + COMMA@10181..10182 "," + WHITESPACE@10182..10183 " " + ARG@10183..10190 + EXPR_VAR@10183..10190 + NAME@10183..10190 + IDENT@10183..10190 "cindent" + R_PAREN@10190..10191 ")" + R_BRACK@10191..10192 "]" + WHITESPACE@10192..10203 "\n " + FOR_SPEC@10203..10231 + FOR_KW@10203..10206 "for" + WHITESPACE@10206..10207 " " + NAME@10207..10208 + IDENT@10207..10208 "k" + WHITESPACE@10208..10209 " " + IN_KW@10209..10211 "in" + WHITESPACE@10211..10212 " " + EXPR_APPLY@10212..10231 + EXPR_INDEX@10212..10228 + EXPR_VAR@10212..10215 + NAME@10212..10215 + IDENT@10212..10215 "std" + DOT@10215..10216 "." + NAME@10216..10228 + IDENT@10216..10228 "objectFields" + ARGS_DESC@10228..10231 + L_PAREN@10228..10229 "(" + ARG@10229..10230 + EXPR_VAR@10229..10230 + NAME@10229..10230 + IDENT@10229..10230 "v" + R_PAREN@10230..10231 ")" + WHITESPACE@10231..10242 "\n " + IF_SPEC@10242..10261 + IF_KW@10242..10244 "if" + WHITESPACE@10244..10245 " " + EXPR_UNARY@10245..10261 + NOT@10245..10246 "!" + EXPR_APPLY@10246..10261 + EXPR_VAR@10246..10255 + NAME@10246..10255 + IDENT@10246..10255 "isSection" + ARGS_DESC@10255..10261 + L_PAREN@10255..10256 "(" + ARG@10256..10260 + EXPR_INDEX_EXPR@10256..10260 + LHS_EXPR@10256..10257 + EXPR_VAR@10256..10257 + NAME@10256..10257 + IDENT@10256..10257 "v" + L_BRACK@10257..10258 "[" + EXPR_VAR@10258..10259 + NAME@10258..10259 + IDENT@10258..10259 "k" + R_BRACK@10259..10260 "]" + R_PAREN@10260..10261 ")" + WHITESPACE@10261..10270 "\n " + R_BRACK@10270..10271 "]" + R_PAREN@10271..10272 ")" + SEMI@10272..10273 ";" + WHITESPACE@10273..10282 "\n " + EXPR_LOCAL@10282..10667 + LOCAL_KW@10282..10287 "local" + WHITESPACE@10287..10288 " " + BIND_DESTRUCT@10288..10631 + DESTRUCT_FULL@10288..10296 + NAME@10288..10296 + IDENT@10288..10296 "sections" + WHITESPACE@10296..10297 " " + ASSIGN@10297..10298 "=" + WHITESPACE@10298..10299 " " + EXPR_BINARY@10299..10631 + LHS_EXPR@10299..10320 + EXPR_ARRAY@10299..10320 + L_BRACK@10299..10300 "[" + EXPR_APPLY@10300..10319 + EXPR_INDEX@10300..10308 + EXPR_VAR@10300..10303 + NAME@10300..10303 + IDENT@10300..10303 "std" + DOT@10303..10304 "." + NAME@10304..10308 + IDENT@10304..10308 "join" + ARGS_DESC@10308..10319 + L_PAREN@10308..10309 "(" + ARG@10309..10313 + EXPR_STRING@10309..10313 + STRING_SINGLE@10309..10313 "'\\n'" + COMMA@10313..10314 "," + WHITESPACE@10314..10315 " " + ARG@10315..10318 + EXPR_VAR@10315..10318 + NAME@10315..10318 + IDENT@10315..10318 "kvp" + R_PAREN@10318..10319 ")" + R_BRACK@10319..10320 "]" + WHITESPACE@10320..10321 " " + PLUS@10321..10322 "+" + WHITESPACE@10322..10323 " " + EXPR_ARRAY_COMP@10323..10631 + L_BRACK@10323..10324 "[" + WHITESPACE@10324..10335 "\n " + EXPR_PARENED@10335..10553 + L_PAREN@10335..10336 "(" + WHITESPACE@10336..10349 "\n " + EXPR_IF_THEN_ELSE@10349..10541 + IF_KW@10349..10351 "if" + WHITESPACE@10351..10352 " " + EXPR_APPLY@10352..10370 + EXPR_INDEX@10352..10364 + EXPR_VAR@10352..10355 + NAME@10352..10355 + IDENT@10352..10355 "std" + DOT@10355..10356 "." + NAME@10356..10364 + IDENT@10356..10364 "isObject" + ARGS_DESC@10364..10370 + L_PAREN@10364..10365 "(" + ARG@10365..10369 + EXPR_INDEX_EXPR@10365..10369 + LHS_EXPR@10365..10366 + EXPR_VAR@10365..10366 + NAME@10365..10366 + IDENT@10365..10366 "v" + L_BRACK@10366..10367 "[" + EXPR_VAR@10367..10368 + NAME@10367..10368 + IDENT@10367..10368 "k" + R_BRACK@10368..10369 "]" + R_PAREN@10369..10370 ")" + WHITESPACE@10370..10371 " " + THEN_KW@10371..10375 "then" + WHITESPACE@10375..10390 "\n " + TRUE_EXPR@10390..10447 + EXPR_APPLY@10390..10447 + EXPR_VAR@10390..10401 + NAME@10390..10401 + IDENT@10390..10401 "renderTable" + ARGS_DESC@10401..10447 + L_PAREN@10401..10402 "(" + ARG@10402..10406 + EXPR_INDEX_EXPR@10402..10406 + LHS_EXPR@10402..10403 + EXPR_VAR@10402..10403 + NAME@10402..10403 + IDENT@10402..10403 "v" + L_BRACK@10403..10404 "[" + EXPR_VAR@10404..10405 + NAME@10404..10405 + IDENT@10404..10405 "k" + R_BRACK@10405..10406 "]" + COMMA@10406..10407 "," + WHITESPACE@10407..10408 " " + ARG@10408..10418 + EXPR_BINARY@10408..10418 + LHS_EXPR@10408..10412 + EXPR_VAR@10408..10412 + NAME@10408..10412 + IDENT@10408..10412 "path" + WHITESPACE@10412..10413 " " + PLUS@10413..10414 "+" + WHITESPACE@10414..10415 " " + EXPR_ARRAY@10415..10418 + L_BRACK@10415..10416 "[" + EXPR_VAR@10416..10417 + NAME@10416..10417 + IDENT@10416..10417 "k" + R_BRACK@10417..10418 "]" + COMMA@10418..10419 "," + WHITESPACE@10419..10420 " " + ARG@10420..10437 + EXPR_BINARY@10420..10437 + LHS_EXPR@10420..10431 + EXPR_VAR@10420..10431 + NAME@10420..10431 + IDENT@10420..10431 "indexedPath" + WHITESPACE@10431..10432 " " + PLUS@10432..10433 "+" + WHITESPACE@10433..10434 " " + EXPR_ARRAY@10434..10437 + L_BRACK@10434..10435 "[" + EXPR_VAR@10435..10436 + NAME@10435..10436 + IDENT@10435..10436 "k" + R_BRACK@10436..10437 "]" + COMMA@10437..10438 "," + WHITESPACE@10438..10439 " " + ARG@10439..10446 + EXPR_VAR@10439..10446 + NAME@10439..10446 + IDENT@10439..10446 "cindent" + R_PAREN@10446..10447 ")" + WHITESPACE@10447..10460 "\n " + ELSE_KW@10460..10464 "else" + WHITESPACE@10464..10479 "\n " + FALSE_EXPR@10479..10541 + EXPR_APPLY@10479..10541 + EXPR_VAR@10479..10495 + NAME@10479..10495 + IDENT@10479..10495 "renderTableArray" + ARGS_DESC@10495..10541 + L_PAREN@10495..10496 "(" + ARG@10496..10500 + EXPR_INDEX_EXPR@10496..10500 + LHS_EXPR@10496..10497 + EXPR_VAR@10496..10497 + NAME@10496..10497 + IDENT@10496..10497 "v" + L_BRACK@10497..10498 "[" + EXPR_VAR@10498..10499 + NAME@10498..10499 + IDENT@10498..10499 "k" + R_BRACK@10499..10500 "]" + COMMA@10500..10501 "," + WHITESPACE@10501..10502 " " + ARG@10502..10512 + EXPR_BINARY@10502..10512 + LHS_EXPR@10502..10506 + EXPR_VAR@10502..10506 + NAME@10502..10506 + IDENT@10502..10506 "path" + WHITESPACE@10506..10507 " " + PLUS@10507..10508 "+" + WHITESPACE@10508..10509 " " + EXPR_ARRAY@10509..10512 + L_BRACK@10509..10510 "[" + EXPR_VAR@10510..10511 + NAME@10510..10511 + IDENT@10510..10511 "k" + R_BRACK@10511..10512 "]" + COMMA@10512..10513 "," + WHITESPACE@10513..10514 " " + ARG@10514..10531 + EXPR_BINARY@10514..10531 + LHS_EXPR@10514..10525 + EXPR_VAR@10514..10525 + NAME@10514..10525 + IDENT@10514..10525 "indexedPath" + WHITESPACE@10525..10526 " " + PLUS@10526..10527 "+" + WHITESPACE@10527..10528 " " + EXPR_ARRAY@10528..10531 + L_BRACK@10528..10529 "[" + EXPR_VAR@10529..10530 + NAME@10529..10530 + IDENT@10529..10530 "k" + R_BRACK@10530..10531 "]" + COMMA@10531..10532 "," + WHITESPACE@10532..10533 " " + ARG@10533..10540 + EXPR_VAR@10533..10540 + NAME@10533..10540 + IDENT@10533..10540 "cindent" + R_PAREN@10540..10541 ")" + WHITESPACE@10541..10552 "\n " + R_PAREN@10552..10553 ")" + WHITESPACE@10553..10564 "\n " + FOR_SPEC@10564..10592 + FOR_KW@10564..10567 "for" + WHITESPACE@10567..10568 " " + NAME@10568..10569 + IDENT@10568..10569 "k" + WHITESPACE@10569..10570 " " + IN_KW@10570..10572 "in" + WHITESPACE@10572..10573 " " + EXPR_APPLY@10573..10592 + EXPR_INDEX@10573..10589 + EXPR_VAR@10573..10576 + NAME@10573..10576 + IDENT@10573..10576 "std" + DOT@10576..10577 "." + NAME@10577..10589 + IDENT@10577..10589 "objectFields" + ARGS_DESC@10589..10592 + L_PAREN@10589..10590 "(" + ARG@10590..10591 + EXPR_VAR@10590..10591 + NAME@10590..10591 + IDENT@10590..10591 "v" + R_PAREN@10591..10592 ")" + WHITESPACE@10592..10603 "\n " + IF_SPEC@10603..10621 + IF_KW@10603..10605 "if" + WHITESPACE@10605..10606 " " + EXPR_APPLY@10606..10621 + EXPR_VAR@10606..10615 + NAME@10606..10615 + IDENT@10606..10615 "isSection" + ARGS_DESC@10615..10621 + L_PAREN@10615..10616 "(" + ARG@10616..10620 + EXPR_INDEX_EXPR@10616..10620 + LHS_EXPR@10616..10617 + EXPR_VAR@10616..10617 + NAME@10616..10617 + IDENT@10616..10617 "v" + L_BRACK@10617..10618 "[" + EXPR_VAR@10618..10619 + NAME@10618..10619 + IDENT@10618..10619 "k" + R_BRACK@10619..10620 "]" + R_PAREN@10620..10621 ")" + WHITESPACE@10621..10630 "\n " + R_BRACK@10630..10631 "]" + SEMI@10631..10632 ";" + WHITESPACE@10632..10641 "\n " + EXPR_APPLY@10641..10667 + EXPR_INDEX@10641..10649 + EXPR_VAR@10641..10644 + NAME@10641..10644 + IDENT@10641..10644 "std" + DOT@10644..10645 "." + NAME@10645..10649 + IDENT@10645..10649 "join" + ARGS_DESC@10649..10667 + L_PAREN@10649..10650 "(" + ARG@10650..10656 + EXPR_STRING@10650..10656 + STRING_SINGLE@10650..10656 "'\\n\\n'" + COMMA@10656..10657 "," + WHITESPACE@10657..10658 " " + ARG@10658..10666 + EXPR_VAR@10658..10666 + NAME@10658..10666 + IDENT@10658..10666 "sections" + R_PAREN@10666..10667 ")" + COMMA@10667..10668 "," + WHITESPACE@10668..10675 "\n " + BIND_FUNCTION@10675..10904 + NAME@10675..10686 + IDENT@10675..10686 "renderTable" + PARAMS_DESC@10686..10717 + L_PAREN@10686..10687 "(" + PARAM@10687..10688 + DESTRUCT_FULL@10687..10688 + NAME@10687..10688 + IDENT@10687..10688 "v" + COMMA@10688..10689 "," + WHITESPACE@10689..10690 " " + PARAM@10690..10694 + DESTRUCT_FULL@10690..10694 + NAME@10690..10694 + IDENT@10690..10694 "path" + COMMA@10694..10695 "," + WHITESPACE@10695..10696 " " + PARAM@10696..10707 + DESTRUCT_FULL@10696..10707 + NAME@10696..10707 + IDENT@10696..10707 "indexedPath" + COMMA@10707..10708 "," + WHITESPACE@10708..10709 " " + PARAM@10709..10716 + DESTRUCT_FULL@10709..10716 + NAME@10709..10716 + IDENT@10709..10716 "cindent" + R_PAREN@10716..10717 ")" + WHITESPACE@10717..10718 " " + ASSIGN@10718..10719 "=" + WHITESPACE@10719..10728 "\n " + EXPR_BINARY@10728..10904 + LHS_EXPR@10728..10834 + EXPR_BINARY@10728..10834 + LHS_EXPR@10728..10793 + EXPR_BINARY@10728..10793 + LHS_EXPR@10728..10787 + EXPR_BINARY@10728..10787 + LHS_EXPR@10728..10741 + EXPR_BINARY@10728..10741 + LHS_EXPR@10728..10735 + EXPR_VAR@10728..10735 + NAME@10728..10735 + IDENT@10728..10735 "cindent" + WHITESPACE@10735..10736 " " + PLUS@10736..10737 "+" + WHITESPACE@10737..10738 " " + EXPR_STRING@10738..10741 + STRING_SINGLE@10738..10741 "'['" + WHITESPACE@10741..10742 " " + PLUS@10742..10743 "+" + WHITESPACE@10743..10744 " " + EXPR_APPLY@10744..10787 + EXPR_INDEX@10744..10752 + EXPR_VAR@10744..10747 + NAME@10744..10747 + IDENT@10744..10747 "std" + DOT@10747..10748 "." + NAME@10748..10752 + IDENT@10748..10752 "join" + ARGS_DESC@10752..10787 + L_PAREN@10752..10753 "(" + ARG@10753..10756 + EXPR_STRING@10753..10756 + STRING_SINGLE@10753..10756 "'.'" + COMMA@10756..10757 "," + WHITESPACE@10757..10758 " " + ARG@10758..10786 + EXPR_APPLY@10758..10786 + EXPR_INDEX@10758..10765 + EXPR_VAR@10758..10761 + NAME@10758..10761 + IDENT@10758..10761 "std" + DOT@10761..10762 "." + NAME@10762..10765 + IDENT@10762..10765 "map" + ARGS_DESC@10765..10786 + L_PAREN@10765..10766 "(" + ARG@10766..10779 + EXPR_VAR@10766..10779 + NAME@10766..10779 + IDENT@10766..10779 "escapeKeyToml" + COMMA@10779..10780 "," + WHITESPACE@10780..10781 " " + ARG@10781..10785 + EXPR_VAR@10781..10785 + NAME@10781..10785 + IDENT@10781..10785 "path" + R_PAREN@10785..10786 ")" + R_PAREN@10786..10787 ")" + WHITESPACE@10787..10788 " " + PLUS@10788..10789 "+" + WHITESPACE@10789..10790 " " + EXPR_STRING@10790..10793 + STRING_SINGLE@10790..10793 "']'" + WHITESPACE@10793..10802 "\n " + PLUS@10802..10803 "+" + WHITESPACE@10803..10804 " " + EXPR_PARENED@10804..10834 + L_PAREN@10804..10805 "(" + EXPR_IF_THEN_ELSE@10805..10833 + IF_KW@10805..10807 "if" + WHITESPACE@10807..10808 " " + EXPR_BINARY@10808..10815 + LHS_EXPR@10808..10809 + EXPR_VAR@10808..10809 + NAME@10808..10809 + IDENT@10808..10809 "v" + WHITESPACE@10809..10810 " " + EQ@10810..10812 "==" + WHITESPACE@10812..10813 " " + EXPR_OBJECT@10813..10815 + OBJ_BODY_MEMBER_LIST@10813..10815 + L_BRACE@10813..10814 "{" + R_BRACE@10814..10815 "}" + WHITESPACE@10815..10816 " " + THEN_KW@10816..10820 "then" + WHITESPACE@10820..10821 " " + TRUE_EXPR@10821..10823 + EXPR_STRING@10821..10823 + STRING_SINGLE@10821..10823 "''" + WHITESPACE@10823..10824 " " + ELSE_KW@10824..10828 "else" + WHITESPACE@10828..10829 " " + FALSE_EXPR@10829..10833 + EXPR_STRING@10829..10833 + STRING_SINGLE@10829..10833 "'\\n'" + R_PAREN@10833..10834 ")" + WHITESPACE@10834..10843 "\n " + PLUS@10843..10844 "+" + WHITESPACE@10844..10845 " " + EXPR_APPLY@10845..10904 + EXPR_VAR@10845..10864 + NAME@10845..10864 + IDENT@10845..10864 "renderTableInternal" + ARGS_DESC@10864..10904 + L_PAREN@10864..10865 "(" + ARG@10865..10866 + EXPR_VAR@10865..10866 + NAME@10865..10866 + IDENT@10865..10866 "v" + COMMA@10866..10867 "," + WHITESPACE@10867..10868 " " + ARG@10868..10872 + EXPR_VAR@10868..10872 + NAME@10868..10872 + IDENT@10868..10872 "path" + COMMA@10872..10873 "," + WHITESPACE@10873..10874 " " + ARG@10874..10885 + EXPR_VAR@10874..10885 + NAME@10874..10885 + IDENT@10874..10885 "indexedPath" + COMMA@10885..10886 "," + WHITESPACE@10886..10887 " " + ARG@10887..10903 + EXPR_BINARY@10887..10903 + LHS_EXPR@10887..10894 + EXPR_VAR@10887..10894 + NAME@10887..10894 + IDENT@10887..10894 "cindent" + WHITESPACE@10894..10895 " " + PLUS@10895..10896 "+" + WHITESPACE@10896..10897 " " + EXPR_VAR@10897..10903 + NAME@10897..10903 + IDENT@10897..10903 "indent" + R_PAREN@10903..10904 ")" + COMMA@10904..10905 "," + WHITESPACE@10905..10912 "\n " + BIND_FUNCTION@10912..11323 + NAME@10912..10928 + IDENT@10912..10928 "renderTableArray" + PARAMS_DESC@10928..10959 + L_PAREN@10928..10929 "(" + PARAM@10929..10930 + DESTRUCT_FULL@10929..10930 + NAME@10929..10930 + IDENT@10929..10930 "v" + COMMA@10930..10931 "," + WHITESPACE@10931..10932 " " + PARAM@10932..10936 + DESTRUCT_FULL@10932..10936 + NAME@10932..10936 + IDENT@10932..10936 "path" + COMMA@10936..10937 "," + WHITESPACE@10937..10938 " " + PARAM@10938..10949 + DESTRUCT_FULL@10938..10949 + NAME@10938..10949 + IDENT@10938..10949 "indexedPath" + COMMA@10949..10950 "," + WHITESPACE@10950..10951 " " + PARAM@10951..10958 + DESTRUCT_FULL@10951..10958 + NAME@10951..10958 + IDENT@10951..10958 "cindent" + R_PAREN@10958..10959 ")" + WHITESPACE@10959..10960 " " + ASSIGN@10960..10961 "=" + WHITESPACE@10961..10970 "\n " + EXPR_LOCAL@10970..11323 + LOCAL_KW@10970..10975 "local" + WHITESPACE@10975..10976 " " + BIND_DESTRUCT@10976..11015 + DESTRUCT_FULL@10976..10981 + NAME@10976..10981 + IDENT@10976..10981 "range" + WHITESPACE@10981..10982 " " + ASSIGN@10982..10983 "=" + WHITESPACE@10983..10984 " " + EXPR_APPLY@10984..11015 + EXPR_INDEX@10984..10993 + EXPR_VAR@10984..10987 + NAME@10984..10987 + IDENT@10984..10987 "std" + DOT@10987..10988 "." + NAME@10988..10993 + IDENT@10988..10993 "range" + ARGS_DESC@10993..11015 + L_PAREN@10993..10994 "(" + ARG@10994..10995 + EXPR_NUMBER@10994..10995 + FLOAT@10994..10995 "0" + COMMA@10995..10996 "," + WHITESPACE@10996..10997 " " + ARG@10997..11014 + EXPR_BINARY@10997..11014 + LHS_EXPR@10997..11010 + EXPR_APPLY@10997..11010 + EXPR_INDEX@10997..11007 + EXPR_VAR@10997..11000 + NAME@10997..11000 + IDENT@10997..11000 "std" + DOT@11000..11001 "." + NAME@11001..11007 + IDENT@11001..11007 "length" + ARGS_DESC@11007..11010 + L_PAREN@11007..11008 "(" + ARG@11008..11009 + EXPR_VAR@11008..11009 + NAME@11008..11009 + IDENT@11008..11009 "v" + R_PAREN@11009..11010 ")" + WHITESPACE@11010..11011 " " + MINUS@11011..11012 "-" + WHITESPACE@11012..11013 " " + EXPR_NUMBER@11013..11014 + FLOAT@11013..11014 "1" + R_PAREN@11014..11015 ")" + SEMI@11015..11016 ";" + WHITESPACE@11016..11025 "\n " + EXPR_LOCAL@11025..11323 + LOCAL_KW@11025..11030 "local" + WHITESPACE@11030..11031 " " + BIND_DESTRUCT@11031..11287 + DESTRUCT_FULL@11031..11039 + NAME@11031..11039 + IDENT@11031..11039 "sections" + WHITESPACE@11039..11040 " " + ASSIGN@11040..11041 "=" + WHITESPACE@11041..11042 " " + EXPR_ARRAY_COMP@11042..11287 + L_BRACK@11042..11043 "[" + WHITESPACE@11043..11054 "\n " + EXPR_PARENED@11054..11252 + L_PAREN@11054..11055 "(" + EXPR_BINARY@11055..11251 + LHS_EXPR@11055..11169 + EXPR_BINARY@11055..11169 + LHS_EXPR@11055..11122 + EXPR_BINARY@11055..11122 + LHS_EXPR@11055..11115 + EXPR_BINARY@11055..11115 + LHS_EXPR@11055..11069 + EXPR_BINARY@11055..11069 + LHS_EXPR@11055..11062 + EXPR_VAR@11055..11062 + NAME@11055..11062 + IDENT@11055..11062 "cindent" + WHITESPACE@11062..11063 " " + PLUS@11063..11064 "+" + WHITESPACE@11064..11065 " " + EXPR_STRING@11065..11069 + STRING_SINGLE@11065..11069 "'[['" + WHITESPACE@11069..11070 " " + PLUS@11070..11071 "+" + WHITESPACE@11071..11072 " " + EXPR_APPLY@11072..11115 + EXPR_INDEX@11072..11080 + EXPR_VAR@11072..11075 + NAME@11072..11075 + IDENT@11072..11075 "std" + DOT@11075..11076 "." + NAME@11076..11080 + IDENT@11076..11080 "join" + ARGS_DESC@11080..11115 + L_PAREN@11080..11081 "(" + ARG@11081..11084 + EXPR_STRING@11081..11084 + STRING_SINGLE@11081..11084 "'.'" + COMMA@11084..11085 "," + WHITESPACE@11085..11086 " " + ARG@11086..11114 + EXPR_APPLY@11086..11114 + EXPR_INDEX@11086..11093 + EXPR_VAR@11086..11089 + NAME@11086..11089 + IDENT@11086..11089 "std" + DOT@11089..11090 "." + NAME@11090..11093 + IDENT@11090..11093 "map" + ARGS_DESC@11093..11114 + L_PAREN@11093..11094 "(" + ARG@11094..11107 + EXPR_VAR@11094..11107 + NAME@11094..11107 + IDENT@11094..11107 "escapeKeyToml" + COMMA@11107..11108 "," + WHITESPACE@11108..11109 " " + ARG@11109..11113 + EXPR_VAR@11109..11113 + NAME@11109..11113 + IDENT@11109..11113 "path" + R_PAREN@11113..11114 ")" + R_PAREN@11114..11115 ")" + WHITESPACE@11115..11116 " " + PLUS@11116..11117 "+" + WHITESPACE@11117..11118 " " + EXPR_STRING@11118..11122 + STRING_SINGLE@11118..11122 "']]'" + WHITESPACE@11122..11134 "\n " + PLUS@11134..11135 "+" + WHITESPACE@11135..11136 " " + EXPR_PARENED@11136..11169 + L_PAREN@11136..11137 "(" + EXPR_IF_THEN_ELSE@11137..11168 + IF_KW@11137..11139 "if" + WHITESPACE@11139..11140 " " + EXPR_BINARY@11140..11150 + LHS_EXPR@11140..11144 + EXPR_INDEX_EXPR@11140..11144 + LHS_EXPR@11140..11141 + EXPR_VAR@11140..11141 + NAME@11140..11141 + IDENT@11140..11141 "v" + L_BRACK@11141..11142 "[" + EXPR_VAR@11142..11143 + NAME@11142..11143 + IDENT@11142..11143 "i" + R_BRACK@11143..11144 "]" + WHITESPACE@11144..11145 " " + EQ@11145..11147 "==" + WHITESPACE@11147..11148 " " + EXPR_OBJECT@11148..11150 + OBJ_BODY_MEMBER_LIST@11148..11150 + L_BRACE@11148..11149 "{" + R_BRACE@11149..11150 "}" + WHITESPACE@11150..11151 " " + THEN_KW@11151..11155 "then" + WHITESPACE@11155..11156 " " + TRUE_EXPR@11156..11158 + EXPR_STRING@11156..11158 + STRING_SINGLE@11156..11158 "''" + WHITESPACE@11158..11159 " " + ELSE_KW@11159..11163 "else" + WHITESPACE@11163..11164 " " + FALSE_EXPR@11164..11168 + EXPR_STRING@11164..11168 + STRING_SINGLE@11164..11168 "'\\n'" + R_PAREN@11168..11169 ")" + WHITESPACE@11169..11181 "\n " + PLUS@11181..11182 "+" + WHITESPACE@11182..11183 " " + EXPR_APPLY@11183..11251 + EXPR_VAR@11183..11202 + NAME@11183..11202 + IDENT@11183..11202 "renderTableInternal" + ARGS_DESC@11202..11251 + L_PAREN@11202..11203 "(" + ARG@11203..11207 + EXPR_INDEX_EXPR@11203..11207 + LHS_EXPR@11203..11204 + EXPR_VAR@11203..11204 + NAME@11203..11204 + IDENT@11203..11204 "v" + L_BRACK@11204..11205 "[" + EXPR_VAR@11205..11206 + NAME@11205..11206 + IDENT@11205..11206 "i" + R_BRACK@11206..11207 "]" + COMMA@11207..11208 "," + WHITESPACE@11208..11209 " " + ARG@11209..11213 + EXPR_VAR@11209..11213 + NAME@11209..11213 + IDENT@11209..11213 "path" + COMMA@11213..11214 "," + WHITESPACE@11214..11215 " " + ARG@11215..11232 + EXPR_BINARY@11215..11232 + LHS_EXPR@11215..11226 + EXPR_VAR@11215..11226 + NAME@11215..11226 + IDENT@11215..11226 "indexedPath" + WHITESPACE@11226..11227 " " + PLUS@11227..11228 "+" + WHITESPACE@11228..11229 " " + EXPR_ARRAY@11229..11232 + L_BRACK@11229..11230 "[" + EXPR_VAR@11230..11231 + NAME@11230..11231 + IDENT@11230..11231 "i" + R_BRACK@11231..11232 "]" + COMMA@11232..11233 "," + WHITESPACE@11233..11234 " " + ARG@11234..11250 + EXPR_BINARY@11234..11250 + LHS_EXPR@11234..11241 + EXPR_VAR@11234..11241 + NAME@11234..11241 + IDENT@11234..11241 "cindent" + WHITESPACE@11241..11242 " " + PLUS@11242..11243 "+" + WHITESPACE@11243..11244 " " + EXPR_VAR@11244..11250 + NAME@11244..11250 + IDENT@11244..11250 "indent" + R_PAREN@11250..11251 ")" + R_PAREN@11251..11252 ")" + WHITESPACE@11252..11263 "\n " + FOR_SPEC@11263..11277 + FOR_KW@11263..11266 "for" + WHITESPACE@11266..11267 " " + NAME@11267..11268 + IDENT@11267..11268 "i" + WHITESPACE@11268..11269 " " + IN_KW@11269..11271 "in" + WHITESPACE@11271..11272 " " + EXPR_VAR@11272..11277 + NAME@11272..11277 + IDENT@11272..11277 "range" + WHITESPACE@11277..11286 "\n " + R_BRACK@11286..11287 "]" + SEMI@11287..11288 ";" + WHITESPACE@11288..11297 "\n " + EXPR_APPLY@11297..11323 + EXPR_INDEX@11297..11305 + EXPR_VAR@11297..11300 + NAME@11297..11300 + IDENT@11297..11300 "std" + DOT@11300..11301 "." + NAME@11301..11305 + IDENT@11301..11305 "join" + ARGS_DESC@11305..11323 + L_PAREN@11305..11306 "(" + ARG@11306..11312 + EXPR_STRING@11306..11312 + STRING_SINGLE@11306..11312 "'\\n\\n'" + COMMA@11312..11313 "," + WHITESPACE@11313..11314 " " + ARG@11314..11322 + EXPR_VAR@11314..11322 + NAME@11314..11322 + IDENT@11314..11322 "sections" + R_PAREN@11322..11323 ")" + SEMI@11323..11324 ";" + WHITESPACE@11324..11329 "\n " + EXPR_IF_THEN_ELSE@11329..11476 + IF_KW@11329..11331 "if" + WHITESPACE@11331..11332 " " + EXPR_APPLY@11332..11351 + EXPR_INDEX@11332..11344 + EXPR_VAR@11332..11335 + NAME@11332..11335 + IDENT@11332..11335 "std" + DOT@11335..11336 "." + NAME@11336..11344 + IDENT@11336..11344 "isObject" + ARGS_DESC@11344..11351 + L_PAREN@11344..11345 "(" + ARG@11345..11350 + EXPR_VAR@11345..11350 + NAME@11345..11350 + IDENT@11345..11350 "value" + R_PAREN@11350..11351 ")" + WHITESPACE@11351..11352 " " + THEN_KW@11352..11356 "then" + WHITESPACE@11356..11363 "\n " + TRUE_EXPR@11363..11401 + EXPR_APPLY@11363..11401 + EXPR_VAR@11363..11382 + NAME@11363..11382 + IDENT@11363..11382 "renderTableInternal" + ARGS_DESC@11382..11401 + L_PAREN@11382..11383 "(" + ARG@11383..11388 + EXPR_VAR@11383..11388 + NAME@11383..11388 + IDENT@11383..11388 "value" + COMMA@11388..11389 "," + WHITESPACE@11389..11390 " " + ARG@11390..11392 + EXPR_ARRAY@11390..11392 + L_BRACK@11390..11391 "[" + R_BRACK@11391..11392 "]" + COMMA@11392..11393 "," + WHITESPACE@11393..11394 " " + ARG@11394..11396 + EXPR_ARRAY@11394..11396 + L_BRACK@11394..11395 "[" + R_BRACK@11395..11396 "]" + COMMA@11396..11397 "," + WHITESPACE@11397..11398 " " + ARG@11398..11400 + EXPR_STRING@11398..11400 + STRING_SINGLE@11398..11400 "''" + R_PAREN@11400..11401 ")" + WHITESPACE@11401..11406 "\n " + ELSE_KW@11406..11410 "else" + WHITESPACE@11410..11417 "\n " + FALSE_EXPR@11417..11476 + EXPR_ERROR@11417..11476 + ERROR_KW@11417..11422 "error" + WHITESPACE@11422..11423 " " + EXPR_BINARY@11423..11476 + LHS_EXPR@11423..11458 + EXPR_STRING@11423..11458 + STRING_SINGLE@11423..11458 "'TOML body must be an ..." + WHITESPACE@11458..11459 " " + PLUS@11459..11460 "+" + WHITESPACE@11460..11461 " " + EXPR_APPLY@11461..11476 + EXPR_INDEX@11461..11469 + EXPR_VAR@11461..11464 + NAME@11461..11464 + IDENT@11461..11464 "std" + DOT@11464..11465 "." + NAME@11465..11469 + IDENT@11465..11469 "type" + ARGS_DESC@11469..11476 + L_PAREN@11469..11470 "(" + ARG@11470..11475 + EXPR_VAR@11470..11475 + NAME@11470..11475 + IDENT@11470..11475 "value" + R_PAREN@11475..11476 ")" + COMMA@11476..11477 "," + WHITESPACE@11477..11481 "\n\n " + MEMBER_FIELD@11481..11528 + FIELD_NORMAL@11481..11528 + FIELD_NAME_FIXED@11481..11497 + NAME@11481..11497 + IDENT@11481..11497 "escapeStringJson" + COLONCOLON@11497..11499 "::" + WHITESPACE@11499..11500 " " + EXPR_INTRINSIC@11500..11528 + INTRINSIC@11500..11510 "$intrinsic" + L_PAREN@11510..11511 "(" + NAME@11511..11527 + IDENT@11511..11527 "escapeStringJson" + R_PAREN@11527..11528 ")" + COMMA@11528..11529 "," + WHITESPACE@11529..11533 "\n\n " + MEMBER_FIELD@11533..11588 + FIELD_METHOD@11533..11588 + FIELD_NAME_FIXED@11533..11551 + NAME@11533..11551 + IDENT@11533..11551 "escapeStringPython" + PARAMS_DESC@11551..11556 + L_PAREN@11551..11552 "(" + PARAM@11552..11555 + DESTRUCT_FULL@11552..11555 + NAME@11552..11555 + IDENT@11552..11555 "str" + R_PAREN@11555..11556 ")" + COLONCOLON@11556..11558 "::" + WHITESPACE@11558..11563 "\n " + EXPR_APPLY@11563..11588 + EXPR_INDEX@11563..11583 + EXPR_VAR@11563..11566 + NAME@11563..11566 + IDENT@11563..11566 "std" + DOT@11566..11567 "." + NAME@11567..11583 + IDENT@11567..11583 "escapeStringJson" + ARGS_DESC@11583..11588 + L_PAREN@11583..11584 "(" + ARG@11584..11587 + EXPR_VAR@11584..11587 + NAME@11584..11587 + IDENT@11584..11587 "str" + R_PAREN@11587..11588 ")" + COMMA@11588..11589 "," + WHITESPACE@11589..11593 "\n\n " + MEMBER_FIELD@11593..11810 + FIELD_METHOD@11593..11810 + FIELD_NAME_FIXED@11593..11609 + NAME@11593..11609 + IDENT@11593..11609 "escapeStringBash" + PARAMS_DESC@11609..11615 + L_PAREN@11609..11610 "(" + PARAM@11610..11614 + DESTRUCT_FULL@11610..11614 + NAME@11610..11614 + IDENT@11610..11614 "str_" + R_PAREN@11614..11615 ")" + COLONCOLON@11615..11617 "::" + WHITESPACE@11617..11622 "\n " + EXPR_LOCAL@11622..11810 + LOCAL_KW@11622..11627 "local" + WHITESPACE@11627..11628 " " + BIND_DESTRUCT@11628..11652 + DESTRUCT_FULL@11628..11631 + NAME@11628..11631 + IDENT@11628..11631 "str" + WHITESPACE@11631..11632 " " + ASSIGN@11632..11633 "=" + WHITESPACE@11633..11634 " " + EXPR_APPLY@11634..11652 + EXPR_INDEX@11634..11646 + EXPR_VAR@11634..11637 + NAME@11634..11637 + IDENT@11634..11637 "std" + DOT@11637..11638 "." + NAME@11638..11646 + IDENT@11638..11646 "toString" + ARGS_DESC@11646..11652 + L_PAREN@11646..11647 "(" + ARG@11647..11651 + EXPR_VAR@11647..11651 + NAME@11647..11651 + IDENT@11647..11651 "str_" + R_PAREN@11651..11652 ")" + SEMI@11652..11653 ";" + WHITESPACE@11653..11658 "\n " + EXPR_LOCAL@11658..11810 + LOCAL_KW@11658..11663 "local" + WHITESPACE@11663..11664 " " + BIND_FUNCTION@11664..11739 + NAME@11664..11669 + IDENT@11664..11669 "trans" + PARAMS_DESC@11669..11673 + L_PAREN@11669..11670 "(" + PARAM@11670..11672 + DESTRUCT_FULL@11670..11672 + NAME@11670..11672 + IDENT@11670..11672 "ch" + R_PAREN@11672..11673 ")" + WHITESPACE@11673..11674 " " + ASSIGN@11674..11675 "=" + WHITESPACE@11675..11682 "\n " + EXPR_IF_THEN_ELSE@11682..11739 + IF_KW@11682..11684 "if" + WHITESPACE@11684..11685 " " + EXPR_BINARY@11685..11694 + LHS_EXPR@11685..11687 + EXPR_VAR@11685..11687 + NAME@11685..11687 + IDENT@11685..11687 "ch" + WHITESPACE@11687..11688 " " + EQ@11688..11690 "==" + WHITESPACE@11690..11691 " " + EXPR_STRING@11691..11694 + STRING_DOUBLE@11691..11694 "\"'\"" + WHITESPACE@11694..11695 " " + THEN_KW@11695..11699 "then" + WHITESPACE@11699..11708 "\n " + TRUE_EXPR@11708..11717 + EXPR_STRING@11708..11717 + STRING_DOUBLE@11708..11717 "\"'\\\"'\\\"'\"" + WHITESPACE@11717..11724 "\n " + ELSE_KW@11724..11728 "else" + WHITESPACE@11728..11737 "\n " + FALSE_EXPR@11737..11739 + EXPR_VAR@11737..11739 + NAME@11737..11739 + IDENT@11737..11739 "ch" + SEMI@11739..11740 ";" + WHITESPACE@11740..11745 "\n " + EXPR_BINARY@11745..11810 + LHS_EXPR@11745..11751 + EXPR_STRING@11745..11751 + STRING_DOUBLE@11745..11751 "\"'%s'\"" + WHITESPACE@11751..11752 " " + MODULO@11752..11753 "%" + WHITESPACE@11753..11754 " " + EXPR_APPLY@11754..11810 + EXPR_INDEX@11754..11762 + EXPR_VAR@11754..11757 + NAME@11754..11757 + IDENT@11754..11757 "std" + DOT@11757..11758 "." + NAME@11758..11762 + IDENT@11758..11762 "join" + ARGS_DESC@11762..11810 + L_PAREN@11762..11763 "(" + ARG@11763..11765 + EXPR_STRING@11763..11765 + STRING_SINGLE@11763..11765 "''" + COMMA@11765..11766 "," + WHITESPACE@11766..11767 " " + ARG@11767..11809 + EXPR_ARRAY_COMP@11767..11809 + L_BRACK@11767..11768 "[" + EXPR_APPLY@11768..11777 + EXPR_VAR@11768..11773 + NAME@11768..11773 + IDENT@11768..11773 "trans" + ARGS_DESC@11773..11777 + L_PAREN@11773..11774 "(" + ARG@11774..11776 + EXPR_VAR@11774..11776 + NAME@11774..11776 + IDENT@11774..11776 "ch" + R_PAREN@11776..11777 ")" + WHITESPACE@11777..11778 " " + FOR_SPEC@11778..11808 + FOR_KW@11778..11781 "for" + WHITESPACE@11781..11782 " " + NAME@11782..11784 + IDENT@11782..11784 "ch" + WHITESPACE@11784..11785 " " + IN_KW@11785..11787 "in" + WHITESPACE@11787..11788 " " + EXPR_APPLY@11788..11808 + EXPR_INDEX@11788..11803 + EXPR_VAR@11788..11791 + NAME@11788..11791 + IDENT@11788..11791 "std" + DOT@11791..11792 "." + NAME@11792..11803 + IDENT@11792..11803 "stringChars" + ARGS_DESC@11803..11808 + L_PAREN@11803..11804 "(" + ARG@11804..11807 + EXPR_VAR@11804..11807 + NAME@11804..11807 + IDENT@11804..11807 "str" + R_PAREN@11807..11808 ")" + R_BRACK@11808..11809 "]" + R_PAREN@11809..11810 ")" + COMMA@11810..11811 "," + WHITESPACE@11811..11815 "\n\n " + MEMBER_FIELD@11815..12029 + FIELD_METHOD@11815..12029 + FIELD_NAME_FIXED@11815..11834 + NAME@11815..11834 + IDENT@11815..11834 "escapeStringDollars" + PARAMS_DESC@11834..11840 + L_PAREN@11834..11835 "(" + PARAM@11835..11839 + DESTRUCT_FULL@11835..11839 + NAME@11835..11839 + IDENT@11835..11839 "str_" + R_PAREN@11839..11840 ")" + COLONCOLON@11840..11842 "::" + WHITESPACE@11842..11847 "\n " + EXPR_LOCAL@11847..12029 + LOCAL_KW@11847..11852 "local" + WHITESPACE@11852..11853 " " + BIND_DESTRUCT@11853..11877 + DESTRUCT_FULL@11853..11856 + NAME@11853..11856 + IDENT@11853..11856 "str" + WHITESPACE@11856..11857 " " + ASSIGN@11857..11858 "=" + WHITESPACE@11858..11859 " " + EXPR_APPLY@11859..11877 + EXPR_INDEX@11859..11871 + EXPR_VAR@11859..11862 + NAME@11859..11862 + IDENT@11859..11862 "std" + DOT@11862..11863 "." + NAME@11863..11871 + IDENT@11863..11871 "toString" + ARGS_DESC@11871..11877 + L_PAREN@11871..11872 "(" + ARG@11872..11876 + EXPR_VAR@11872..11876 + NAME@11872..11876 + IDENT@11872..11876 "str_" + R_PAREN@11876..11877 ")" + SEMI@11877..11878 ";" + WHITESPACE@11878..11883 "\n " + EXPR_LOCAL@11883..12029 + LOCAL_KW@11883..11888 "local" + WHITESPACE@11888..11889 " " + BIND_FUNCTION@11889..11959 + NAME@11889..11894 + IDENT@11889..11894 "trans" + PARAMS_DESC@11894..11898 + L_PAREN@11894..11895 "(" + PARAM@11895..11897 + DESTRUCT_FULL@11895..11897 + NAME@11895..11897 + IDENT@11895..11897 "ch" + R_PAREN@11897..11898 ")" + WHITESPACE@11898..11899 " " + ASSIGN@11899..11900 "=" + WHITESPACE@11900..11907 "\n " + EXPR_IF_THEN_ELSE@11907..11959 + IF_KW@11907..11909 "if" + WHITESPACE@11909..11910 " " + EXPR_BINARY@11910..11919 + LHS_EXPR@11910..11912 + EXPR_VAR@11910..11912 + NAME@11910..11912 + IDENT@11910..11912 "ch" + WHITESPACE@11912..11913 " " + EQ@11913..11915 "==" + WHITESPACE@11915..11916 " " + EXPR_STRING@11916..11919 + STRING_SINGLE@11916..11919 "'$'" + WHITESPACE@11919..11920 " " + THEN_KW@11920..11924 "then" + WHITESPACE@11924..11933 "\n " + TRUE_EXPR@11933..11937 + EXPR_STRING@11933..11937 + STRING_SINGLE@11933..11937 "'$$'" + WHITESPACE@11937..11944 "\n " + ELSE_KW@11944..11948 "else" + WHITESPACE@11948..11957 "\n " + FALSE_EXPR@11957..11959 + EXPR_VAR@11957..11959 + NAME@11957..11959 + IDENT@11957..11959 "ch" + SEMI@11959..11960 ";" + WHITESPACE@11960..11965 "\n " + EXPR_APPLY@11965..12029 + EXPR_INDEX@11965..11974 + EXPR_VAR@11965..11968 + NAME@11965..11968 + IDENT@11965..11968 "std" + DOT@11968..11969 "." + NAME@11969..11974 + IDENT@11969..11974 "foldl" + ARGS_DESC@11974..12029 + L_PAREN@11974..11975 "(" + ARG@11975..12002 + EXPR_FUNCTION@11975..12002 + FUNCTION_KW@11975..11983 "function" + PARAMS_DESC@11983..11989 + L_PAREN@11983..11984 "(" + PARAM@11984..11985 + DESTRUCT_FULL@11984..11985 + NAME@11984..11985 + IDENT@11984..11985 "a" + COMMA@11985..11986 "," + WHITESPACE@11986..11987 " " + PARAM@11987..11988 + DESTRUCT_FULL@11987..11988 + NAME@11987..11988 + IDENT@11987..11988 "b" + R_PAREN@11988..11989 ")" + WHITESPACE@11989..11990 " " + EXPR_BINARY@11990..12002 + LHS_EXPR@11990..11991 + EXPR_VAR@11990..11991 + NAME@11990..11991 + IDENT@11990..11991 "a" + WHITESPACE@11991..11992 " " + PLUS@11992..11993 "+" + WHITESPACE@11993..11994 " " + EXPR_APPLY@11994..12002 + EXPR_VAR@11994..11999 + NAME@11994..11999 + IDENT@11994..11999 "trans" + ARGS_DESC@11999..12002 + L_PAREN@11999..12000 "(" + ARG@12000..12001 + EXPR_VAR@12000..12001 + NAME@12000..12001 + IDENT@12000..12001 "b" + R_PAREN@12001..12002 ")" + COMMA@12002..12003 "," + WHITESPACE@12003..12004 " " + ARG@12004..12024 + EXPR_APPLY@12004..12024 + EXPR_INDEX@12004..12019 + EXPR_VAR@12004..12007 + NAME@12004..12007 + IDENT@12004..12007 "std" + DOT@12007..12008 "." + NAME@12008..12019 + IDENT@12008..12019 "stringChars" + ARGS_DESC@12019..12024 + L_PAREN@12019..12020 "(" + ARG@12020..12023 + EXPR_VAR@12020..12023 + NAME@12020..12023 + IDENT@12020..12023 "str" + R_PAREN@12023..12024 ")" + COMMA@12024..12025 "," + WHITESPACE@12025..12026 " " + ARG@12026..12028 + EXPR_STRING@12026..12028 + STRING_SINGLE@12026..12028 "''" + R_PAREN@12028..12029 ")" + COMMA@12029..12030 "," + WHITESPACE@12030..12034 "\n\n " + MEMBER_FIELD@12034..12100 + FIELD_METHOD@12034..12100 + FIELD_NAME_FIXED@12034..12046 + NAME@12034..12046 + IDENT@12034..12046 "manifestJson" + PARAMS_DESC@12046..12053 + L_PAREN@12046..12047 "(" + PARAM@12047..12052 + DESTRUCT_FULL@12047..12052 + NAME@12047..12052 + IDENT@12047..12052 "value" + R_PAREN@12052..12053 ")" + COLONCOLON@12053..12055 "::" + WHITESPACE@12055..12056 " " + EXPR_APPLY@12056..12100 + EXPR_INDEX@12056..12074 + EXPR_VAR@12056..12059 + NAME@12056..12059 + IDENT@12056..12059 "std" + DOT@12059..12060 "." + NAME@12060..12074 + IDENT@12060..12074 "manifestJsonEx" + ARGS_DESC@12074..12100 + L_PAREN@12074..12075 "(" + ARG@12075..12080 + EXPR_VAR@12075..12080 + NAME@12075..12080 + IDENT@12075..12080 "value" + COMMA@12080..12081 "," + WHITESPACE@12081..12082 " " + ARG@12082..12088 + EXPR_STRING@12082..12088 + STRING_SINGLE@12082..12088 "' '" + R_PAREN@12088..12089 ")" + WHITESPACE@12089..12090 " " + TAILSTRICT_KW@12090..12100 "tailstrict" + COMMA@12100..12101 "," + WHITESPACE@12101..12105 "\n\n " + MEMBER_FIELD@12105..12173 + FIELD_METHOD@12105..12173 + FIELD_NAME_FIXED@12105..12125 + NAME@12105..12125 + IDENT@12105..12125 "manifestJsonMinified" + PARAMS_DESC@12125..12132 + L_PAREN@12125..12126 "(" + PARAM@12126..12131 + DESTRUCT_FULL@12126..12131 + NAME@12126..12131 + IDENT@12126..12131 "value" + R_PAREN@12131..12132 ")" + COLONCOLON@12132..12134 "::" + WHITESPACE@12134..12135 " " + EXPR_APPLY@12135..12173 + EXPR_INDEX@12135..12153 + EXPR_VAR@12135..12138 + NAME@12135..12138 + IDENT@12135..12138 "std" + DOT@12138..12139 "." + NAME@12139..12153 + IDENT@12139..12153 "manifestJsonEx" + ARGS_DESC@12153..12173 + L_PAREN@12153..12154 "(" + ARG@12154..12159 + EXPR_VAR@12154..12159 + NAME@12154..12159 + IDENT@12154..12159 "value" + COMMA@12159..12160 "," + WHITESPACE@12160..12161 " " + ARG@12161..12163 + EXPR_STRING@12161..12163 + STRING_SINGLE@12161..12163 "''" + COMMA@12163..12164 "," + WHITESPACE@12164..12165 " " + ARG@12165..12167 + EXPR_STRING@12165..12167 + STRING_SINGLE@12165..12167 "''" + COMMA@12167..12168 "," + WHITESPACE@12168..12169 " " + ARG@12169..12172 + EXPR_STRING@12169..12172 + STRING_SINGLE@12169..12172 "':'" + R_PAREN@12172..12173 ")" + COMMA@12173..12174 "," + WHITESPACE@12174..12178 "\n\n " + MEMBER_FIELD@12178..12221 + FIELD_NORMAL@12178..12221 + FIELD_NAME_FIXED@12178..12192 + NAME@12178..12192 + IDENT@12178..12192 "manifestJsonEx" + COLONCOLON@12192..12194 "::" + WHITESPACE@12194..12195 " " + EXPR_INTRINSIC@12195..12221 + INTRINSIC@12195..12205 "$intrinsic" + L_PAREN@12205..12206 "(" + NAME@12206..12220 + IDENT@12206..12220 "manifestJsonEx" + R_PAREN@12220..12221 ")" + COMMA@12221..12222 "," + WHITESPACE@12222..12226 "\n\n " + MEMBER_FIELD@12226..12271 + FIELD_NORMAL@12226..12271 + FIELD_NAME_FIXED@12226..12241 + NAME@12226..12241 + IDENT@12226..12241 "manifestYamlDoc" + COLONCOLON@12241..12243 "::" + WHITESPACE@12243..12244 " " + EXPR_INTRINSIC@12244..12271 + INTRINSIC@12244..12254 "$intrinsic" + L_PAREN@12254..12255 "(" + NAME@12255..12270 + IDENT@12255..12270 "manifestYamlDoc" + R_PAREN@12270..12271 ")" + COMMA@12271..12272 "," + WHITESPACE@12272..12276 "\n\n " + MEMBER_FIELD@12276..12632 + FIELD_METHOD@12276..12632 + FIELD_NAME_FIXED@12276..12294 + NAME@12276..12294 + IDENT@12276..12294 "manifestYamlStream" + PARAMS_DESC@12294..12352 + L_PAREN@12294..12295 "(" + PARAM@12295..12300 + DESTRUCT_FULL@12295..12300 + NAME@12295..12300 + IDENT@12295..12300 "value" + COMMA@12300..12301 "," + WHITESPACE@12301..12302 " " + PARAM@12302..12330 + DESTRUCT_FULL@12302..12324 + NAME@12302..12324 + IDENT@12302..12324 "indent_array_in_object" + ASSIGN@12324..12325 "=" + EXPR_LITERAL@12325..12330 + FALSE_KW@12325..12330 "false" + COMMA@12330..12331 "," + WHITESPACE@12331..12332 " " + PARAM@12332..12351 + DESTRUCT_FULL@12332..12346 + NAME@12332..12346 + IDENT@12332..12346 "c_document_end" + ASSIGN@12346..12347 "=" + EXPR_LITERAL@12347..12351 + TRUE_KW@12347..12351 "true" + R_PAREN@12351..12352 ")" + COLONCOLON@12352..12354 "::" + WHITESPACE@12354..12359 "\n " + EXPR_IF_THEN_ELSE@12359..12632 + IF_KW@12359..12361 "if" + WHITESPACE@12361..12362 " " + EXPR_UNARY@12362..12381 + NOT@12362..12363 "!" + EXPR_APPLY@12363..12381 + EXPR_INDEX@12363..12374 + EXPR_VAR@12363..12366 + NAME@12363..12366 + IDENT@12363..12366 "std" + DOT@12366..12367 "." + NAME@12367..12374 + IDENT@12367..12374 "isArray" + ARGS_DESC@12374..12381 + L_PAREN@12374..12375 "(" + ARG@12375..12380 + EXPR_VAR@12375..12380 + NAME@12375..12380 + IDENT@12375..12380 "value" + R_PAREN@12380..12381 ")" + WHITESPACE@12381..12382 " " + THEN_KW@12382..12386 "then" + WHITESPACE@12386..12393 "\n " + TRUE_EXPR@12393..12461 + EXPR_ERROR@12393..12461 + ERROR_KW@12393..12398 "error" + WHITESPACE@12398..12399 " " + EXPR_BINARY@12399..12461 + LHS_EXPR@12399..12443 + EXPR_STRING@12399..12443 + STRING_SINGLE@12399..12443 "'manifestYamlStream o ..." + WHITESPACE@12443..12444 " " + PLUS@12444..12445 "+" + WHITESPACE@12445..12446 " " + EXPR_APPLY@12446..12461 + EXPR_INDEX@12446..12454 + EXPR_VAR@12446..12449 + NAME@12446..12449 + IDENT@12446..12449 "std" + DOT@12449..12450 "." + NAME@12450..12454 + IDENT@12450..12454 "type" + ARGS_DESC@12454..12461 + L_PAREN@12454..12455 "(" + ARG@12455..12460 + EXPR_VAR@12455..12460 + NAME@12455..12460 + IDENT@12455..12460 "value" + R_PAREN@12460..12461 ")" + WHITESPACE@12461..12466 "\n " + ELSE_KW@12466..12470 "else" + WHITESPACE@12470..12477 "\n " + FALSE_EXPR@12477..12632 + EXPR_BINARY@12477..12632 + LHS_EXPR@12477..12587 + EXPR_BINARY@12477..12587 + LHS_EXPR@12477..12484 + EXPR_STRING@12477..12484 + STRING_SINGLE@12477..12484 "'---\\n'" + WHITESPACE@12484..12485 " " + PLUS@12485..12486 "+" + WHITESPACE@12486..12487 " " + EXPR_APPLY@12487..12587 + EXPR_INDEX@12487..12495 + EXPR_VAR@12487..12490 + NAME@12487..12490 + IDENT@12487..12490 "std" + DOT@12490..12491 "." + NAME@12491..12495 + IDENT@12491..12495 "join" + ARGS_DESC@12495..12587 + L_PAREN@12495..12496 "(" + WHITESPACE@12496..12505 "\n " + ARG@12505..12514 + EXPR_STRING@12505..12514 + STRING_SINGLE@12505..12514 "'\\n---\\n'" + COMMA@12514..12515 "," + WHITESPACE@12515..12516 " " + ARG@12516..12579 + EXPR_ARRAY_COMP@12516..12579 + L_BRACK@12516..12517 "[" + EXPR_APPLY@12517..12563 + EXPR_INDEX@12517..12536 + EXPR_VAR@12517..12520 + NAME@12517..12520 + IDENT@12517..12520 "std" + DOT@12520..12521 "." + NAME@12521..12536 + IDENT@12521..12536 "manifestYamlDoc" + ARGS_DESC@12536..12563 + L_PAREN@12536..12537 "(" + ARG@12537..12538 + EXPR_VAR@12537..12538 + NAME@12537..12538 + IDENT@12537..12538 "e" + COMMA@12538..12539 "," + WHITESPACE@12539..12540 " " + ARG@12540..12562 + EXPR_VAR@12540..12562 + NAME@12540..12562 + IDENT@12540..12562 "indent_array_in_object" + R_PAREN@12562..12563 ")" + WHITESPACE@12563..12564 " " + FOR_SPEC@12564..12578 + FOR_KW@12564..12567 "for" + WHITESPACE@12567..12568 " " + NAME@12568..12569 + IDENT@12568..12569 "e" + WHITESPACE@12569..12570 " " + IN_KW@12570..12572 "in" + WHITESPACE@12572..12573 " " + EXPR_VAR@12573..12578 + NAME@12573..12578 + IDENT@12573..12578 "value" + R_BRACK@12578..12579 "]" + WHITESPACE@12579..12586 "\n " + R_PAREN@12586..12587 ")" + WHITESPACE@12587..12588 " " + PLUS@12588..12589 "+" + WHITESPACE@12589..12590 " " + EXPR_IF_THEN_ELSE@12590..12632 + IF_KW@12590..12592 "if" + WHITESPACE@12592..12593 " " + EXPR_VAR@12593..12607 + NAME@12593..12607 + IDENT@12593..12607 "c_document_end" + WHITESPACE@12607..12608 " " + THEN_KW@12608..12612 "then" + WHITESPACE@12612..12613 " " + TRUE_EXPR@12613..12622 + EXPR_STRING@12613..12622 + STRING_SINGLE@12613..12622 "'\\n...\\n'" + WHITESPACE@12622..12623 " " + ELSE_KW@12623..12627 "else" + WHITESPACE@12627..12628 " " + FALSE_EXPR@12628..12632 + EXPR_STRING@12628..12632 + STRING_SINGLE@12628..12632 "'\\n'" + COMMA@12632..12633 "," + WHITESPACE@12633..12638 "\n\n\n " + MEMBER_FIELD@12638..13294 + FIELD_METHOD@12638..13294 + FIELD_NAME_FIXED@12638..12652 + NAME@12638..12652 + IDENT@12638..12652 "manifestPython" + PARAMS_DESC@12652..12655 + L_PAREN@12652..12653 "(" + PARAM@12653..12654 + DESTRUCT_FULL@12653..12654 + NAME@12653..12654 + IDENT@12653..12654 "v" + R_PAREN@12654..12655 ")" + COLONCOLON@12655..12657 "::" + WHITESPACE@12657..12662 "\n " + EXPR_IF_THEN_ELSE@12662..13294 + IF_KW@12662..12664 "if" + WHITESPACE@12664..12665 " " + EXPR_APPLY@12665..12680 + EXPR_INDEX@12665..12677 + EXPR_VAR@12665..12668 + NAME@12665..12668 + IDENT@12665..12668 "std" + DOT@12668..12669 "." + NAME@12669..12677 + IDENT@12669..12677 "isObject" + ARGS_DESC@12677..12680 + L_PAREN@12677..12678 "(" + ARG@12678..12679 + EXPR_VAR@12678..12679 + NAME@12678..12679 + IDENT@12678..12679 "v" + R_PAREN@12679..12680 ")" + WHITESPACE@12680..12681 " " + THEN_KW@12681..12685 "then" + WHITESPACE@12685..12692 "\n " + TRUE_EXPR@12692..12867 + EXPR_LOCAL@12692..12867 + LOCAL_KW@12692..12697 "local" + WHITESPACE@12697..12698 " " + BIND_DESTRUCT@12698..12826 + DESTRUCT_FULL@12698..12704 + NAME@12698..12704 + IDENT@12698..12704 "fields" + WHITESPACE@12704..12705 " " + ASSIGN@12705..12706 "=" + WHITESPACE@12706..12707 " " + EXPR_ARRAY_COMP@12707..12826 + L_BRACK@12707..12708 "[" + WHITESPACE@12708..12717 "\n " + EXPR_BINARY@12717..12781 + LHS_EXPR@12717..12725 + EXPR_STRING@12717..12725 + STRING_SINGLE@12717..12725 "'%s: %s'" + WHITESPACE@12725..12726 " " + MODULO@12726..12727 "%" + WHITESPACE@12727..12728 " " + EXPR_ARRAY@12728..12781 + L_BRACK@12728..12729 "[" + EXPR_APPLY@12729..12754 + EXPR_INDEX@12729..12751 + EXPR_VAR@12729..12732 + NAME@12729..12732 + IDENT@12729..12732 "std" + DOT@12732..12733 "." + NAME@12733..12751 + IDENT@12733..12751 "escapeStringPython" + ARGS_DESC@12751..12754 + L_PAREN@12751..12752 "(" + ARG@12752..12753 + EXPR_VAR@12752..12753 + NAME@12752..12753 + IDENT@12752..12753 "k" + R_PAREN@12753..12754 ")" + COMMA@12754..12755 "," + WHITESPACE@12755..12756 " " + EXPR_APPLY@12756..12780 + EXPR_INDEX@12756..12774 + EXPR_VAR@12756..12759 + NAME@12756..12759 + IDENT@12756..12759 "std" + DOT@12759..12760 "." + NAME@12760..12774 + IDENT@12760..12774 "manifestPython" + ARGS_DESC@12774..12780 + L_PAREN@12774..12775 "(" + ARG@12775..12779 + EXPR_INDEX_EXPR@12775..12779 + LHS_EXPR@12775..12776 + EXPR_VAR@12775..12776 + NAME@12775..12776 + IDENT@12775..12776 "v" + L_BRACK@12776..12777 "[" + EXPR_VAR@12777..12778 + NAME@12777..12778 + IDENT@12777..12778 "k" + R_BRACK@12778..12779 "]" + R_PAREN@12779..12780 ")" + R_BRACK@12780..12781 "]" + WHITESPACE@12781..12790 "\n " + FOR_SPEC@12790..12818 + FOR_KW@12790..12793 "for" + WHITESPACE@12793..12794 " " + NAME@12794..12795 + IDENT@12794..12795 "k" + WHITESPACE@12795..12796 " " + IN_KW@12796..12798 "in" + WHITESPACE@12798..12799 " " + EXPR_APPLY@12799..12818 + EXPR_INDEX@12799..12815 + EXPR_VAR@12799..12802 + NAME@12799..12802 + IDENT@12799..12802 "std" + DOT@12802..12803 "." + NAME@12803..12815 + IDENT@12803..12815 "objectFields" + ARGS_DESC@12815..12818 + L_PAREN@12815..12816 "(" + ARG@12816..12817 + EXPR_VAR@12816..12817 + NAME@12816..12817 + IDENT@12816..12817 "v" + R_PAREN@12817..12818 ")" + WHITESPACE@12818..12825 "\n " + R_BRACK@12825..12826 "]" + SEMI@12826..12827 ";" + WHITESPACE@12827..12834 "\n " + EXPR_BINARY@12834..12867 + LHS_EXPR@12834..12840 + EXPR_STRING@12834..12840 + STRING_SINGLE@12834..12840 "'{%s}'" + WHITESPACE@12840..12841 " " + MODULO@12841..12842 "%" + WHITESPACE@12842..12843 " " + EXPR_ARRAY@12843..12867 + L_BRACK@12843..12844 "[" + EXPR_APPLY@12844..12866 + EXPR_INDEX@12844..12852 + EXPR_VAR@12844..12847 + NAME@12844..12847 + IDENT@12844..12847 "std" + DOT@12847..12848 "." + NAME@12848..12852 + IDENT@12848..12852 "join" + ARGS_DESC@12852..12866 + L_PAREN@12852..12853 "(" + ARG@12853..12857 + EXPR_STRING@12853..12857 + STRING_SINGLE@12853..12857 "', '" + COMMA@12857..12858 "," + WHITESPACE@12858..12859 " " + ARG@12859..12865 + EXPR_VAR@12859..12865 + NAME@12859..12865 + IDENT@12859..12865 "fields" + R_PAREN@12865..12866 ")" + R_BRACK@12866..12867 "]" + WHITESPACE@12867..12872 "\n " + ELSE_KW@12872..12876 "else" + WHITESPACE@12876..12877 " " + FALSE_EXPR@12877..13294 + EXPR_IF_THEN_ELSE@12877..13294 + IF_KW@12877..12879 "if" + WHITESPACE@12879..12880 " " + EXPR_APPLY@12880..12894 + EXPR_INDEX@12880..12891 + EXPR_VAR@12880..12883 + NAME@12880..12883 + IDENT@12880..12883 "std" + DOT@12883..12884 "." + NAME@12884..12891 + IDENT@12884..12891 "isArray" + ARGS_DESC@12891..12894 + L_PAREN@12891..12892 "(" + ARG@12892..12893 + EXPR_VAR@12892..12893 + NAME@12892..12893 + IDENT@12892..12893 "v" + R_PAREN@12893..12894 ")" + WHITESPACE@12894..12895 " " + THEN_KW@12895..12899 "then" + WHITESPACE@12899..12906 "\n " + TRUE_EXPR@12906..12969 + EXPR_BINARY@12906..12969 + LHS_EXPR@12906..12912 + EXPR_STRING@12906..12912 + STRING_SINGLE@12906..12912 "'[%s]'" + WHITESPACE@12912..12913 " " + MODULO@12913..12914 "%" + WHITESPACE@12914..12915 " " + EXPR_ARRAY@12915..12969 + L_BRACK@12915..12916 "[" + EXPR_APPLY@12916..12968 + EXPR_INDEX@12916..12924 + EXPR_VAR@12916..12919 + NAME@12916..12919 + IDENT@12916..12919 "std" + DOT@12919..12920 "." + NAME@12920..12924 + IDENT@12920..12924 "join" + ARGS_DESC@12924..12968 + L_PAREN@12924..12925 "(" + ARG@12925..12929 + EXPR_STRING@12925..12929 + STRING_SINGLE@12925..12929 "', '" + COMMA@12929..12930 "," + WHITESPACE@12930..12931 " " + ARG@12931..12967 + EXPR_ARRAY_COMP@12931..12967 + L_BRACK@12931..12932 "[" + EXPR_APPLY@12932..12954 + EXPR_INDEX@12932..12950 + EXPR_VAR@12932..12935 + NAME@12932..12935 + IDENT@12932..12935 "std" + DOT@12935..12936 "." + NAME@12936..12950 + IDENT@12936..12950 "manifestPython" + ARGS_DESC@12950..12954 + L_PAREN@12950..12951 "(" + ARG@12951..12953 + EXPR_VAR@12951..12953 + NAME@12951..12953 + IDENT@12951..12953 "v2" + R_PAREN@12953..12954 ")" + WHITESPACE@12954..12955 " " + FOR_SPEC@12955..12966 + FOR_KW@12955..12958 "for" + WHITESPACE@12958..12959 " " + NAME@12959..12961 + IDENT@12959..12961 "v2" + WHITESPACE@12961..12962 " " + IN_KW@12962..12964 "in" + WHITESPACE@12964..12965 " " + EXPR_VAR@12965..12966 + NAME@12965..12966 + IDENT@12965..12966 "v" + R_BRACK@12966..12967 "]" + R_PAREN@12967..12968 ")" + R_BRACK@12968..12969 "]" + WHITESPACE@12969..12974 "\n " + ELSE_KW@12974..12978 "else" + WHITESPACE@12978..12979 " " + FALSE_EXPR@12979..13294 + EXPR_IF_THEN_ELSE@12979..13294 + IF_KW@12979..12981 "if" + WHITESPACE@12981..12982 " " + EXPR_APPLY@12982..12997 + EXPR_INDEX@12982..12994 + EXPR_VAR@12982..12985 + NAME@12982..12985 + IDENT@12982..12985 "std" + DOT@12985..12986 "." + NAME@12986..12994 + IDENT@12986..12994 "isString" + ARGS_DESC@12994..12997 + L_PAREN@12994..12995 "(" + ARG@12995..12996 + EXPR_VAR@12995..12996 + NAME@12995..12996 + IDENT@12995..12996 "v" + R_PAREN@12996..12997 ")" + WHITESPACE@12997..12998 " " + THEN_KW@12998..13002 "then" + WHITESPACE@13002..13009 "\n " + TRUE_EXPR@13009..13043 + EXPR_BINARY@13009..13043 + LHS_EXPR@13009..13013 + EXPR_STRING@13009..13013 + STRING_SINGLE@13009..13013 "'%s'" + WHITESPACE@13013..13014 " " + MODULO@13014..13015 "%" + WHITESPACE@13015..13016 " " + EXPR_ARRAY@13016..13043 + L_BRACK@13016..13017 "[" + EXPR_APPLY@13017..13042 + EXPR_INDEX@13017..13039 + EXPR_VAR@13017..13020 + NAME@13017..13020 + IDENT@13017..13020 "std" + DOT@13020..13021 "." + NAME@13021..13039 + IDENT@13021..13039 "escapeStringPython" + ARGS_DESC@13039..13042 + L_PAREN@13039..13040 "(" + ARG@13040..13041 + EXPR_VAR@13040..13041 + NAME@13040..13041 + IDENT@13040..13041 "v" + R_PAREN@13041..13042 ")" + R_BRACK@13042..13043 "]" + WHITESPACE@13043..13048 "\n " + ELSE_KW@13048..13052 "else" + WHITESPACE@13052..13053 " " + FALSE_EXPR@13053..13294 + EXPR_IF_THEN_ELSE@13053..13294 + IF_KW@13053..13055 "if" + WHITESPACE@13055..13056 " " + EXPR_APPLY@13056..13073 + EXPR_INDEX@13056..13070 + EXPR_VAR@13056..13059 + NAME@13056..13059 + IDENT@13056..13059 "std" + DOT@13059..13060 "." + NAME@13060..13070 + IDENT@13060..13070 "isFunction" + ARGS_DESC@13070..13073 + L_PAREN@13070..13071 "(" + ARG@13071..13072 + EXPR_VAR@13071..13072 + NAME@13071..13072 + IDENT@13071..13072 "v" + R_PAREN@13072..13073 ")" + WHITESPACE@13073..13074 " " + THEN_KW@13074..13078 "then" + WHITESPACE@13078..13085 "\n " + TRUE_EXPR@13085..13117 + EXPR_ERROR@13085..13117 + ERROR_KW@13085..13090 "error" + WHITESPACE@13090..13091 " " + EXPR_STRING@13091..13117 + STRING_SINGLE@13091..13117 "'cannot manifest func ..." + WHITESPACE@13117..13122 "\n " + ELSE_KW@13122..13126 "else" + WHITESPACE@13126..13127 " " + FALSE_EXPR@13127..13294 + EXPR_IF_THEN_ELSE@13127..13294 + IF_KW@13127..13129 "if" + WHITESPACE@13129..13130 " " + EXPR_APPLY@13130..13145 + EXPR_INDEX@13130..13142 + EXPR_VAR@13130..13133 + NAME@13130..13133 + IDENT@13130..13133 "std" + DOT@13133..13134 "." + NAME@13134..13142 + IDENT@13134..13142 "isNumber" + ARGS_DESC@13142..13145 + L_PAREN@13142..13143 "(" + ARG@13143..13144 + EXPR_VAR@13143..13144 + NAME@13143..13144 + IDENT@13143..13144 "v" + R_PAREN@13144..13145 ")" + WHITESPACE@13145..13146 " " + THEN_KW@13146..13150 "then" + WHITESPACE@13150..13157 "\n " + TRUE_EXPR@13157..13172 + EXPR_APPLY@13157..13172 + EXPR_INDEX@13157..13169 + EXPR_VAR@13157..13160 + NAME@13157..13160 + IDENT@13157..13160 "std" + DOT@13160..13161 "." + NAME@13161..13169 + IDENT@13161..13169 "toString" + ARGS_DESC@13169..13172 + L_PAREN@13169..13170 "(" + ARG@13170..13171 + EXPR_VAR@13170..13171 + NAME@13170..13171 + IDENT@13170..13171 "v" + R_PAREN@13171..13172 ")" + WHITESPACE@13172..13177 "\n " + ELSE_KW@13177..13181 "else" + WHITESPACE@13181..13182 " " + FALSE_EXPR@13182..13294 + EXPR_IF_THEN_ELSE@13182..13294 + IF_KW@13182..13184 "if" + WHITESPACE@13184..13185 " " + EXPR_BINARY@13185..13194 + LHS_EXPR@13185..13186 + EXPR_VAR@13185..13186 + NAME@13185..13186 + IDENT@13185..13186 "v" + WHITESPACE@13186..13187 " " + EQ@13187..13189 "==" + WHITESPACE@13189..13190 " " + EXPR_LITERAL@13190..13194 + TRUE_KW@13190..13194 "true" + WHITESPACE@13194..13195 " " + THEN_KW@13195..13199 "then" + WHITESPACE@13199..13206 "\n " + TRUE_EXPR@13206..13212 + EXPR_STRING@13206..13212 + STRING_SINGLE@13206..13212 "'True'" + WHITESPACE@13212..13217 "\n " + ELSE_KW@13217..13221 "else" + WHITESPACE@13221..13222 " " + FALSE_EXPR@13222..13294 + EXPR_IF_THEN_ELSE@13222..13294 + IF_KW@13222..13224 "if" + WHITESPACE@13224..13225 " " + EXPR_BINARY@13225..13235 + LHS_EXPR@13225..13226 + EXPR_VAR@13225..13226 + NAME@13225..13226 + IDENT@13225..13226 "v" + WHITESPACE@13226..13227 " " + EQ@13227..13229 "==" + WHITESPACE@13229..13230 " " + EXPR_LITERAL@13230..13235 + FALSE_KW@13230..13235 "false" + WHITESPACE@13235..13236 " " + THEN_KW@13236..13240 "then" + WHITESPACE@13240..13247 "\n " + TRUE_EXPR@13247..13254 + EXPR_STRING@13247..13254 + STRING_SINGLE@13247..13254 "'False'" + WHITESPACE@13254..13259 "\n " + ELSE_KW@13259..13263 "else" + WHITESPACE@13263..13264 " " + FALSE_EXPR@13264..13294 + EXPR_IF_THEN_ELSE@13264..13294 + IF_KW@13264..13266 "if" + WHITESPACE@13266..13267 " " + EXPR_BINARY@13267..13276 + LHS_EXPR@13267..13268 + EXPR_VAR@13267..13268 + NAME@13267..13268 + IDENT@13267..13268 "v" + WHITESPACE@13268..13269 " " + EQ@13269..13271 "==" + WHITESPACE@13271..13272 " " + EXPR_LITERAL@13272..13276 + NULL_KW@13272..13276 "null" + WHITESPACE@13276..13277 " " + THEN_KW@13277..13281 "then" + WHITESPACE@13281..13288 "\n " + TRUE_EXPR@13288..13294 + EXPR_STRING@13288..13294 + STRING_SINGLE@13288..13294 "'None'" + COMMA@13294..13295 "," + WHITESPACE@13295..13299 "\n\n " + MEMBER_FIELD@13299..13454 + FIELD_METHOD@13299..13454 + FIELD_NAME_FIXED@13299..13317 + NAME@13299..13317 + IDENT@13299..13317 "manifestPythonVars" + PARAMS_DESC@13317..13323 + L_PAREN@13317..13318 "(" + PARAM@13318..13322 + DESTRUCT_FULL@13318..13322 + NAME@13318..13322 + IDENT@13318..13322 "conf" + R_PAREN@13322..13323 ")" + COLONCOLON@13323..13325 "::" + WHITESPACE@13325..13330 "\n " + EXPR_LOCAL@13330..13454 + LOCAL_KW@13330..13335 "local" + WHITESPACE@13335..13336 " " + BIND_DESTRUCT@13336..13421 + DESTRUCT_FULL@13336..13340 + NAME@13336..13340 + IDENT@13336..13340 "vars" + WHITESPACE@13340..13341 " " + ASSIGN@13341..13342 "=" + WHITESPACE@13342..13343 " " + EXPR_ARRAY_COMP@13343..13421 + L_BRACK@13343..13344 "[" + EXPR_BINARY@13344..13388 + LHS_EXPR@13344..13353 + EXPR_STRING@13344..13353 + STRING_SINGLE@13344..13353 "'%s = %s'" + WHITESPACE@13353..13354 " " + MODULO@13354..13355 "%" + WHITESPACE@13355..13356 " " + EXPR_ARRAY@13356..13388 + L_BRACK@13356..13357 "[" + EXPR_VAR@13357..13358 + NAME@13357..13358 + IDENT@13357..13358 "k" + COMMA@13358..13359 "," + WHITESPACE@13359..13360 " " + EXPR_APPLY@13360..13387 + EXPR_INDEX@13360..13378 + EXPR_VAR@13360..13363 + NAME@13360..13363 + IDENT@13360..13363 "std" + DOT@13363..13364 "." + NAME@13364..13378 + IDENT@13364..13378 "manifestPython" + ARGS_DESC@13378..13387 + L_PAREN@13378..13379 "(" + ARG@13379..13386 + EXPR_INDEX_EXPR@13379..13386 + LHS_EXPR@13379..13383 + EXPR_VAR@13379..13383 + NAME@13379..13383 + IDENT@13379..13383 "conf" + L_BRACK@13383..13384 "[" + EXPR_VAR@13384..13385 + NAME@13384..13385 + IDENT@13384..13385 "k" + R_BRACK@13385..13386 "]" + R_PAREN@13386..13387 ")" + R_BRACK@13387..13388 "]" + WHITESPACE@13388..13389 " " + FOR_SPEC@13389..13420 + FOR_KW@13389..13392 "for" + WHITESPACE@13392..13393 " " + NAME@13393..13394 + IDENT@13393..13394 "k" + WHITESPACE@13394..13395 " " + IN_KW@13395..13397 "in" + WHITESPACE@13397..13398 " " + EXPR_APPLY@13398..13420 + EXPR_INDEX@13398..13414 + EXPR_VAR@13398..13401 + NAME@13398..13401 + IDENT@13398..13401 "std" + DOT@13401..13402 "." + NAME@13402..13414 + IDENT@13402..13414 "objectFields" + ARGS_DESC@13414..13420 + L_PAREN@13414..13415 "(" + ARG@13415..13419 + EXPR_VAR@13415..13419 + NAME@13415..13419 + IDENT@13415..13419 "conf" + R_PAREN@13419..13420 ")" + R_BRACK@13420..13421 "]" + SEMI@13421..13422 ";" + WHITESPACE@13422..13427 "\n " + EXPR_APPLY@13427..13454 + EXPR_INDEX@13427..13435 + EXPR_VAR@13427..13430 + NAME@13427..13430 + IDENT@13427..13430 "std" + DOT@13430..13431 "." + NAME@13431..13435 + IDENT@13431..13435 "join" + ARGS_DESC@13435..13454 + L_PAREN@13435..13436 "(" + ARG@13436..13440 + EXPR_STRING@13436..13440 + STRING_SINGLE@13436..13440 "'\\n'" + COMMA@13440..13441 "," + WHITESPACE@13441..13442 " " + ARG@13442..13453 + EXPR_BINARY@13442..13453 + LHS_EXPR@13442..13446 + EXPR_VAR@13442..13446 + NAME@13442..13446 + IDENT@13442..13446 "vars" + WHITESPACE@13446..13447 " " + PLUS@13447..13448 "+" + WHITESPACE@13448..13449 " " + EXPR_ARRAY@13449..13453 + L_BRACK@13449..13450 "[" + EXPR_STRING@13450..13452 + STRING_SINGLE@13450..13452 "''" + R_BRACK@13452..13453 "]" + R_PAREN@13453..13454 ")" + COMMA@13454..13455 "," + WHITESPACE@13455..13459 "\n\n " + MEMBER_FIELD@13459..14126 + FIELD_METHOD@13459..14126 + FIELD_NAME_FIXED@13459..13476 + NAME@13459..13476 + IDENT@13459..13476 "manifestXmlJsonml" + PARAMS_DESC@13476..13483 + L_PAREN@13476..13477 "(" + PARAM@13477..13482 + DESTRUCT_FULL@13477..13482 + NAME@13477..13482 + IDENT@13477..13482 "value" + R_PAREN@13482..13483 ")" + COLONCOLON@13483..13485 "::" + WHITESPACE@13485..13490 "\n " + EXPR_IF_THEN_ELSE@13490..14126 + IF_KW@13490..13492 "if" + WHITESPACE@13492..13493 " " + EXPR_UNARY@13493..13512 + NOT@13493..13494 "!" + EXPR_APPLY@13494..13512 + EXPR_INDEX@13494..13505 + EXPR_VAR@13494..13497 + NAME@13494..13497 + IDENT@13494..13497 "std" + DOT@13497..13498 "." + NAME@13498..13505 + IDENT@13498..13505 "isArray" + ARGS_DESC@13505..13512 + L_PAREN@13505..13506 "(" + ARG@13506..13511 + EXPR_VAR@13506..13511 + NAME@13506..13511 + IDENT@13506..13511 "value" + R_PAREN@13511..13512 ")" + WHITESPACE@13512..13513 " " + THEN_KW@13513..13517 "then" + WHITESPACE@13517..13524 "\n " + TRUE_EXPR@13524..13592 + EXPR_ERROR@13524..13592 + ERROR_KW@13524..13529 "error" + WHITESPACE@13529..13530 " " + EXPR_BINARY@13530..13592 + LHS_EXPR@13530..13574 + EXPR_STRING@13530..13574 + STRING_SINGLE@13530..13574 "'Expected a JSONML va ..." + WHITESPACE@13574..13575 " " + MODULO@13575..13576 "%" + WHITESPACE@13576..13577 " " + EXPR_APPLY@13577..13592 + EXPR_INDEX@13577..13585 + EXPR_VAR@13577..13580 + NAME@13577..13580 + IDENT@13577..13580 "std" + DOT@13580..13581 "." + NAME@13581..13585 + IDENT@13581..13585 "type" + ARGS_DESC@13585..13592 + L_PAREN@13585..13586 "(" + ARG@13586..13591 + EXPR_VAR@13586..13591 + NAME@13586..13591 + IDENT@13586..13591 "value" + R_PAREN@13591..13592 ")" + WHITESPACE@13592..13597 "\n " + ELSE_KW@13597..13601 "else" + WHITESPACE@13601..13608 "\n " + FALSE_EXPR@13608..14126 + EXPR_LOCAL@13608..14126 + LOCAL_KW@13608..13613 "local" + WHITESPACE@13613..13614 " " + BIND_FUNCTION@13614..14107 + NAME@13614..13617 + IDENT@13614..13617 "aux" + PARAMS_DESC@13617..13620 + L_PAREN@13617..13618 "(" + PARAM@13618..13619 + DESTRUCT_FULL@13618..13619 + NAME@13618..13619 + IDENT@13618..13619 "v" + R_PAREN@13619..13620 ")" + WHITESPACE@13620..13621 " " + ASSIGN@13621..13622 "=" + WHITESPACE@13622..13631 "\n " + EXPR_IF_THEN_ELSE@13631..14107 + IF_KW@13631..13633 "if" + WHITESPACE@13633..13634 " " + EXPR_APPLY@13634..13649 + EXPR_INDEX@13634..13646 + EXPR_VAR@13634..13637 + NAME@13634..13637 + IDENT@13634..13637 "std" + DOT@13637..13638 "." + NAME@13638..13646 + IDENT@13638..13646 "isString" + ARGS_DESC@13646..13649 + L_PAREN@13646..13647 "(" + ARG@13647..13648 + EXPR_VAR@13647..13648 + NAME@13647..13648 + IDENT@13647..13648 "v" + R_PAREN@13648..13649 ")" + WHITESPACE@13649..13650 " " + THEN_KW@13650..13654 "then" + WHITESPACE@13654..13665 "\n " + TRUE_EXPR@13665..13666 + EXPR_VAR@13665..13666 + NAME@13665..13666 + IDENT@13665..13666 "v" + WHITESPACE@13666..13675 "\n " + ELSE_KW@13675..13679 "else" + WHITESPACE@13679..13690 "\n " + FALSE_EXPR@13690..14107 + EXPR_LOCAL@13690..14107 + LOCAL_KW@13690..13695 "local" + WHITESPACE@13695..13696 " " + BIND_DESTRUCT@13696..13706 + DESTRUCT_FULL@13696..13699 + NAME@13696..13699 + IDENT@13696..13699 "tag" + WHITESPACE@13699..13700 " " + ASSIGN@13700..13701 "=" + WHITESPACE@13701..13702 " " + EXPR_INDEX_EXPR@13702..13706 + LHS_EXPR@13702..13703 + EXPR_VAR@13702..13703 + NAME@13702..13703 + IDENT@13702..13703 "v" + L_BRACK@13703..13704 "[" + EXPR_NUMBER@13704..13705 + FLOAT@13704..13705 "0" + R_BRACK@13705..13706 "]" + SEMI@13706..13707 ";" + WHITESPACE@13707..13718 "\n " + EXPR_LOCAL@13718..14107 + LOCAL_KW@13718..13723 "local" + WHITESPACE@13723..13724 " " + BIND_DESTRUCT@13724..13775 + DESTRUCT_FULL@13724..13733 + NAME@13724..13733 + IDENT@13724..13733 "has_attrs" + WHITESPACE@13733..13734 " " + ASSIGN@13734..13735 "=" + WHITESPACE@13735..13736 " " + EXPR_BINARY@13736..13775 + LHS_EXPR@13736..13753 + EXPR_BINARY@13736..13753 + LHS_EXPR@13736..13749 + EXPR_APPLY@13736..13749 + EXPR_INDEX@13736..13746 + EXPR_VAR@13736..13739 + NAME@13736..13739 + IDENT@13736..13739 "std" + DOT@13739..13740 "." + NAME@13740..13746 + IDENT@13740..13746 "length" + ARGS_DESC@13746..13749 + L_PAREN@13746..13747 "(" + ARG@13747..13748 + EXPR_VAR@13747..13748 + NAME@13747..13748 + IDENT@13747..13748 "v" + R_PAREN@13748..13749 ")" + WHITESPACE@13749..13750 " " + GT@13750..13751 ">" + WHITESPACE@13751..13752 " " + EXPR_NUMBER@13752..13753 + FLOAT@13752..13753 "1" + WHITESPACE@13753..13754 " " + AND@13754..13756 "&&" + WHITESPACE@13756..13757 " " + EXPR_APPLY@13757..13775 + EXPR_INDEX@13757..13769 + EXPR_VAR@13757..13760 + NAME@13757..13760 + IDENT@13757..13760 "std" + DOT@13760..13761 "." + NAME@13761..13769 + IDENT@13761..13769 "isObject" + ARGS_DESC@13769..13775 + L_PAREN@13769..13770 "(" + ARG@13770..13774 + EXPR_INDEX_EXPR@13770..13774 + LHS_EXPR@13770..13771 + EXPR_VAR@13770..13771 + NAME@13770..13771 + IDENT@13770..13771 "v" + L_BRACK@13771..13772 "[" + EXPR_NUMBER@13772..13773 + FLOAT@13772..13773 "1" + R_BRACK@13773..13774 "]" + R_PAREN@13774..13775 ")" + SEMI@13775..13776 ";" + WHITESPACE@13776..13787 "\n " + EXPR_LOCAL@13787..14107 + LOCAL_KW@13787..13792 "local" + WHITESPACE@13792..13793 " " + BIND_DESTRUCT@13793..13831 + DESTRUCT_FULL@13793..13798 + NAME@13793..13798 + IDENT@13793..13798 "attrs" + WHITESPACE@13798..13799 " " + ASSIGN@13799..13800 "=" + WHITESPACE@13800..13801 " " + EXPR_IF_THEN_ELSE@13801..13831 + IF_KW@13801..13803 "if" + WHITESPACE@13803..13804 " " + EXPR_VAR@13804..13813 + NAME@13804..13813 + IDENT@13804..13813 "has_attrs" + WHITESPACE@13813..13814 " " + THEN_KW@13814..13818 "then" + WHITESPACE@13818..13819 " " + TRUE_EXPR@13819..13823 + EXPR_INDEX_EXPR@13819..13823 + LHS_EXPR@13819..13820 + EXPR_VAR@13819..13820 + NAME@13819..13820 + IDENT@13819..13820 "v" + L_BRACK@13820..13821 "[" + EXPR_NUMBER@13821..13822 + FLOAT@13821..13822 "1" + R_BRACK@13822..13823 "]" + WHITESPACE@13823..13824 " " + ELSE_KW@13824..13828 "else" + WHITESPACE@13828..13829 " " + FALSE_EXPR@13829..13831 + EXPR_OBJECT@13829..13831 + OBJ_BODY_MEMBER_LIST@13829..13831 + L_BRACE@13829..13830 "{" + R_BRACE@13830..13831 "}" + SEMI@13831..13832 ";" + WHITESPACE@13832..13843 "\n " + EXPR_LOCAL@13843..14107 + LOCAL_KW@13843..13848 "local" + WHITESPACE@13848..13849 " " + BIND_DESTRUCT@13849..13894 + DESTRUCT_FULL@13849..13857 + NAME@13849..13857 + IDENT@13849..13857 "children" + WHITESPACE@13857..13858 " " + ASSIGN@13858..13859 "=" + WHITESPACE@13859..13860 " " + EXPR_IF_THEN_ELSE@13860..13894 + IF_KW@13860..13862 "if" + WHITESPACE@13862..13863 " " + EXPR_VAR@13863..13872 + NAME@13863..13872 + IDENT@13863..13872 "has_attrs" + WHITESPACE@13872..13873 " " + THEN_KW@13873..13877 "then" + WHITESPACE@13877..13878 " " + TRUE_EXPR@13878..13883 + EXPR_SLICE@13878..13883 + EXPR_VAR@13878..13879 + NAME@13878..13879 + IDENT@13878..13879 "v" + SLICE_DESC@13879..13883 + L_BRACK@13879..13880 "[" + EXPR_NUMBER@13880..13881 + FLOAT@13880..13881 "2" + COLON@13881..13882 ":" + R_BRACK@13882..13883 "]" + WHITESPACE@13883..13884 " " + ELSE_KW@13884..13888 "else" + WHITESPACE@13888..13889 " " + FALSE_EXPR@13889..13894 + EXPR_SLICE@13889..13894 + EXPR_VAR@13889..13890 + NAME@13889..13890 + IDENT@13889..13890 "v" + SLICE_DESC@13890..13894 + L_BRACK@13890..13891 "[" + EXPR_NUMBER@13891..13892 + FLOAT@13891..13892 "1" + COLON@13892..13893 ":" + R_BRACK@13893..13894 "]" + SEMI@13894..13895 ";" + WHITESPACE@13895..13906 "\n " + EXPR_LOCAL@13906..14107 + LOCAL_KW@13906..13911 "local" + WHITESPACE@13911..13912 " " + BIND_DESTRUCT@13912..14011 + DESTRUCT_FULL@13912..13921 + NAME@13912..13921 + IDENT@13912..13921 "attrs_str" + WHITESPACE@13921..13922 " " + ASSIGN@13922..13923 "=" + WHITESPACE@13923..13936 "\n " + EXPR_APPLY@13936..14011 + EXPR_INDEX@13936..13944 + EXPR_VAR@13936..13939 + NAME@13936..13939 + IDENT@13936..13939 "std" + DOT@13939..13940 "." + NAME@13940..13944 + IDENT@13940..13944 "join" + ARGS_DESC@13944..14011 + L_PAREN@13944..13945 "(" + ARG@13945..13947 + EXPR_STRING@13945..13947 + STRING_SINGLE@13945..13947 "''" + COMMA@13947..13948 "," + WHITESPACE@13948..13949 " " + ARG@13949..14010 + EXPR_ARRAY_COMP@13949..14010 + L_BRACK@13949..13950 "[" + EXPR_BINARY@13950..13976 + LHS_EXPR@13950..13960 + EXPR_STRING@13950..13960 + STRING_SINGLE@13950..13960 "' %s=\"%s\"'" + WHITESPACE@13960..13961 " " + MODULO@13961..13962 "%" + WHITESPACE@13962..13963 " " + EXPR_ARRAY@13963..13976 + L_BRACK@13963..13964 "[" + EXPR_VAR@13964..13965 + NAME@13964..13965 + IDENT@13964..13965 "k" + COMMA@13965..13966 "," + WHITESPACE@13966..13967 " " + EXPR_INDEX_EXPR@13967..13975 + LHS_EXPR@13967..13972 + EXPR_VAR@13967..13972 + NAME@13967..13972 + IDENT@13967..13972 "attrs" + L_BRACK@13972..13973 "[" + EXPR_VAR@13973..13974 + NAME@13973..13974 + IDENT@13973..13974 "k" + R_BRACK@13974..13975 "]" + R_BRACK@13975..13976 "]" + WHITESPACE@13976..13977 " " + FOR_SPEC@13977..14009 + FOR_KW@13977..13980 "for" + WHITESPACE@13980..13981 " " + NAME@13981..13982 + IDENT@13981..13982 "k" + WHITESPACE@13982..13983 " " + IN_KW@13983..13985 "in" + WHITESPACE@13985..13986 " " + EXPR_APPLY@13986..14009 + EXPR_INDEX@13986..14002 + EXPR_VAR@13986..13989 + NAME@13986..13989 + IDENT@13986..13989 "std" + DOT@13989..13990 "." + NAME@13990..14002 + IDENT@13990..14002 "objectFields" + ARGS_DESC@14002..14009 + L_PAREN@14002..14003 "(" + ARG@14003..14008 + EXPR_VAR@14003..14008 + NAME@14003..14008 + IDENT@14003..14008 "attrs" + R_PAREN@14008..14009 ")" + R_BRACK@14009..14010 "]" + R_PAREN@14010..14011 ")" + SEMI@14011..14012 ";" + WHITESPACE@14012..14023 "\n " + EXPR_APPLY@14023..14107 + EXPR_INDEX@14023..14035 + EXPR_VAR@14023..14026 + NAME@14023..14026 + IDENT@14023..14026 "std" + DOT@14026..14027 "." + NAME@14027..14035 + IDENT@14027..14035 "deepJoin" + ARGS_DESC@14035..14107 + L_PAREN@14035..14036 "(" + ARG@14036..14106 + EXPR_ARRAY@14036..14106 + L_BRACK@14036..14037 "[" + EXPR_STRING@14037..14040 + STRING_SINGLE@14037..14040 "'<'" + COMMA@14040..14041 "," + WHITESPACE@14041..14042 " " + EXPR_VAR@14042..14045 + NAME@14042..14045 + IDENT@14042..14045 "tag" + COMMA@14045..14046 "," + WHITESPACE@14046..14047 " " + EXPR_VAR@14047..14056 + NAME@14047..14056 + IDENT@14047..14056 "attrs_str" + COMMA@14056..14057 "," + WHITESPACE@14057..14058 " " + EXPR_STRING@14058..14061 + STRING_SINGLE@14058..14061 "'>'" + COMMA@14061..14062 "," + WHITESPACE@14062..14063 " " + EXPR_ARRAY_COMP@14063..14089 + L_BRACK@14063..14064 "[" + EXPR_APPLY@14064..14070 + EXPR_VAR@14064..14067 + NAME@14064..14067 + IDENT@14064..14067 "aux" + ARGS_DESC@14067..14070 + L_PAREN@14067..14068 "(" + ARG@14068..14069 + EXPR_VAR@14068..14069 + NAME@14068..14069 + IDENT@14068..14069 "x" + R_PAREN@14069..14070 ")" + WHITESPACE@14070..14071 " " + FOR_SPEC@14071..14088 + FOR_KW@14071..14074 "for" + WHITESPACE@14074..14075 " " + NAME@14075..14076 + IDENT@14075..14076 "x" + WHITESPACE@14076..14077 " " + IN_KW@14077..14079 "in" + WHITESPACE@14079..14080 " " + EXPR_VAR@14080..14088 + NAME@14080..14088 + IDENT@14080..14088 "children" + R_BRACK@14088..14089 "]" + COMMA@14089..14090 "," + WHITESPACE@14090..14091 " " + EXPR_STRING@14091..14095 + STRING_SINGLE@14091..14095 "''" + R_BRACK@14105..14106 "]" + R_PAREN@14106..14107 ")" + SEMI@14107..14108 ";" + WHITESPACE@14108..14116 "\n\n " + EXPR_APPLY@14116..14126 + EXPR_VAR@14116..14119 + NAME@14116..14119 + IDENT@14116..14119 "aux" + ARGS_DESC@14119..14126 + L_PAREN@14119..14120 "(" + ARG@14120..14125 + EXPR_VAR@14120..14125 + NAME@14120..14125 + IDENT@14120..14125 "value" + R_PAREN@14125..14126 ")" + COMMA@14126..14127 "," + WHITESPACE@14127..14131 "\n\n " + MEMBER_BIND_STMT@14131..14218 + OBJ_LOCAL@14131..14218 + LOCAL_KW@14131..14136 "local" + WHITESPACE@14136..14137 " " + BIND_DESTRUCT@14137..14218 + DESTRUCT_FULL@14137..14149 + NAME@14137..14149 + IDENT@14137..14149 "base64_table" + WHITESPACE@14149..14150 " " + ASSIGN@14150..14151 "=" + WHITESPACE@14151..14152 " " + EXPR_STRING@14152..14218 + STRING_SINGLE@14152..14218 "'ABCDEFGHIJKLMNOPQRST ..." + COMMA@14218..14219 "," + WHITESPACE@14219..14222 "\n " + MEMBER_BIND_STMT@14222..14291 + OBJ_LOCAL@14222..14291 + LOCAL_KW@14222..14227 "local" + WHITESPACE@14227..14228 " " + BIND_DESTRUCT@14228..14291 + DESTRUCT_FULL@14228..14238 + NAME@14228..14238 + IDENT@14228..14238 "base64_inv" + WHITESPACE@14238..14239 " " + ASSIGN@14239..14240 "=" + WHITESPACE@14240..14241 " " + EXPR_OBJECT@14241..14291 + OBJ_BODY_MEMBER_LIST@14241..14291 + L_BRACE@14241..14242 "{" + WHITESPACE@14242..14243 " " + MEMBER_FIELD@14243..14289 + FIELD_NORMAL@14243..14263 + FIELD_NAME_DYNAMIC@14243..14260 + L_BRACK@14243..14244 "[" + EXPR_INDEX_EXPR@14244..14259 + LHS_EXPR@14244..14256 + EXPR_VAR@14244..14256 + NAME@14244..14256 + IDENT@14244..14256 "base64_table" + L_BRACK@14256..14257 "[" + EXPR_VAR@14257..14258 + NAME@14257..14258 + IDENT@14257..14258 "i" + R_BRACK@14258..14259 "]" + R_BRACK@14259..14260 "]" + COLON@14260..14261 ":" + WHITESPACE@14261..14262 " " + EXPR_VAR@14262..14263 + NAME@14262..14263 + IDENT@14262..14263 "i" + WHITESPACE@14263..14264 " " + FOR_SPEC@14264..14289 + FOR_KW@14264..14267 "for" + WHITESPACE@14267..14268 " " + NAME@14268..14269 + IDENT@14268..14269 "i" + WHITESPACE@14269..14270 " " + IN_KW@14270..14272 "in" + WHITESPACE@14272..14273 " " + EXPR_APPLY@14273..14289 + EXPR_INDEX@14273..14282 + EXPR_VAR@14273..14276 + NAME@14273..14276 + IDENT@14273..14276 "std" + DOT@14276..14277 "." + NAME@14277..14282 + IDENT@14277..14282 "range" + ARGS_DESC@14282..14289 + L_PAREN@14282..14283 "(" + ARG@14283..14284 + EXPR_NUMBER@14283..14284 + FLOAT@14283..14284 "0" + COMMA@14284..14285 "," + WHITESPACE@14285..14286 " " + ARG@14286..14288 + EXPR_NUMBER@14286..14288 + FLOAT@14286..14288 "63" + R_PAREN@14288..14289 ")" + WHITESPACE@14289..14290 " " + R_BRACE@14290..14291 "}" + COMMA@14291..14292 "," + WHITESPACE@14292..14296 "\n\n " + MEMBER_FIELD@14296..14323 + FIELD_NORMAL@14296..14323 + FIELD_NAME_FIXED@14296..14302 + NAME@14296..14302 + IDENT@14296..14302 "base64" + COLONCOLON@14302..14304 "::" + WHITESPACE@14304..14305 " " + EXPR_INTRINSIC@14305..14323 + INTRINSIC@14305..14315 "$intrinsic" + L_PAREN@14315..14316 "(" + NAME@14316..14322 + IDENT@14316..14322 "base64" + R_PAREN@14322..14323 ")" + COMMA@14323..14324 "," + WHITESPACE@14324..14328 "\n\n " + MEMBER_FIELD@14328..14377 + FIELD_NORMAL@14328..14377 + FIELD_NAME_FIXED@14328..14345 + NAME@14328..14345 + IDENT@14328..14345 "base64DecodeBytes" + COLONCOLON@14345..14347 "::" + WHITESPACE@14347..14348 " " + EXPR_INTRINSIC@14348..14377 + INTRINSIC@14348..14358 "$intrinsic" + L_PAREN@14358..14359 "(" + NAME@14359..14376 + IDENT@14359..14376 "base64DecodeBytes" + R_PAREN@14376..14377 ")" + COMMA@14377..14378 "," + WHITESPACE@14378..14382 "\n\n " + MEMBER_FIELD@14382..14421 + FIELD_NORMAL@14382..14421 + FIELD_NAME_FIXED@14382..14394 + NAME@14382..14394 + IDENT@14382..14394 "base64Decode" + COLONCOLON@14394..14396 "::" + WHITESPACE@14396..14397 " " + EXPR_INTRINSIC@14397..14421 + INTRINSIC@14397..14407 "$intrinsic" + L_PAREN@14407..14408 "(" + NAME@14408..14420 + IDENT@14408..14420 "base64Decode" + R_PAREN@14420..14421 ")" + COMMA@14421..14422 "," + WHITESPACE@14422..14426 "\n\n " + MEMBER_FIELD@14426..14455 + FIELD_NORMAL@14426..14455 + FIELD_NAME_FIXED@14426..14433 + NAME@14426..14433 + IDENT@14426..14433 "reverse" + COLONCOLON@14433..14435 "::" + WHITESPACE@14435..14436 " " + EXPR_INTRINSIC@14436..14455 + INTRINSIC@14436..14446 "$intrinsic" + L_PAREN@14446..14447 "(" + NAME@14447..14454 + IDENT@14447..14454 "reverse" + R_PAREN@14454..14455 ")" + COMMA@14455..14456 "," + WHITESPACE@14456..14460 "\n\n " + MEMBER_FIELD@14460..14483 + FIELD_NORMAL@14460..14483 + FIELD_NAME_FIXED@14460..14464 + NAME@14460..14464 + IDENT@14460..14464 "sort" + COLONCOLON@14464..14466 "::" + WHITESPACE@14466..14467 " " + EXPR_INTRINSIC@14467..14483 + INTRINSIC@14467..14477 "$intrinsic" + L_PAREN@14477..14478 "(" + NAME@14478..14482 + IDENT@14478..14482 "sort" + R_PAREN@14482..14483 ")" + COMMA@14483..14484 "," + WHITESPACE@14484..14488 "\n\n " + MEMBER_FIELD@14488..14694 + FIELD_METHOD@14488..14694 + FIELD_NAME_FIXED@14488..14492 + NAME@14488..14492 + IDENT@14488..14492 "uniq" + PARAMS_DESC@14492..14506 + L_PAREN@14492..14493 "(" + PARAM@14493..14496 + DESTRUCT_FULL@14493..14496 + NAME@14493..14496 + IDENT@14493..14496 "arr" + COMMA@14496..14497 "," + WHITESPACE@14497..14498 " " + PARAM@14498..14505 + DESTRUCT_FULL@14498..14502 + NAME@14498..14502 + IDENT@14498..14502 "keyF" + ASSIGN@14502..14503 "=" + EXPR_VAR@14503..14505 + NAME@14503..14505 + IDENT@14503..14505 "id" + R_PAREN@14505..14506 ")" + COLONCOLON@14506..14508 "::" + WHITESPACE@14508..14513 "\n " + EXPR_LOCAL@14513..14694 + LOCAL_KW@14513..14518 "local" + WHITESPACE@14518..14519 " " + BIND_FUNCTION@14519..14667 + NAME@14519..14520 + IDENT@14519..14520 "f" + PARAMS_DESC@14520..14526 + L_PAREN@14520..14521 "(" + PARAM@14521..14522 + DESTRUCT_FULL@14521..14522 + NAME@14521..14522 + IDENT@14521..14522 "a" + COMMA@14522..14523 "," + WHITESPACE@14523..14524 " " + PARAM@14524..14525 + DESTRUCT_FULL@14524..14525 + NAME@14524..14525 + IDENT@14524..14525 "b" + R_PAREN@14525..14526 ")" + WHITESPACE@14526..14527 " " + ASSIGN@14527..14528 "=" + WHITESPACE@14528..14535 "\n " + EXPR_IF_THEN_ELSE@14535..14667 + IF_KW@14535..14537 "if" + WHITESPACE@14537..14538 " " + EXPR_BINARY@14538..14556 + LHS_EXPR@14538..14551 + EXPR_APPLY@14538..14551 + EXPR_INDEX@14538..14548 + EXPR_VAR@14538..14541 + NAME@14538..14541 + IDENT@14538..14541 "std" + DOT@14541..14542 "." + NAME@14542..14548 + IDENT@14542..14548 "length" + ARGS_DESC@14548..14551 + L_PAREN@14548..14549 "(" + ARG@14549..14550 + EXPR_VAR@14549..14550 + NAME@14549..14550 + IDENT@14549..14550 "a" + R_PAREN@14550..14551 ")" + WHITESPACE@14551..14552 " " + EQ@14552..14554 "==" + WHITESPACE@14554..14555 " " + EXPR_NUMBER@14555..14556 + FLOAT@14555..14556 "0" + WHITESPACE@14556..14557 " " + THEN_KW@14557..14561 "then" + WHITESPACE@14561..14570 "\n " + TRUE_EXPR@14570..14573 + EXPR_ARRAY@14570..14573 + L_BRACK@14570..14571 "[" + EXPR_VAR@14571..14572 + NAME@14571..14572 + IDENT@14571..14572 "b" + R_BRACK@14572..14573 "]" + WHITESPACE@14573..14580 "\n " + ELSE_KW@14580..14584 "else" + WHITESPACE@14584..14585 " " + FALSE_EXPR@14585..14667 + EXPR_IF_THEN_ELSE@14585..14667 + IF_KW@14585..14587 "if" + WHITESPACE@14587..14588 " " + EXPR_BINARY@14588..14625 + LHS_EXPR@14588..14614 + EXPR_APPLY@14588..14614 + EXPR_VAR@14588..14592 + NAME@14588..14592 + IDENT@14588..14592 "keyF" + ARGS_DESC@14592..14614 + L_PAREN@14592..14593 "(" + ARG@14593..14613 + EXPR_INDEX_EXPR@14593..14613 + LHS_EXPR@14593..14594 + EXPR_VAR@14593..14594 + NAME@14593..14594 + IDENT@14593..14594 "a" + L_BRACK@14594..14595 "[" + EXPR_BINARY@14595..14612 + LHS_EXPR@14595..14608 + EXPR_APPLY@14595..14608 + EXPR_INDEX@14595..14605 + EXPR_VAR@14595..14598 + NAME@14595..14598 + IDENT@14595..14598 "std" + DOT@14598..14599 "." + NAME@14599..14605 + IDENT@14599..14605 "length" + ARGS_DESC@14605..14608 + L_PAREN@14605..14606 "(" + ARG@14606..14607 + EXPR_VAR@14606..14607 + NAME@14606..14607 + IDENT@14606..14607 "a" + R_PAREN@14607..14608 ")" + WHITESPACE@14608..14609 " " + MINUS@14609..14610 "-" + WHITESPACE@14610..14611 " " + EXPR_NUMBER@14611..14612 + FLOAT@14611..14612 "1" + R_BRACK@14612..14613 "]" + R_PAREN@14613..14614 ")" + WHITESPACE@14614..14615 " " + EQ@14615..14617 "==" + WHITESPACE@14617..14618 " " + EXPR_APPLY@14618..14625 + EXPR_VAR@14618..14622 + NAME@14618..14622 + IDENT@14618..14622 "keyF" + ARGS_DESC@14622..14625 + L_PAREN@14622..14623 "(" + ARG@14623..14624 + EXPR_VAR@14623..14624 + NAME@14623..14624 + IDENT@14623..14624 "b" + R_PAREN@14624..14625 ")" + WHITESPACE@14625..14626 " " + THEN_KW@14626..14630 "then" + WHITESPACE@14630..14639 "\n " + TRUE_EXPR@14639..14640 + EXPR_VAR@14639..14640 + NAME@14639..14640 + IDENT@14639..14640 "a" + WHITESPACE@14640..14647 "\n " + ELSE_KW@14647..14651 "else" + WHITESPACE@14651..14660 "\n " + FALSE_EXPR@14660..14667 + EXPR_BINARY@14660..14667 + LHS_EXPR@14660..14661 + EXPR_VAR@14660..14661 + NAME@14660..14661 + IDENT@14660..14661 "a" + WHITESPACE@14661..14662 " " + PLUS@14662..14663 "+" + WHITESPACE@14663..14664 " " + EXPR_ARRAY@14664..14667 + L_BRACK@14664..14665 "[" + EXPR_VAR@14665..14666 + NAME@14665..14666 + IDENT@14665..14666 "b" + R_BRACK@14666..14667 "]" + SEMI@14667..14668 ";" + WHITESPACE@14668..14673 "\n " + EXPR_APPLY@14673..14694 + EXPR_INDEX@14673..14682 + EXPR_VAR@14673..14676 + NAME@14673..14676 + IDENT@14673..14676 "std" + DOT@14676..14677 "." + NAME@14677..14682 + IDENT@14677..14682 "foldl" + ARGS_DESC@14682..14694 + L_PAREN@14682..14683 "(" + ARG@14683..14684 + EXPR_VAR@14683..14684 + NAME@14683..14684 + IDENT@14683..14684 "f" + COMMA@14684..14685 "," + WHITESPACE@14685..14686 " " + ARG@14686..14689 + EXPR_VAR@14686..14689 + NAME@14686..14689 + IDENT@14686..14689 "arr" + COMMA@14689..14690 "," + WHITESPACE@14690..14691 " " + ARG@14691..14693 + EXPR_ARRAY@14691..14693 + L_BRACK@14691..14692 "[" + R_BRACK@14692..14693 "]" + R_PAREN@14693..14694 ")" + COMMA@14694..14695 "," + WHITESPACE@14695..14699 "\n\n " + MEMBER_FIELD@14699..14758 + FIELD_METHOD@14699..14758 + FIELD_NAME_FIXED@14699..14702 + NAME@14699..14702 + IDENT@14699..14702 "set" + PARAMS_DESC@14702..14716 + L_PAREN@14702..14703 "(" + PARAM@14703..14706 + DESTRUCT_FULL@14703..14706 + NAME@14703..14706 + IDENT@14703..14706 "arr" + COMMA@14706..14707 "," + WHITESPACE@14707..14708 " " + PARAM@14708..14715 + DESTRUCT_FULL@14708..14712 + NAME@14708..14712 + IDENT@14708..14712 "keyF" + ASSIGN@14712..14713 "=" + EXPR_VAR@14713..14715 + NAME@14713..14715 + IDENT@14713..14715 "id" + R_PAREN@14715..14716 ")" + COLONCOLON@14716..14718 "::" + WHITESPACE@14718..14723 "\n " + EXPR_APPLY@14723..14758 + EXPR_INDEX@14723..14731 + EXPR_VAR@14723..14726 + NAME@14723..14726 + IDENT@14723..14726 "std" + DOT@14726..14727 "." + NAME@14727..14731 + IDENT@14727..14731 "uniq" + ARGS_DESC@14731..14758 + L_PAREN@14731..14732 "(" + ARG@14732..14751 + EXPR_APPLY@14732..14751 + EXPR_INDEX@14732..14740 + EXPR_VAR@14732..14735 + NAME@14732..14735 + IDENT@14732..14735 "std" + DOT@14735..14736 "." + NAME@14736..14740 + IDENT@14736..14740 "sort" + ARGS_DESC@14740..14751 + L_PAREN@14740..14741 "(" + ARG@14741..14744 + EXPR_VAR@14741..14744 + NAME@14741..14744 + IDENT@14741..14744 "arr" + COMMA@14744..14745 "," + WHITESPACE@14745..14746 " " + ARG@14746..14750 + EXPR_VAR@14746..14750 + NAME@14746..14750 + IDENT@14746..14750 "keyF" + R_PAREN@14750..14751 ")" + COMMA@14751..14752 "," + WHITESPACE@14752..14753 " " + ARG@14753..14757 + EXPR_VAR@14753..14757 + NAME@14753..14757 + IDENT@14753..14757 "keyF" + R_PAREN@14757..14758 ")" + COMMA@14758..14759 "," + WHITESPACE@14759..14763 "\n\n " + MEMBER_FIELD@14763..14898 + FIELD_METHOD@14763..14898 + FIELD_NAME_FIXED@14763..14772 + NAME@14763..14772 + IDENT@14763..14772 "setMember" + PARAMS_DESC@14772..14789 + L_PAREN@14772..14773 "(" + PARAM@14773..14774 + DESTRUCT_FULL@14773..14774 + NAME@14773..14774 + IDENT@14773..14774 "x" + COMMA@14774..14775 "," + WHITESPACE@14775..14776 " " + PARAM@14776..14779 + DESTRUCT_FULL@14776..14779 + NAME@14776..14779 + IDENT@14776..14779 "arr" + COMMA@14779..14780 "," + WHITESPACE@14780..14781 " " + PARAM@14781..14788 + DESTRUCT_FULL@14781..14785 + NAME@14781..14785 + IDENT@14781..14785 "keyF" + ASSIGN@14785..14786 "=" + EXPR_VAR@14786..14788 + NAME@14786..14788 + IDENT@14786..14788 "id" + R_PAREN@14788..14789 ")" + COLONCOLON@14789..14791 "::" + WHITESPACE@14791..14796 "\n " + SINGLE_LINE_SLASH_COMMENT@14796..14850 "// TODO(dcunnin): Bin ..." + WHITESPACE@14850..14854 " " + EXPR_BINARY@14854..14898 + LHS_EXPR@14854..14894 + EXPR_APPLY@14854..14894 + EXPR_INDEX@14854..14864 + EXPR_VAR@14854..14857 + NAME@14854..14857 + IDENT@14854..14857 "std" + DOT@14857..14858 "." + NAME@14858..14864 + IDENT@14858..14864 "length" + ARGS_DESC@14864..14894 + L_PAREN@14864..14865 "(" + ARG@14865..14893 + EXPR_APPLY@14865..14893 + EXPR_INDEX@14865..14877 + EXPR_VAR@14865..14868 + NAME@14865..14868 + IDENT@14865..14868 "std" + DOT@14868..14869 "." + NAME@14869..14877 + IDENT@14869..14877 "setInter" + ARGS_DESC@14877..14893 + L_PAREN@14877..14878 "(" + ARG@14878..14881 + EXPR_ARRAY@14878..14881 + L_BRACK@14878..14879 "[" + EXPR_VAR@14879..14880 + NAME@14879..14880 + IDENT@14879..14880 "x" + R_BRACK@14880..14881 "]" + COMMA@14881..14882 "," + WHITESPACE@14882..14883 " " + ARG@14883..14886 + EXPR_VAR@14883..14886 + NAME@14883..14886 + IDENT@14883..14886 "arr" + COMMA@14886..14887 "," + WHITESPACE@14887..14888 " " + ARG@14888..14892 + EXPR_VAR@14888..14892 + NAME@14888..14892 + IDENT@14888..14892 "keyF" + R_PAREN@14892..14893 ")" + R_PAREN@14893..14894 ")" + WHITESPACE@14894..14895 " " + GT@14895..14896 ">" + WHITESPACE@14896..14897 " " + EXPR_NUMBER@14897..14898 + FLOAT@14897..14898 "0" + COMMA@14898..14899 "," + WHITESPACE@14899..14903 "\n\n " + MEMBER_FIELD@14903..15452 + FIELD_METHOD@14903..15452 + FIELD_NAME_FIXED@14903..14911 + NAME@14903..14911 + IDENT@14903..14911 "setUnion" + PARAMS_DESC@14911..14926 + L_PAREN@14911..14912 "(" + PARAM@14912..14913 + DESTRUCT_FULL@14912..14913 + NAME@14912..14913 + IDENT@14912..14913 "a" + COMMA@14913..14914 "," + WHITESPACE@14914..14915 " " + PARAM@14915..14916 + DESTRUCT_FULL@14915..14916 + NAME@14915..14916 + IDENT@14915..14916 "b" + COMMA@14916..14917 "," + WHITESPACE@14917..14918 " " + PARAM@14918..14925 + DESTRUCT_FULL@14918..14922 + NAME@14918..14922 + IDENT@14918..14922 "keyF" + ASSIGN@14922..14923 "=" + EXPR_VAR@14923..14925 + NAME@14923..14925 + IDENT@14923..14925 "id" + R_PAREN@14925..14926 ")" + COLONCOLON@14926..14928 "::" + WHITESPACE@14928..14933 "\n " + SINGLE_LINE_SLASH_COMMENT@14933..14975 "// NOTE: order matter ..." + WHITESPACE@14975..14979 " " + EXPR_LOCAL@14979..15452 + LOCAL_KW@14979..14984 "local" + WHITESPACE@14984..14985 " " + BIND_FUNCTION@14985..15427 + NAME@14985..14988 + IDENT@14985..14988 "aux" + PARAMS_DESC@14988..15005 + L_PAREN@14988..14989 "(" + PARAM@14989..14990 + DESTRUCT_FULL@14989..14990 + NAME@14989..14990 + IDENT@14989..14990 "a" + COMMA@14990..14991 "," + WHITESPACE@14991..14992 " " + PARAM@14992..14993 + DESTRUCT_FULL@14992..14993 + NAME@14992..14993 + IDENT@14992..14993 "b" + COMMA@14993..14994 "," + WHITESPACE@14994..14995 " " + PARAM@14995..14996 + DESTRUCT_FULL@14995..14996 + NAME@14995..14996 + IDENT@14995..14996 "i" + COMMA@14996..14997 "," + WHITESPACE@14997..14998 " " + PARAM@14998..14999 + DESTRUCT_FULL@14998..14999 + NAME@14998..14999 + IDENT@14998..14999 "j" + COMMA@14999..15000 "," + WHITESPACE@15000..15001 " " + PARAM@15001..15004 + DESTRUCT_FULL@15001..15004 + NAME@15001..15004 + IDENT@15001..15004 "acc" + R_PAREN@15004..15005 ")" + WHITESPACE@15005..15006 " " + ASSIGN@15006..15007 "=" + WHITESPACE@15007..15014 "\n " + EXPR_IF_THEN_ELSE@15014..15427 + IF_KW@15014..15016 "if" + WHITESPACE@15016..15017 " " + EXPR_BINARY@15017..15035 + LHS_EXPR@15017..15018 + EXPR_VAR@15017..15018 + NAME@15017..15018 + IDENT@15017..15018 "i" + WHITESPACE@15018..15019 " " + GE@15019..15021 ">=" + WHITESPACE@15021..15022 " " + EXPR_APPLY@15022..15035 + EXPR_INDEX@15022..15032 + EXPR_VAR@15022..15025 + NAME@15022..15025 + IDENT@15022..15025 "std" + DOT@15025..15026 "." + NAME@15026..15032 + IDENT@15026..15032 "length" + ARGS_DESC@15032..15035 + L_PAREN@15032..15033 "(" + ARG@15033..15034 + EXPR_VAR@15033..15034 + NAME@15033..15034 + IDENT@15033..15034 "a" + R_PAREN@15034..15035 ")" + WHITESPACE@15035..15036 " " + THEN_KW@15036..15040 "then" + WHITESPACE@15040..15049 "\n " + TRUE_EXPR@15049..15060 + EXPR_BINARY@15049..15060 + LHS_EXPR@15049..15052 + EXPR_VAR@15049..15052 + NAME@15049..15052 + IDENT@15049..15052 "acc" + WHITESPACE@15052..15053 " " + PLUS@15053..15054 "+" + WHITESPACE@15054..15055 " " + EXPR_SLICE@15055..15060 + EXPR_VAR@15055..15056 + NAME@15055..15056 + IDENT@15055..15056 "b" + SLICE_DESC@15056..15060 + L_BRACK@15056..15057 "[" + EXPR_VAR@15057..15058 + NAME@15057..15058 + IDENT@15057..15058 "j" + COLON@15058..15059 ":" + R_BRACK@15059..15060 "]" + WHITESPACE@15060..15067 "\n " + ELSE_KW@15067..15071 "else" + WHITESPACE@15071..15072 " " + FALSE_EXPR@15072..15427 + EXPR_IF_THEN_ELSE@15072..15427 + IF_KW@15072..15074 "if" + WHITESPACE@15074..15075 " " + EXPR_BINARY@15075..15093 + LHS_EXPR@15075..15076 + EXPR_VAR@15075..15076 + NAME@15075..15076 + IDENT@15075..15076 "j" + WHITESPACE@15076..15077 " " + GE@15077..15079 ">=" + WHITESPACE@15079..15080 " " + EXPR_APPLY@15080..15093 + EXPR_INDEX@15080..15090 + EXPR_VAR@15080..15083 + NAME@15080..15083 + IDENT@15080..15083 "std" + DOT@15083..15084 "." + NAME@15084..15090 + IDENT@15084..15090 "length" + ARGS_DESC@15090..15093 + L_PAREN@15090..15091 "(" + ARG@15091..15092 + EXPR_VAR@15091..15092 + NAME@15091..15092 + IDENT@15091..15092 "b" + R_PAREN@15092..15093 ")" + WHITESPACE@15093..15094 " " + THEN_KW@15094..15098 "then" + WHITESPACE@15098..15107 "\n " + TRUE_EXPR@15107..15118 + EXPR_BINARY@15107..15118 + LHS_EXPR@15107..15110 + EXPR_VAR@15107..15110 + NAME@15107..15110 + IDENT@15107..15110 "acc" + WHITESPACE@15110..15111 " " + PLUS@15111..15112 "+" + WHITESPACE@15112..15113 " " + EXPR_SLICE@15113..15118 + EXPR_VAR@15113..15114 + NAME@15113..15114 + IDENT@15113..15114 "a" + SLICE_DESC@15114..15118 + L_BRACK@15114..15115 "[" + EXPR_VAR@15115..15116 + NAME@15115..15116 + IDENT@15115..15116 "i" + COLON@15116..15117 ":" + R_BRACK@15117..15118 "]" + WHITESPACE@15118..15125 "\n " + ELSE_KW@15125..15129 "else" + WHITESPACE@15129..15138 "\n " + FALSE_EXPR@15138..15427 + EXPR_LOCAL@15138..15427 + LOCAL_KW@15138..15143 "local" + WHITESPACE@15143..15144 " " + BIND_DESTRUCT@15144..15159 + DESTRUCT_FULL@15144..15146 + NAME@15144..15146 + IDENT@15144..15146 "ak" + WHITESPACE@15146..15147 " " + ASSIGN@15147..15148 "=" + WHITESPACE@15148..15149 " " + EXPR_APPLY@15149..15159 + EXPR_VAR@15149..15153 + NAME@15149..15153 + IDENT@15149..15153 "keyF" + ARGS_DESC@15153..15159 + L_PAREN@15153..15154 "(" + ARG@15154..15158 + EXPR_INDEX_EXPR@15154..15158 + LHS_EXPR@15154..15155 + EXPR_VAR@15154..15155 + NAME@15154..15155 + IDENT@15154..15155 "a" + L_BRACK@15155..15156 "[" + EXPR_VAR@15156..15157 + NAME@15156..15157 + IDENT@15156..15157 "i" + R_BRACK@15157..15158 "]" + R_PAREN@15158..15159 ")" + SEMI@15159..15160 ";" + WHITESPACE@15160..15169 "\n " + EXPR_LOCAL@15169..15427 + LOCAL_KW@15169..15174 "local" + WHITESPACE@15174..15175 " " + BIND_DESTRUCT@15175..15190 + DESTRUCT_FULL@15175..15177 + NAME@15175..15177 + IDENT@15175..15177 "bk" + WHITESPACE@15177..15178 " " + ASSIGN@15178..15179 "=" + WHITESPACE@15179..15180 " " + EXPR_APPLY@15180..15190 + EXPR_VAR@15180..15184 + NAME@15180..15184 + IDENT@15180..15184 "keyF" + ARGS_DESC@15184..15190 + L_PAREN@15184..15185 "(" + ARG@15185..15189 + EXPR_INDEX_EXPR@15185..15189 + LHS_EXPR@15185..15186 + EXPR_VAR@15185..15186 + NAME@15185..15186 + IDENT@15185..15186 "b" + L_BRACK@15186..15187 "[" + EXPR_VAR@15187..15188 + NAME@15187..15188 + IDENT@15187..15188 "j" + R_BRACK@15188..15189 "]" + R_PAREN@15189..15190 ")" + SEMI@15190..15191 ";" + WHITESPACE@15191..15200 "\n " + EXPR_IF_THEN_ELSE@15200..15427 + IF_KW@15200..15202 "if" + WHITESPACE@15202..15203 " " + EXPR_BINARY@15203..15211 + LHS_EXPR@15203..15205 + EXPR_VAR@15203..15205 + NAME@15203..15205 + IDENT@15203..15205 "ak" + WHITESPACE@15205..15206 " " + EQ@15206..15208 "==" + WHITESPACE@15208..15209 " " + EXPR_VAR@15209..15211 + NAME@15209..15211 + IDENT@15209..15211 "bk" + WHITESPACE@15211..15212 " " + THEN_KW@15212..15216 "then" + WHITESPACE@15216..15227 "\n " + TRUE_EXPR@15227..15275 + EXPR_APPLY@15227..15275 + EXPR_VAR@15227..15230 + NAME@15227..15230 + IDENT@15227..15230 "aux" + ARGS_DESC@15230..15275 + L_PAREN@15230..15231 "(" + ARG@15231..15232 + EXPR_VAR@15231..15232 + NAME@15231..15232 + IDENT@15231..15232 "a" + COMMA@15232..15233 "," + WHITESPACE@15233..15234 " " + ARG@15234..15235 + EXPR_VAR@15234..15235 + NAME@15234..15235 + IDENT@15234..15235 "b" + COMMA@15235..15236 "," + WHITESPACE@15236..15237 " " + ARG@15237..15242 + EXPR_BINARY@15237..15242 + LHS_EXPR@15237..15238 + EXPR_VAR@15237..15238 + NAME@15237..15238 + IDENT@15237..15238 "i" + WHITESPACE@15238..15239 " " + PLUS@15239..15240 "+" + WHITESPACE@15240..15241 " " + EXPR_NUMBER@15241..15242 + FLOAT@15241..15242 "1" + COMMA@15242..15243 "," + WHITESPACE@15243..15244 " " + ARG@15244..15249 + EXPR_BINARY@15244..15249 + LHS_EXPR@15244..15245 + EXPR_VAR@15244..15245 + NAME@15244..15245 + IDENT@15244..15245 "j" + WHITESPACE@15245..15246 " " + PLUS@15246..15247 "+" + WHITESPACE@15247..15248 " " + EXPR_NUMBER@15248..15249 + FLOAT@15248..15249 "1" + COMMA@15249..15250 "," + WHITESPACE@15250..15251 " " + ARG@15251..15263 + EXPR_BINARY@15251..15263 + LHS_EXPR@15251..15254 + EXPR_VAR@15251..15254 + NAME@15251..15254 + IDENT@15251..15254 "acc" + WHITESPACE@15254..15255 " " + PLUS@15255..15256 "+" + WHITESPACE@15256..15257 " " + EXPR_ARRAY@15257..15263 + L_BRACK@15257..15258 "[" + EXPR_INDEX_EXPR@15258..15262 + LHS_EXPR@15258..15259 + EXPR_VAR@15258..15259 + NAME@15258..15259 + IDENT@15258..15259 "a" + L_BRACK@15259..15260 "[" + EXPR_VAR@15260..15261 + NAME@15260..15261 + IDENT@15260..15261 "i" + R_BRACK@15261..15262 "]" + R_BRACK@15262..15263 "]" + R_PAREN@15263..15264 ")" + WHITESPACE@15264..15265 " " + TAILSTRICT_KW@15265..15275 "tailstrict" + WHITESPACE@15275..15284 "\n " + ELSE_KW@15284..15288 "else" + WHITESPACE@15288..15289 " " + FALSE_EXPR@15289..15427 + EXPR_IF_THEN_ELSE@15289..15427 + IF_KW@15289..15291 "if" + WHITESPACE@15291..15292 " " + EXPR_BINARY@15292..15299 + LHS_EXPR@15292..15294 + EXPR_VAR@15292..15294 + NAME@15292..15294 + IDENT@15292..15294 "ak" + WHITESPACE@15294..15295 " " + LT@15295..15296 "<" + WHITESPACE@15296..15297 " " + EXPR_VAR@15297..15299 + NAME@15297..15299 + IDENT@15297..15299 "bk" + WHITESPACE@15299..15300 " " + THEN_KW@15300..15304 "then" + WHITESPACE@15304..15315 "\n " + TRUE_EXPR@15315..15359 + EXPR_APPLY@15315..15359 + EXPR_VAR@15315..15318 + NAME@15315..15318 + IDENT@15315..15318 "aux" + ARGS_DESC@15318..15359 + L_PAREN@15318..15319 "(" + ARG@15319..15320 + EXPR_VAR@15319..15320 + NAME@15319..15320 + IDENT@15319..15320 "a" + COMMA@15320..15321 "," + WHITESPACE@15321..15322 " " + ARG@15322..15323 + EXPR_VAR@15322..15323 + NAME@15322..15323 + IDENT@15322..15323 "b" + COMMA@15323..15324 "," + WHITESPACE@15324..15325 " " + ARG@15325..15330 + EXPR_BINARY@15325..15330 + LHS_EXPR@15325..15326 + EXPR_VAR@15325..15326 + NAME@15325..15326 + IDENT@15325..15326 "i" + WHITESPACE@15326..15327 " " + PLUS@15327..15328 "+" + WHITESPACE@15328..15329 " " + EXPR_NUMBER@15329..15330 + FLOAT@15329..15330 "1" + COMMA@15330..15331 "," + WHITESPACE@15331..15332 " " + ARG@15332..15333 + EXPR_VAR@15332..15333 + NAME@15332..15333 + IDENT@15332..15333 "j" + COMMA@15333..15334 "," + WHITESPACE@15334..15335 " " + ARG@15335..15347 + EXPR_BINARY@15335..15347 + LHS_EXPR@15335..15338 + EXPR_VAR@15335..15338 + NAME@15335..15338 + IDENT@15335..15338 "acc" + WHITESPACE@15338..15339 " " + PLUS@15339..15340 "+" + WHITESPACE@15340..15341 " " + EXPR_ARRAY@15341..15347 + L_BRACK@15341..15342 "[" + EXPR_INDEX_EXPR@15342..15346 + LHS_EXPR@15342..15343 + EXPR_VAR@15342..15343 + NAME@15342..15343 + IDENT@15342..15343 "a" + L_BRACK@15343..15344 "[" + EXPR_VAR@15344..15345 + NAME@15344..15345 + IDENT@15344..15345 "i" + R_BRACK@15345..15346 "]" + R_BRACK@15346..15347 "]" + R_PAREN@15347..15348 ")" + WHITESPACE@15348..15349 " " + TAILSTRICT_KW@15349..15359 "tailstrict" + WHITESPACE@15359..15368 "\n " + ELSE_KW@15368..15372 "else" + WHITESPACE@15372..15383 "\n " + FALSE_EXPR@15383..15427 + EXPR_APPLY@15383..15427 + EXPR_VAR@15383..15386 + NAME@15383..15386 + IDENT@15383..15386 "aux" + ARGS_DESC@15386..15427 + L_PAREN@15386..15387 "(" + ARG@15387..15388 + EXPR_VAR@15387..15388 + NAME@15387..15388 + IDENT@15387..15388 "a" + COMMA@15388..15389 "," + WHITESPACE@15389..15390 " " + ARG@15390..15391 + EXPR_VAR@15390..15391 + NAME@15390..15391 + IDENT@15390..15391 "b" + COMMA@15391..15392 "," + WHITESPACE@15392..15393 " " + ARG@15393..15394 + EXPR_VAR@15393..15394 + NAME@15393..15394 + IDENT@15393..15394 "i" + COMMA@15394..15395 "," + WHITESPACE@15395..15396 " " + ARG@15396..15401 + EXPR_BINARY@15396..15401 + LHS_EXPR@15396..15397 + EXPR_VAR@15396..15397 + NAME@15396..15397 + IDENT@15396..15397 "j" + WHITESPACE@15397..15398 " " + PLUS@15398..15399 "+" + WHITESPACE@15399..15400 " " + EXPR_NUMBER@15400..15401 + FLOAT@15400..15401 "1" + COMMA@15401..15402 "," + WHITESPACE@15402..15403 " " + ARG@15403..15415 + EXPR_BINARY@15403..15415 + LHS_EXPR@15403..15406 + EXPR_VAR@15403..15406 + NAME@15403..15406 + IDENT@15403..15406 "acc" + WHITESPACE@15406..15407 " " + PLUS@15407..15408 "+" + WHITESPACE@15408..15409 " " + EXPR_ARRAY@15409..15415 + L_BRACK@15409..15410 "[" + EXPR_INDEX_EXPR@15410..15414 + LHS_EXPR@15410..15411 + EXPR_VAR@15410..15411 + NAME@15410..15411 + IDENT@15410..15411 "b" + L_BRACK@15411..15412 "[" + EXPR_VAR@15412..15413 + NAME@15412..15413 + IDENT@15412..15413 "j" + R_BRACK@15413..15414 "]" + R_BRACK@15414..15415 "]" + R_PAREN@15415..15416 ")" + WHITESPACE@15416..15417 " " + TAILSTRICT_KW@15417..15427 "tailstrict" + SEMI@15427..15428 ";" + WHITESPACE@15428..15433 "\n " + EXPR_APPLY@15433..15452 + EXPR_VAR@15433..15436 + NAME@15433..15436 + IDENT@15433..15436 "aux" + ARGS_DESC@15436..15452 + L_PAREN@15436..15437 "(" + ARG@15437..15438 + EXPR_VAR@15437..15438 + NAME@15437..15438 + IDENT@15437..15438 "a" + COMMA@15438..15439 "," + WHITESPACE@15439..15440 " " + ARG@15440..15441 + EXPR_VAR@15440..15441 + NAME@15440..15441 + IDENT@15440..15441 "b" + COMMA@15441..15442 "," + WHITESPACE@15442..15443 " " + ARG@15443..15444 + EXPR_NUMBER@15443..15444 + FLOAT@15443..15444 "0" + COMMA@15444..15445 "," + WHITESPACE@15445..15446 " " + ARG@15446..15447 + EXPR_NUMBER@15446..15447 + FLOAT@15446..15447 "0" + COMMA@15447..15448 "," + WHITESPACE@15448..15449 " " + ARG@15449..15451 + EXPR_ARRAY@15449..15451 + L_BRACK@15449..15450 "[" + R_BRACK@15450..15451 "]" + R_PAREN@15451..15452 ")" + COMMA@15452..15453 "," + WHITESPACE@15453..15457 "\n\n " + MEMBER_FIELD@15457..15879 + FIELD_METHOD@15457..15879 + FIELD_NAME_FIXED@15457..15465 + NAME@15457..15465 + IDENT@15457..15465 "setInter" + PARAMS_DESC@15465..15480 + L_PAREN@15465..15466 "(" + PARAM@15466..15467 + DESTRUCT_FULL@15466..15467 + NAME@15466..15467 + IDENT@15466..15467 "a" + COMMA@15467..15468 "," + WHITESPACE@15468..15469 " " + PARAM@15469..15470 + DESTRUCT_FULL@15469..15470 + NAME@15469..15470 + IDENT@15469..15470 "b" + COMMA@15470..15471 "," + WHITESPACE@15471..15472 " " + PARAM@15472..15479 + DESTRUCT_FULL@15472..15476 + NAME@15472..15476 + IDENT@15472..15476 "keyF" + ASSIGN@15476..15477 "=" + EXPR_VAR@15477..15479 + NAME@15477..15479 + IDENT@15477..15479 "id" + R_PAREN@15479..15480 ")" + COLONCOLON@15480..15482 "::" + WHITESPACE@15482..15487 "\n " + EXPR_LOCAL@15487..15879 + LOCAL_KW@15487..15492 "local" + WHITESPACE@15492..15493 " " + BIND_FUNCTION@15493..15843 + NAME@15493..15496 + IDENT@15493..15496 "aux" + PARAMS_DESC@15496..15513 + L_PAREN@15496..15497 "(" + PARAM@15497..15498 + DESTRUCT_FULL@15497..15498 + NAME@15497..15498 + IDENT@15497..15498 "a" + COMMA@15498..15499 "," + WHITESPACE@15499..15500 " " + PARAM@15500..15501 + DESTRUCT_FULL@15500..15501 + NAME@15500..15501 + IDENT@15500..15501 "b" + COMMA@15501..15502 "," + WHITESPACE@15502..15503 " " + PARAM@15503..15504 + DESTRUCT_FULL@15503..15504 + NAME@15503..15504 + IDENT@15503..15504 "i" + COMMA@15504..15505 "," + WHITESPACE@15505..15506 " " + PARAM@15506..15507 + DESTRUCT_FULL@15506..15507 + NAME@15506..15507 + IDENT@15506..15507 "j" + COMMA@15507..15508 "," + WHITESPACE@15508..15509 " " + PARAM@15509..15512 + DESTRUCT_FULL@15509..15512 + NAME@15509..15512 + IDENT@15509..15512 "acc" + R_PAREN@15512..15513 ")" + WHITESPACE@15513..15514 " " + ASSIGN@15514..15515 "=" + WHITESPACE@15515..15522 "\n " + EXPR_IF_THEN_ELSE@15522..15843 + IF_KW@15522..15524 "if" + WHITESPACE@15524..15525 " " + EXPR_BINARY@15525..15565 + LHS_EXPR@15525..15543 + EXPR_BINARY@15525..15543 + LHS_EXPR@15525..15526 + EXPR_VAR@15525..15526 + NAME@15525..15526 + IDENT@15525..15526 "i" + WHITESPACE@15526..15527 " " + GE@15527..15529 ">=" + WHITESPACE@15529..15530 " " + EXPR_APPLY@15530..15543 + EXPR_INDEX@15530..15540 + EXPR_VAR@15530..15533 + NAME@15530..15533 + IDENT@15530..15533 "std" + DOT@15533..15534 "." + NAME@15534..15540 + IDENT@15534..15540 "length" + ARGS_DESC@15540..15543 + L_PAREN@15540..15541 "(" + ARG@15541..15542 + EXPR_VAR@15541..15542 + NAME@15541..15542 + IDENT@15541..15542 "a" + R_PAREN@15542..15543 ")" + WHITESPACE@15543..15544 " " + OR@15544..15546 "||" + WHITESPACE@15546..15547 " " + EXPR_BINARY@15547..15565 + LHS_EXPR@15547..15548 + EXPR_VAR@15547..15548 + NAME@15547..15548 + IDENT@15547..15548 "j" + WHITESPACE@15548..15549 " " + GE@15549..15551 ">=" + WHITESPACE@15551..15552 " " + EXPR_APPLY@15552..15565 + EXPR_INDEX@15552..15562 + EXPR_VAR@15552..15555 + NAME@15552..15555 + IDENT@15552..15555 "std" + DOT@15555..15556 "." + NAME@15556..15562 + IDENT@15556..15562 "length" + ARGS_DESC@15562..15565 + L_PAREN@15562..15563 "(" + ARG@15563..15564 + EXPR_VAR@15563..15564 + NAME@15563..15564 + IDENT@15563..15564 "b" + R_PAREN@15564..15565 ")" + WHITESPACE@15565..15566 " " + THEN_KW@15566..15570 "then" + WHITESPACE@15570..15579 "\n " + TRUE_EXPR@15579..15582 + EXPR_VAR@15579..15582 + NAME@15579..15582 + IDENT@15579..15582 "acc" + WHITESPACE@15582..15589 "\n " + ELSE_KW@15589..15593 "else" + WHITESPACE@15593..15602 "\n " + FALSE_EXPR@15602..15843 + EXPR_IF_THEN_ELSE@15602..15843 + IF_KW@15602..15604 "if" + WHITESPACE@15604..15605 " " + EXPR_BINARY@15605..15629 + LHS_EXPR@15605..15615 + EXPR_APPLY@15605..15615 + EXPR_VAR@15605..15609 + NAME@15605..15609 + IDENT@15605..15609 "keyF" + ARGS_DESC@15609..15615 + L_PAREN@15609..15610 "(" + ARG@15610..15614 + EXPR_INDEX_EXPR@15610..15614 + LHS_EXPR@15610..15611 + EXPR_VAR@15610..15611 + NAME@15610..15611 + IDENT@15610..15611 "a" + L_BRACK@15611..15612 "[" + EXPR_VAR@15612..15613 + NAME@15612..15613 + IDENT@15612..15613 "i" + R_BRACK@15613..15614 "]" + R_PAREN@15614..15615 ")" + WHITESPACE@15615..15616 " " + EQ@15616..15618 "==" + WHITESPACE@15618..15619 " " + EXPR_APPLY@15619..15629 + EXPR_VAR@15619..15623 + NAME@15619..15623 + IDENT@15619..15623 "keyF" + ARGS_DESC@15623..15629 + L_PAREN@15623..15624 "(" + ARG@15624..15628 + EXPR_INDEX_EXPR@15624..15628 + LHS_EXPR@15624..15625 + EXPR_VAR@15624..15625 + NAME@15624..15625 + IDENT@15624..15625 "b" + L_BRACK@15625..15626 "[" + EXPR_VAR@15626..15627 + NAME@15626..15627 + IDENT@15626..15627 "j" + R_BRACK@15627..15628 "]" + R_PAREN@15628..15629 ")" + WHITESPACE@15629..15630 " " + THEN_KW@15630..15634 "then" + WHITESPACE@15634..15645 "\n " + TRUE_EXPR@15645..15693 + EXPR_APPLY@15645..15693 + EXPR_VAR@15645..15648 + NAME@15645..15648 + IDENT@15645..15648 "aux" + ARGS_DESC@15648..15693 + L_PAREN@15648..15649 "(" + ARG@15649..15650 + EXPR_VAR@15649..15650 + NAME@15649..15650 + IDENT@15649..15650 "a" + COMMA@15650..15651 "," + WHITESPACE@15651..15652 " " + ARG@15652..15653 + EXPR_VAR@15652..15653 + NAME@15652..15653 + IDENT@15652..15653 "b" + COMMA@15653..15654 "," + WHITESPACE@15654..15655 " " + ARG@15655..15660 + EXPR_BINARY@15655..15660 + LHS_EXPR@15655..15656 + EXPR_VAR@15655..15656 + NAME@15655..15656 + IDENT@15655..15656 "i" + WHITESPACE@15656..15657 " " + PLUS@15657..15658 "+" + WHITESPACE@15658..15659 " " + EXPR_NUMBER@15659..15660 + FLOAT@15659..15660 "1" + COMMA@15660..15661 "," + WHITESPACE@15661..15662 " " + ARG@15662..15667 + EXPR_BINARY@15662..15667 + LHS_EXPR@15662..15663 + EXPR_VAR@15662..15663 + NAME@15662..15663 + IDENT@15662..15663 "j" + WHITESPACE@15663..15664 " " + PLUS@15664..15665 "+" + WHITESPACE@15665..15666 " " + EXPR_NUMBER@15666..15667 + FLOAT@15666..15667 "1" + COMMA@15667..15668 "," + WHITESPACE@15668..15669 " " + ARG@15669..15681 + EXPR_BINARY@15669..15681 + LHS_EXPR@15669..15672 + EXPR_VAR@15669..15672 + NAME@15669..15672 + IDENT@15669..15672 "acc" + WHITESPACE@15672..15673 " " + PLUS@15673..15674 "+" + WHITESPACE@15674..15675 " " + EXPR_ARRAY@15675..15681 + L_BRACK@15675..15676 "[" + EXPR_INDEX_EXPR@15676..15680 + LHS_EXPR@15676..15677 + EXPR_VAR@15676..15677 + NAME@15676..15677 + IDENT@15676..15677 "a" + L_BRACK@15677..15678 "[" + EXPR_VAR@15678..15679 + NAME@15678..15679 + IDENT@15678..15679 "i" + R_BRACK@15679..15680 "]" + R_BRACK@15680..15681 "]" + R_PAREN@15681..15682 ")" + WHITESPACE@15682..15683 " " + TAILSTRICT_KW@15683..15693 "tailstrict" + WHITESPACE@15693..15702 "\n " + ELSE_KW@15702..15706 "else" + WHITESPACE@15706..15707 " " + FALSE_EXPR@15707..15843 + EXPR_IF_THEN_ELSE@15707..15843 + IF_KW@15707..15709 "if" + WHITESPACE@15709..15710 " " + EXPR_BINARY@15710..15733 + LHS_EXPR@15710..15720 + EXPR_APPLY@15710..15720 + EXPR_VAR@15710..15714 + NAME@15710..15714 + IDENT@15710..15714 "keyF" + ARGS_DESC@15714..15720 + L_PAREN@15714..15715 "(" + ARG@15715..15719 + EXPR_INDEX_EXPR@15715..15719 + LHS_EXPR@15715..15716 + EXPR_VAR@15715..15716 + NAME@15715..15716 + IDENT@15715..15716 "a" + L_BRACK@15716..15717 "[" + EXPR_VAR@15717..15718 + NAME@15717..15718 + IDENT@15717..15718 "i" + R_BRACK@15718..15719 "]" + R_PAREN@15719..15720 ")" + WHITESPACE@15720..15721 " " + LT@15721..15722 "<" + WHITESPACE@15722..15723 " " + EXPR_APPLY@15723..15733 + EXPR_VAR@15723..15727 + NAME@15723..15727 + IDENT@15723..15727 "keyF" + ARGS_DESC@15727..15733 + L_PAREN@15727..15728 "(" + ARG@15728..15732 + EXPR_INDEX_EXPR@15728..15732 + LHS_EXPR@15728..15729 + EXPR_VAR@15728..15729 + NAME@15728..15729 + IDENT@15728..15729 "b" + L_BRACK@15729..15730 "[" + EXPR_VAR@15730..15731 + NAME@15730..15731 + IDENT@15730..15731 "j" + R_BRACK@15731..15732 "]" + R_PAREN@15732..15733 ")" + WHITESPACE@15733..15734 " " + THEN_KW@15734..15738 "then" + WHITESPACE@15738..15749 "\n " + TRUE_EXPR@15749..15784 + EXPR_APPLY@15749..15784 + EXPR_VAR@15749..15752 + NAME@15749..15752 + IDENT@15749..15752 "aux" + ARGS_DESC@15752..15784 + L_PAREN@15752..15753 "(" + ARG@15753..15754 + EXPR_VAR@15753..15754 + NAME@15753..15754 + IDENT@15753..15754 "a" + COMMA@15754..15755 "," + WHITESPACE@15755..15756 " " + ARG@15756..15757 + EXPR_VAR@15756..15757 + NAME@15756..15757 + IDENT@15756..15757 "b" + COMMA@15757..15758 "," + WHITESPACE@15758..15759 " " + ARG@15759..15764 + EXPR_BINARY@15759..15764 + LHS_EXPR@15759..15760 + EXPR_VAR@15759..15760 + NAME@15759..15760 + IDENT@15759..15760 "i" + WHITESPACE@15760..15761 " " + PLUS@15761..15762 "+" + WHITESPACE@15762..15763 " " + EXPR_NUMBER@15763..15764 + FLOAT@15763..15764 "1" + COMMA@15764..15765 "," + WHITESPACE@15765..15766 " " + ARG@15766..15767 + EXPR_VAR@15766..15767 + NAME@15766..15767 + IDENT@15766..15767 "j" + COMMA@15767..15768 "," + WHITESPACE@15768..15769 " " + ARG@15769..15772 + EXPR_VAR@15769..15772 + NAME@15769..15772 + IDENT@15769..15772 "acc" + R_PAREN@15772..15773 ")" + WHITESPACE@15773..15774 " " + TAILSTRICT_KW@15774..15784 "tailstrict" + WHITESPACE@15784..15793 "\n " + ELSE_KW@15793..15797 "else" + WHITESPACE@15797..15808 "\n " + FALSE_EXPR@15808..15843 + EXPR_APPLY@15808..15843 + EXPR_VAR@15808..15811 + NAME@15808..15811 + IDENT@15808..15811 "aux" + ARGS_DESC@15811..15843 + L_PAREN@15811..15812 "(" + ARG@15812..15813 + EXPR_VAR@15812..15813 + NAME@15812..15813 + IDENT@15812..15813 "a" + COMMA@15813..15814 "," + WHITESPACE@15814..15815 " " + ARG@15815..15816 + EXPR_VAR@15815..15816 + NAME@15815..15816 + IDENT@15815..15816 "b" + COMMA@15816..15817 "," + WHITESPACE@15817..15818 " " + ARG@15818..15819 + EXPR_VAR@15818..15819 + NAME@15818..15819 + IDENT@15818..15819 "i" + COMMA@15819..15820 "," + WHITESPACE@15820..15821 " " + ARG@15821..15826 + EXPR_BINARY@15821..15826 + LHS_EXPR@15821..15822 + EXPR_VAR@15821..15822 + NAME@15821..15822 + IDENT@15821..15822 "j" + WHITESPACE@15822..15823 " " + PLUS@15823..15824 "+" + WHITESPACE@15824..15825 " " + EXPR_NUMBER@15825..15826 + FLOAT@15825..15826 "1" + COMMA@15826..15827 "," + WHITESPACE@15827..15828 " " + ARG@15828..15831 + EXPR_VAR@15828..15831 + NAME@15828..15831 + IDENT@15828..15831 "acc" + R_PAREN@15831..15832 ")" + WHITESPACE@15832..15833 " " + TAILSTRICT_KW@15833..15843 "tailstrict" + SEMI@15843..15844 ";" + WHITESPACE@15844..15849 "\n " + EXPR_APPLY@15849..15879 + EXPR_VAR@15849..15852 + NAME@15849..15852 + IDENT@15849..15852 "aux" + ARGS_DESC@15852..15879 + L_PAREN@15852..15853 "(" + ARG@15853..15854 + EXPR_VAR@15853..15854 + NAME@15853..15854 + IDENT@15853..15854 "a" + COMMA@15854..15855 "," + WHITESPACE@15855..15856 " " + ARG@15856..15857 + EXPR_VAR@15856..15857 + NAME@15856..15857 + IDENT@15856..15857 "b" + COMMA@15857..15858 "," + WHITESPACE@15858..15859 " " + ARG@15859..15860 + EXPR_NUMBER@15859..15860 + FLOAT@15859..15860 "0" + COMMA@15860..15861 "," + WHITESPACE@15861..15862 " " + ARG@15862..15863 + EXPR_NUMBER@15862..15863 + FLOAT@15862..15863 "0" + COMMA@15863..15864 "," + WHITESPACE@15864..15865 " " + ARG@15865..15867 + EXPR_ARRAY@15865..15867 + L_BRACK@15865..15866 "[" + R_BRACK@15866..15867 "]" + R_PAREN@15867..15868 ")" + WHITESPACE@15868..15869 " " + TAILSTRICT_KW@15869..15879 "tailstrict" + COMMA@15879..15880 "," + WHITESPACE@15880..15884 "\n\n " + MEMBER_FIELD@15884..16341 + FIELD_METHOD@15884..16341 + FIELD_NAME_FIXED@15884..15891 + NAME@15884..15891 + IDENT@15884..15891 "setDiff" + PARAMS_DESC@15891..15906 + L_PAREN@15891..15892 "(" + PARAM@15892..15893 + DESTRUCT_FULL@15892..15893 + NAME@15892..15893 + IDENT@15892..15893 "a" + COMMA@15893..15894 "," + WHITESPACE@15894..15895 " " + PARAM@15895..15896 + DESTRUCT_FULL@15895..15896 + NAME@15895..15896 + IDENT@15895..15896 "b" + COMMA@15896..15897 "," + WHITESPACE@15897..15898 " " + PARAM@15898..15905 + DESTRUCT_FULL@15898..15902 + NAME@15898..15902 + IDENT@15898..15902 "keyF" + ASSIGN@15902..15903 "=" + EXPR_VAR@15903..15905 + NAME@15903..15905 + IDENT@15903..15905 "id" + R_PAREN@15905..15906 ")" + COLONCOLON@15906..15908 "::" + WHITESPACE@15908..15913 "\n " + EXPR_LOCAL@15913..16341 + LOCAL_KW@15913..15918 "local" + WHITESPACE@15918..15919 " " + BIND_FUNCTION@15919..16305 + NAME@15919..15922 + IDENT@15919..15922 "aux" + PARAMS_DESC@15922..15939 + L_PAREN@15922..15923 "(" + PARAM@15923..15924 + DESTRUCT_FULL@15923..15924 + NAME@15923..15924 + IDENT@15923..15924 "a" + COMMA@15924..15925 "," + WHITESPACE@15925..15926 " " + PARAM@15926..15927 + DESTRUCT_FULL@15926..15927 + NAME@15926..15927 + IDENT@15926..15927 "b" + COMMA@15927..15928 "," + WHITESPACE@15928..15929 " " + PARAM@15929..15930 + DESTRUCT_FULL@15929..15930 + NAME@15929..15930 + IDENT@15929..15930 "i" + COMMA@15930..15931 "," + WHITESPACE@15931..15932 " " + PARAM@15932..15933 + DESTRUCT_FULL@15932..15933 + NAME@15932..15933 + IDENT@15932..15933 "j" + COMMA@15933..15934 "," + WHITESPACE@15934..15935 " " + PARAM@15935..15938 + DESTRUCT_FULL@15935..15938 + NAME@15935..15938 + IDENT@15935..15938 "acc" + R_PAREN@15938..15939 ")" + WHITESPACE@15939..15940 " " + ASSIGN@15940..15941 "=" + WHITESPACE@15941..15948 "\n " + EXPR_IF_THEN_ELSE@15948..16305 + IF_KW@15948..15950 "if" + WHITESPACE@15950..15951 " " + EXPR_BINARY@15951..15969 + LHS_EXPR@15951..15952 + EXPR_VAR@15951..15952 + NAME@15951..15952 + IDENT@15951..15952 "i" + WHITESPACE@15952..15953 " " + GE@15953..15955 ">=" + WHITESPACE@15955..15956 " " + EXPR_APPLY@15956..15969 + EXPR_INDEX@15956..15966 + EXPR_VAR@15956..15959 + NAME@15956..15959 + IDENT@15956..15959 "std" + DOT@15959..15960 "." + NAME@15960..15966 + IDENT@15960..15966 "length" + ARGS_DESC@15966..15969 + L_PAREN@15966..15967 "(" + ARG@15967..15968 + EXPR_VAR@15967..15968 + NAME@15967..15968 + IDENT@15967..15968 "a" + R_PAREN@15968..15969 ")" + WHITESPACE@15969..15970 " " + THEN_KW@15970..15974 "then" + WHITESPACE@15974..15983 "\n " + TRUE_EXPR@15983..15986 + EXPR_VAR@15983..15986 + NAME@15983..15986 + IDENT@15983..15986 "acc" + WHITESPACE@15986..15993 "\n " + ELSE_KW@15993..15997 "else" + WHITESPACE@15997..15998 " " + FALSE_EXPR@15998..16305 + EXPR_IF_THEN_ELSE@15998..16305 + IF_KW@15998..16000 "if" + WHITESPACE@16000..16001 " " + EXPR_BINARY@16001..16019 + LHS_EXPR@16001..16002 + EXPR_VAR@16001..16002 + NAME@16001..16002 + IDENT@16001..16002 "j" + WHITESPACE@16002..16003 " " + GE@16003..16005 ">=" + WHITESPACE@16005..16006 " " + EXPR_APPLY@16006..16019 + EXPR_INDEX@16006..16016 + EXPR_VAR@16006..16009 + NAME@16006..16009 + IDENT@16006..16009 "std" + DOT@16009..16010 "." + NAME@16010..16016 + IDENT@16010..16016 "length" + ARGS_DESC@16016..16019 + L_PAREN@16016..16017 "(" + ARG@16017..16018 + EXPR_VAR@16017..16018 + NAME@16017..16018 + IDENT@16017..16018 "b" + R_PAREN@16018..16019 ")" + WHITESPACE@16019..16020 " " + THEN_KW@16020..16024 "then" + WHITESPACE@16024..16033 "\n " + TRUE_EXPR@16033..16044 + EXPR_BINARY@16033..16044 + LHS_EXPR@16033..16036 + EXPR_VAR@16033..16036 + NAME@16033..16036 + IDENT@16033..16036 "acc" + WHITESPACE@16036..16037 " " + PLUS@16037..16038 "+" + WHITESPACE@16038..16039 " " + EXPR_SLICE@16039..16044 + EXPR_VAR@16039..16040 + NAME@16039..16040 + IDENT@16039..16040 "a" + SLICE_DESC@16040..16044 + L_BRACK@16040..16041 "[" + EXPR_VAR@16041..16042 + NAME@16041..16042 + IDENT@16041..16042 "i" + COLON@16042..16043 ":" + R_BRACK@16043..16044 "]" + WHITESPACE@16044..16051 "\n " + ELSE_KW@16051..16055 "else" + WHITESPACE@16055..16064 "\n " + FALSE_EXPR@16064..16305 + EXPR_IF_THEN_ELSE@16064..16305 + IF_KW@16064..16066 "if" + WHITESPACE@16066..16067 " " + EXPR_BINARY@16067..16091 + LHS_EXPR@16067..16077 + EXPR_APPLY@16067..16077 + EXPR_VAR@16067..16071 + NAME@16067..16071 + IDENT@16067..16071 "keyF" + ARGS_DESC@16071..16077 + L_PAREN@16071..16072 "(" + ARG@16072..16076 + EXPR_INDEX_EXPR@16072..16076 + LHS_EXPR@16072..16073 + EXPR_VAR@16072..16073 + NAME@16072..16073 + IDENT@16072..16073 "a" + L_BRACK@16073..16074 "[" + EXPR_VAR@16074..16075 + NAME@16074..16075 + IDENT@16074..16075 "i" + R_BRACK@16075..16076 "]" + R_PAREN@16076..16077 ")" + WHITESPACE@16077..16078 " " + EQ@16078..16080 "==" + WHITESPACE@16080..16081 " " + EXPR_APPLY@16081..16091 + EXPR_VAR@16081..16085 + NAME@16081..16085 + IDENT@16081..16085 "keyF" + ARGS_DESC@16085..16091 + L_PAREN@16085..16086 "(" + ARG@16086..16090 + EXPR_INDEX_EXPR@16086..16090 + LHS_EXPR@16086..16087 + EXPR_VAR@16086..16087 + NAME@16086..16087 + IDENT@16086..16087 "b" + L_BRACK@16087..16088 "[" + EXPR_VAR@16088..16089 + NAME@16088..16089 + IDENT@16088..16089 "j" + R_BRACK@16089..16090 "]" + R_PAREN@16090..16091 ")" + WHITESPACE@16091..16092 " " + THEN_KW@16092..16096 "then" + WHITESPACE@16096..16107 "\n " + TRUE_EXPR@16107..16146 + EXPR_APPLY@16107..16146 + EXPR_VAR@16107..16110 + NAME@16107..16110 + IDENT@16107..16110 "aux" + ARGS_DESC@16110..16146 + L_PAREN@16110..16111 "(" + ARG@16111..16112 + EXPR_VAR@16111..16112 + NAME@16111..16112 + IDENT@16111..16112 "a" + COMMA@16112..16113 "," + WHITESPACE@16113..16114 " " + ARG@16114..16115 + EXPR_VAR@16114..16115 + NAME@16114..16115 + IDENT@16114..16115 "b" + COMMA@16115..16116 "," + WHITESPACE@16116..16117 " " + ARG@16117..16122 + EXPR_BINARY@16117..16122 + LHS_EXPR@16117..16118 + EXPR_VAR@16117..16118 + NAME@16117..16118 + IDENT@16117..16118 "i" + WHITESPACE@16118..16119 " " + PLUS@16119..16120 "+" + WHITESPACE@16120..16121 " " + EXPR_NUMBER@16121..16122 + FLOAT@16121..16122 "1" + COMMA@16122..16123 "," + WHITESPACE@16123..16124 " " + ARG@16124..16129 + EXPR_BINARY@16124..16129 + LHS_EXPR@16124..16125 + EXPR_VAR@16124..16125 + NAME@16124..16125 + IDENT@16124..16125 "j" + WHITESPACE@16125..16126 " " + PLUS@16126..16127 "+" + WHITESPACE@16127..16128 " " + EXPR_NUMBER@16128..16129 + FLOAT@16128..16129 "1" + COMMA@16129..16130 "," + WHITESPACE@16130..16131 " " + ARG@16131..16134 + EXPR_VAR@16131..16134 + NAME@16131..16134 + IDENT@16131..16134 "acc" + R_PAREN@16134..16135 ")" + WHITESPACE@16135..16136 " " + TAILSTRICT_KW@16136..16146 "tailstrict" + WHITESPACE@16146..16155 "\n " + ELSE_KW@16155..16159 "else" + WHITESPACE@16159..16160 " " + FALSE_EXPR@16160..16305 + EXPR_IF_THEN_ELSE@16160..16305 + IF_KW@16160..16162 "if" + WHITESPACE@16162..16163 " " + EXPR_BINARY@16163..16186 + LHS_EXPR@16163..16173 + EXPR_APPLY@16163..16173 + EXPR_VAR@16163..16167 + NAME@16163..16167 + IDENT@16163..16167 "keyF" + ARGS_DESC@16167..16173 + L_PAREN@16167..16168 "(" + ARG@16168..16172 + EXPR_INDEX_EXPR@16168..16172 + LHS_EXPR@16168..16169 + EXPR_VAR@16168..16169 + NAME@16168..16169 + IDENT@16168..16169 "a" + L_BRACK@16169..16170 "[" + EXPR_VAR@16170..16171 + NAME@16170..16171 + IDENT@16170..16171 "i" + R_BRACK@16171..16172 "]" + R_PAREN@16172..16173 ")" + WHITESPACE@16173..16174 " " + LT@16174..16175 "<" + WHITESPACE@16175..16176 " " + EXPR_APPLY@16176..16186 + EXPR_VAR@16176..16180 + NAME@16176..16180 + IDENT@16176..16180 "keyF" + ARGS_DESC@16180..16186 + L_PAREN@16180..16181 "(" + ARG@16181..16185 + EXPR_INDEX_EXPR@16181..16185 + LHS_EXPR@16181..16182 + EXPR_VAR@16181..16182 + NAME@16181..16182 + IDENT@16181..16182 "b" + L_BRACK@16182..16183 "[" + EXPR_VAR@16183..16184 + NAME@16183..16184 + IDENT@16183..16184 "j" + R_BRACK@16184..16185 "]" + R_PAREN@16185..16186 ")" + WHITESPACE@16186..16187 " " + THEN_KW@16187..16191 "then" + WHITESPACE@16191..16202 "\n " + TRUE_EXPR@16202..16246 + EXPR_APPLY@16202..16246 + EXPR_VAR@16202..16205 + NAME@16202..16205 + IDENT@16202..16205 "aux" + ARGS_DESC@16205..16246 + L_PAREN@16205..16206 "(" + ARG@16206..16207 + EXPR_VAR@16206..16207 + NAME@16206..16207 + IDENT@16206..16207 "a" + COMMA@16207..16208 "," + WHITESPACE@16208..16209 " " + ARG@16209..16210 + EXPR_VAR@16209..16210 + NAME@16209..16210 + IDENT@16209..16210 "b" + COMMA@16210..16211 "," + WHITESPACE@16211..16212 " " + ARG@16212..16217 + EXPR_BINARY@16212..16217 + LHS_EXPR@16212..16213 + EXPR_VAR@16212..16213 + NAME@16212..16213 + IDENT@16212..16213 "i" + WHITESPACE@16213..16214 " " + PLUS@16214..16215 "+" + WHITESPACE@16215..16216 " " + EXPR_NUMBER@16216..16217 + FLOAT@16216..16217 "1" + COMMA@16217..16218 "," + WHITESPACE@16218..16219 " " + ARG@16219..16220 + EXPR_VAR@16219..16220 + NAME@16219..16220 + IDENT@16219..16220 "j" + COMMA@16220..16221 "," + WHITESPACE@16221..16222 " " + ARG@16222..16234 + EXPR_BINARY@16222..16234 + LHS_EXPR@16222..16225 + EXPR_VAR@16222..16225 + NAME@16222..16225 + IDENT@16222..16225 "acc" + WHITESPACE@16225..16226 " " + PLUS@16226..16227 "+" + WHITESPACE@16227..16228 " " + EXPR_ARRAY@16228..16234 + L_BRACK@16228..16229 "[" + EXPR_INDEX_EXPR@16229..16233 + LHS_EXPR@16229..16230 + EXPR_VAR@16229..16230 + NAME@16229..16230 + IDENT@16229..16230 "a" + L_BRACK@16230..16231 "[" + EXPR_VAR@16231..16232 + NAME@16231..16232 + IDENT@16231..16232 "i" + R_BRACK@16232..16233 "]" + R_BRACK@16233..16234 "]" + R_PAREN@16234..16235 ")" + WHITESPACE@16235..16236 " " + TAILSTRICT_KW@16236..16246 "tailstrict" + WHITESPACE@16246..16255 "\n " + ELSE_KW@16255..16259 "else" + WHITESPACE@16259..16270 "\n " + FALSE_EXPR@16270..16305 + EXPR_APPLY@16270..16305 + EXPR_VAR@16270..16273 + NAME@16270..16273 + IDENT@16270..16273 "aux" + ARGS_DESC@16273..16305 + L_PAREN@16273..16274 "(" + ARG@16274..16275 + EXPR_VAR@16274..16275 + NAME@16274..16275 + IDENT@16274..16275 "a" + COMMA@16275..16276 "," + WHITESPACE@16276..16277 " " + ARG@16277..16278 + EXPR_VAR@16277..16278 + NAME@16277..16278 + IDENT@16277..16278 "b" + COMMA@16278..16279 "," + WHITESPACE@16279..16280 " " + ARG@16280..16281 + EXPR_VAR@16280..16281 + NAME@16280..16281 + IDENT@16280..16281 "i" + COMMA@16281..16282 "," + WHITESPACE@16282..16283 " " + ARG@16283..16288 + EXPR_BINARY@16283..16288 + LHS_EXPR@16283..16284 + EXPR_VAR@16283..16284 + NAME@16283..16284 + IDENT@16283..16284 "j" + WHITESPACE@16284..16285 " " + PLUS@16285..16286 "+" + WHITESPACE@16286..16287 " " + EXPR_NUMBER@16287..16288 + FLOAT@16287..16288 "1" + COMMA@16288..16289 "," + WHITESPACE@16289..16290 " " + ARG@16290..16293 + EXPR_VAR@16290..16293 + NAME@16290..16293 + IDENT@16290..16293 "acc" + R_PAREN@16293..16294 ")" + WHITESPACE@16294..16295 " " + TAILSTRICT_KW@16295..16305 "tailstrict" + SEMI@16305..16306 ";" + WHITESPACE@16306..16311 "\n " + EXPR_APPLY@16311..16341 + EXPR_VAR@16311..16314 + NAME@16311..16314 + IDENT@16311..16314 "aux" + ARGS_DESC@16314..16341 + L_PAREN@16314..16315 "(" + ARG@16315..16316 + EXPR_VAR@16315..16316 + NAME@16315..16316 + IDENT@16315..16316 "a" + COMMA@16316..16317 "," + WHITESPACE@16317..16318 " " + ARG@16318..16319 + EXPR_VAR@16318..16319 + NAME@16318..16319 + IDENT@16318..16319 "b" + COMMA@16319..16320 "," + WHITESPACE@16320..16321 " " + ARG@16321..16322 + EXPR_NUMBER@16321..16322 + FLOAT@16321..16322 "0" + COMMA@16322..16323 "," + WHITESPACE@16323..16324 " " + ARG@16324..16325 + EXPR_NUMBER@16324..16325 + FLOAT@16324..16325 "0" + COMMA@16325..16326 "," + WHITESPACE@16326..16327 " " + ARG@16327..16329 + EXPR_ARRAY@16327..16329 + L_BRACK@16327..16328 "[" + R_BRACK@16328..16329 "]" + R_PAREN@16329..16330 ")" + WHITESPACE@16330..16331 " " + TAILSTRICT_KW@16331..16341 "tailstrict" + COMMA@16341..16342 "," + WHITESPACE@16342..16346 "\n\n " + MEMBER_FIELD@16346..17134 + FIELD_METHOD@16346..17134 + FIELD_NAME_FIXED@16346..16356 + NAME@16346..16356 + IDENT@16346..16356 "mergePatch" + PARAMS_DESC@16356..16371 + L_PAREN@16356..16357 "(" + PARAM@16357..16363 + DESTRUCT_FULL@16357..16363 + NAME@16357..16363 + IDENT@16357..16363 "target" + COMMA@16363..16364 "," + WHITESPACE@16364..16365 " " + PARAM@16365..16370 + DESTRUCT_FULL@16365..16370 + NAME@16365..16370 + IDENT@16365..16370 "patch" + R_PAREN@16370..16371 ")" + COLONCOLON@16371..16373 "::" + WHITESPACE@16373..16378 "\n " + EXPR_IF_THEN_ELSE@16378..17134 + IF_KW@16378..16380 "if" + WHITESPACE@16380..16381 " " + EXPR_APPLY@16381..16400 + EXPR_INDEX@16381..16393 + EXPR_VAR@16381..16384 + NAME@16381..16384 + IDENT@16381..16384 "std" + DOT@16384..16385 "." + NAME@16385..16393 + IDENT@16385..16393 "isObject" + ARGS_DESC@16393..16400 + L_PAREN@16393..16394 "(" + ARG@16394..16399 + EXPR_VAR@16394..16399 + NAME@16394..16399 + IDENT@16394..16399 "patch" + R_PAREN@16399..16400 ")" + WHITESPACE@16400..16401 " " + THEN_KW@16401..16405 "then" + WHITESPACE@16405..16412 "\n " + TRUE_EXPR@16412..17113 + EXPR_LOCAL@16412..17113 + LOCAL_KW@16412..16417 "local" + WHITESPACE@16417..16418 " " + BIND_DESTRUCT@16418..16485 + DESTRUCT_FULL@16418..16431 + NAME@16418..16431 + IDENT@16418..16431 "target_object" + WHITESPACE@16431..16432 " " + ASSIGN@16432..16433 "=" + WHITESPACE@16433..16442 "\n " + EXPR_IF_THEN_ELSE@16442..16485 + IF_KW@16442..16444 "if" + WHITESPACE@16444..16445 " " + EXPR_APPLY@16445..16465 + EXPR_INDEX@16445..16457 + EXPR_VAR@16445..16448 + NAME@16445..16448 + IDENT@16445..16448 "std" + DOT@16448..16449 "." + NAME@16449..16457 + IDENT@16449..16457 "isObject" + ARGS_DESC@16457..16465 + L_PAREN@16457..16458 "(" + ARG@16458..16464 + EXPR_VAR@16458..16464 + NAME@16458..16464 + IDENT@16458..16464 "target" + R_PAREN@16464..16465 ")" + WHITESPACE@16465..16466 " " + THEN_KW@16466..16470 "then" + WHITESPACE@16470..16471 " " + TRUE_EXPR@16471..16477 + EXPR_VAR@16471..16477 + NAME@16471..16477 + IDENT@16471..16477 "target" + WHITESPACE@16477..16478 " " + ELSE_KW@16478..16482 "else" + WHITESPACE@16482..16483 " " + FALSE_EXPR@16483..16485 + EXPR_OBJECT@16483..16485 + OBJ_BODY_MEMBER_LIST@16483..16485 + L_BRACE@16483..16484 "{" + R_BRACE@16484..16485 "}" + SEMI@16485..16486 ";" + WHITESPACE@16486..16494 "\n\n " + EXPR_LOCAL@16494..17113 + LOCAL_KW@16494..16499 "local" + WHITESPACE@16499..16500 " " + BIND_DESTRUCT@16500..16599 + DESTRUCT_FULL@16500..16513 + NAME@16500..16513 + IDENT@16500..16513 "target_fields" + WHITESPACE@16513..16514 " " + ASSIGN@16514..16515 "=" + WHITESPACE@16515..16524 "\n " + EXPR_IF_THEN_ELSE@16524..16599 + IF_KW@16524..16526 "if" + WHITESPACE@16526..16527 " " + EXPR_APPLY@16527..16554 + EXPR_INDEX@16527..16539 + EXPR_VAR@16527..16530 + NAME@16527..16530 + IDENT@16527..16530 "std" + DOT@16530..16531 "." + NAME@16531..16539 + IDENT@16531..16539 "isObject" + ARGS_DESC@16539..16554 + L_PAREN@16539..16540 "(" + ARG@16540..16553 + EXPR_VAR@16540..16553 + NAME@16540..16553 + IDENT@16540..16553 "target_object" + R_PAREN@16553..16554 ")" + WHITESPACE@16554..16555 " " + THEN_KW@16555..16559 "then" + WHITESPACE@16559..16560 " " + TRUE_EXPR@16560..16591 + EXPR_APPLY@16560..16591 + EXPR_INDEX@16560..16576 + EXPR_VAR@16560..16563 + NAME@16560..16563 + IDENT@16560..16563 "std" + DOT@16563..16564 "." + NAME@16564..16576 + IDENT@16564..16576 "objectFields" + ARGS_DESC@16576..16591 + L_PAREN@16576..16577 "(" + ARG@16577..16590 + EXPR_VAR@16577..16590 + NAME@16577..16590 + IDENT@16577..16590 "target_object" + R_PAREN@16590..16591 ")" + WHITESPACE@16591..16592 " " + ELSE_KW@16592..16596 "else" + WHITESPACE@16596..16597 " " + FALSE_EXPR@16597..16599 + EXPR_ARRAY@16597..16599 + L_BRACK@16597..16598 "[" + R_BRACK@16598..16599 "]" + SEMI@16599..16600 ";" + WHITESPACE@16600..16608 "\n\n " + EXPR_LOCAL@16608..17113 + LOCAL_KW@16608..16613 "local" + WHITESPACE@16613..16614 " " + BIND_DESTRUCT@16614..16684 + DESTRUCT_FULL@16614..16625 + NAME@16614..16625 + IDENT@16614..16625 "null_fields" + WHITESPACE@16625..16626 " " + ASSIGN@16626..16627 "=" + WHITESPACE@16627..16628 " " + EXPR_ARRAY_COMP@16628..16684 + L_BRACK@16628..16629 "[" + EXPR_VAR@16629..16630 + NAME@16629..16630 + IDENT@16629..16630 "k" + WHITESPACE@16630..16631 " " + FOR_SPEC@16631..16663 + FOR_KW@16631..16634 "for" + WHITESPACE@16634..16635 " " + NAME@16635..16636 + IDENT@16635..16636 "k" + WHITESPACE@16636..16637 " " + IN_KW@16637..16639 "in" + WHITESPACE@16639..16640 " " + EXPR_APPLY@16640..16663 + EXPR_INDEX@16640..16656 + EXPR_VAR@16640..16643 + NAME@16640..16643 + IDENT@16640..16643 "std" + DOT@16643..16644 "." + NAME@16644..16656 + IDENT@16644..16656 "objectFields" + ARGS_DESC@16656..16663 + L_PAREN@16656..16657 "(" + ARG@16657..16662 + EXPR_VAR@16657..16662 + NAME@16657..16662 + IDENT@16657..16662 "patch" + R_PAREN@16662..16663 ")" + WHITESPACE@16663..16664 " " + IF_SPEC@16664..16683 + IF_KW@16664..16666 "if" + WHITESPACE@16666..16667 " " + EXPR_BINARY@16667..16683 + LHS_EXPR@16667..16675 + EXPR_INDEX_EXPR@16667..16675 + LHS_EXPR@16667..16672 + EXPR_VAR@16667..16672 + NAME@16667..16672 + IDENT@16667..16672 "patch" + L_BRACK@16672..16673 "[" + EXPR_VAR@16673..16674 + NAME@16673..16674 + IDENT@16673..16674 "k" + R_BRACK@16674..16675 "]" + WHITESPACE@16675..16676 " " + EQ@16676..16678 "==" + WHITESPACE@16678..16679 " " + EXPR_LITERAL@16679..16683 + NULL_KW@16679..16683 "null" + R_BRACK@16683..16684 "]" + SEMI@16684..16685 ";" + WHITESPACE@16685..16692 "\n " + EXPR_LOCAL@16692..17113 + LOCAL_KW@16692..16697 "local" + WHITESPACE@16697..16698 " " + BIND_DESTRUCT@16698..16764 + DESTRUCT_FULL@16698..16709 + NAME@16698..16709 + IDENT@16698..16709 "both_fields" + WHITESPACE@16709..16710 " " + ASSIGN@16710..16711 "=" + WHITESPACE@16711..16712 " " + EXPR_APPLY@16712..16764 + EXPR_INDEX@16712..16724 + EXPR_VAR@16712..16715 + NAME@16712..16715 + IDENT@16712..16715 "std" + DOT@16715..16716 "." + NAME@16716..16724 + IDENT@16716..16724 "setUnion" + ARGS_DESC@16724..16764 + L_PAREN@16724..16725 "(" + ARG@16725..16738 + EXPR_VAR@16725..16738 + NAME@16725..16738 + IDENT@16725..16738 "target_fields" + COMMA@16738..16739 "," + WHITESPACE@16739..16740 " " + ARG@16740..16763 + EXPR_APPLY@16740..16763 + EXPR_INDEX@16740..16756 + EXPR_VAR@16740..16743 + NAME@16740..16743 + IDENT@16740..16743 "std" + DOT@16743..16744 "." + NAME@16744..16756 + IDENT@16744..16756 "objectFields" + ARGS_DESC@16756..16763 + L_PAREN@16756..16757 "(" + ARG@16757..16762 + EXPR_VAR@16757..16762 + NAME@16757..16762 + IDENT@16757..16762 "patch" + R_PAREN@16762..16763 ")" + R_PAREN@16763..16764 ")" + SEMI@16764..16765 ";" + WHITESPACE@16765..16773 "\n\n " + EXPR_OBJECT@16773..17113 + OBJ_BODY_MEMBER_LIST@16773..17113 + L_BRACE@16773..16774 "{" + WHITESPACE@16774..16783 "\n " + MEMBER_FIELD@16783..17105 + FIELD_NORMAL@16783..17050 + FIELD_NAME_DYNAMIC@16783..16786 + L_BRACK@16783..16784 "[" + EXPR_VAR@16784..16785 + NAME@16784..16785 + IDENT@16784..16785 "k" + R_BRACK@16785..16786 "]" + COLON@16786..16787 ":" + WHITESPACE@16787..16798 "\n " + EXPR_IF_THEN_ELSE@16798..17050 + IF_KW@16798..16800 "if" + WHITESPACE@16800..16801 " " + EXPR_UNARY@16801..16825 + NOT@16801..16802 "!" + EXPR_APPLY@16802..16825 + EXPR_INDEX@16802..16815 + EXPR_VAR@16802..16805 + NAME@16802..16805 + IDENT@16802..16805 "std" + DOT@16805..16806 "." + NAME@16806..16815 + IDENT@16806..16815 "objectHas" + ARGS_DESC@16815..16825 + L_PAREN@16815..16816 "(" + ARG@16816..16821 + EXPR_VAR@16816..16821 + NAME@16816..16821 + IDENT@16816..16821 "patch" + COMMA@16821..16822 "," + WHITESPACE@16822..16823 " " + ARG@16823..16824 + EXPR_VAR@16823..16824 + NAME@16823..16824 + IDENT@16823..16824 "k" + R_PAREN@16824..16825 ")" + WHITESPACE@16825..16826 " " + THEN_KW@16826..16830 "then" + WHITESPACE@16830..16843 "\n " + TRUE_EXPR@16843..16859 + EXPR_INDEX_EXPR@16843..16859 + LHS_EXPR@16843..16856 + EXPR_VAR@16843..16856 + NAME@16843..16856 + IDENT@16843..16856 "target_object" + L_BRACK@16856..16857 "[" + EXPR_VAR@16857..16858 + NAME@16857..16858 + IDENT@16857..16858 "k" + R_BRACK@16858..16859 "]" + WHITESPACE@16859..16870 "\n " + ELSE_KW@16870..16874 "else" + WHITESPACE@16874..16875 " " + FALSE_EXPR@16875..17050 + EXPR_IF_THEN_ELSE@16875..17050 + IF_KW@16875..16877 "if" + WHITESPACE@16877..16878 " " + EXPR_UNARY@16878..16910 + NOT@16878..16879 "!" + EXPR_APPLY@16879..16910 + EXPR_INDEX@16879..16892 + EXPR_VAR@16879..16882 + NAME@16879..16882 + IDENT@16879..16882 "std" + DOT@16882..16883 "." + NAME@16883..16892 + IDENT@16883..16892 "objectHas" + ARGS_DESC@16892..16910 + L_PAREN@16892..16893 "(" + ARG@16893..16906 + EXPR_VAR@16893..16906 + NAME@16893..16906 + IDENT@16893..16906 "target_object" + COMMA@16906..16907 "," + WHITESPACE@16907..16908 " " + ARG@16908..16909 + EXPR_VAR@16908..16909 + NAME@16908..16909 + IDENT@16908..16909 "k" + R_PAREN@16909..16910 ")" + WHITESPACE@16910..16911 " " + THEN_KW@16911..16915 "then" + WHITESPACE@16915..16928 "\n " + TRUE_EXPR@16928..16969 + EXPR_APPLY@16928..16969 + EXPR_INDEX@16928..16942 + EXPR_VAR@16928..16931 + NAME@16928..16931 + IDENT@16928..16931 "std" + DOT@16931..16932 "." + NAME@16932..16942 + IDENT@16932..16942 "mergePatch" + ARGS_DESC@16942..16969 + L_PAREN@16942..16943 "(" + ARG@16943..16947 + EXPR_LITERAL@16943..16947 + NULL_KW@16943..16947 "null" + COMMA@16947..16948 "," + WHITESPACE@16948..16949 " " + ARG@16949..16957 + EXPR_INDEX_EXPR@16949..16957 + LHS_EXPR@16949..16954 + EXPR_VAR@16949..16954 + NAME@16949..16954 + IDENT@16949..16954 "patch" + L_BRACK@16954..16955 "[" + EXPR_VAR@16955..16956 + NAME@16955..16956 + IDENT@16955..16956 "k" + R_BRACK@16956..16957 "]" + R_PAREN@16957..16958 ")" + WHITESPACE@16958..16959 " " + TAILSTRICT_KW@16959..16969 "tailstrict" + WHITESPACE@16969..16980 "\n " + ELSE_KW@16980..16984 "else" + WHITESPACE@16984..16997 "\n " + FALSE_EXPR@16997..17050 + EXPR_APPLY@16997..17050 + EXPR_INDEX@16997..17011 + EXPR_VAR@16997..17000 + NAME@16997..17000 + IDENT@16997..17000 "std" + DOT@17000..17001 "." + NAME@17001..17011 + IDENT@17001..17011 "mergePatch" + ARGS_DESC@17011..17050 + L_PAREN@17011..17012 "(" + ARG@17012..17028 + EXPR_INDEX_EXPR@17012..17028 + LHS_EXPR@17012..17025 + EXPR_VAR@17012..17025 + NAME@17012..17025 + IDENT@17012..17025 "target_object" + L_BRACK@17025..17026 "[" + EXPR_VAR@17026..17027 + NAME@17026..17027 + IDENT@17026..17027 "k" + R_BRACK@17027..17028 "]" + COMMA@17028..17029 "," + WHITESPACE@17029..17030 " " + ARG@17030..17038 + EXPR_INDEX_EXPR@17030..17038 + LHS_EXPR@17030..17035 + EXPR_VAR@17030..17035 + NAME@17030..17035 + IDENT@17030..17035 "patch" + L_BRACK@17035..17036 "[" + EXPR_VAR@17036..17037 + NAME@17036..17037 + IDENT@17036..17037 "k" + R_BRACK@17037..17038 "]" + R_PAREN@17038..17039 ")" + WHITESPACE@17039..17040 " " + TAILSTRICT_KW@17040..17050 "tailstrict" + WHITESPACE@17050..17059 "\n " + FOR_SPEC@17059..17105 + FOR_KW@17059..17062 "for" + WHITESPACE@17062..17063 " " + NAME@17063..17064 + IDENT@17063..17064 "k" + WHITESPACE@17064..17065 " " + IN_KW@17065..17067 "in" + WHITESPACE@17067..17068 " " + EXPR_APPLY@17068..17105 + EXPR_INDEX@17068..17079 + EXPR_VAR@17068..17071 + NAME@17068..17071 + IDENT@17068..17071 "std" + DOT@17071..17072 "." + NAME@17072..17079 + IDENT@17072..17079 "setDiff" + ARGS_DESC@17079..17105 + L_PAREN@17079..17080 "(" + ARG@17080..17091 + EXPR_VAR@17080..17091 + NAME@17080..17091 + IDENT@17080..17091 "both_fields" + COMMA@17091..17092 "," + WHITESPACE@17092..17093 " " + ARG@17093..17104 + EXPR_VAR@17093..17104 + NAME@17093..17104 + IDENT@17093..17104 "null_fields" + R_PAREN@17104..17105 ")" + WHITESPACE@17105..17112 "\n " + R_BRACE@17112..17113 "}" + WHITESPACE@17113..17118 "\n " + ELSE_KW@17118..17122 "else" + WHITESPACE@17122..17129 "\n " + FALSE_EXPR@17129..17134 + EXPR_VAR@17129..17134 + NAME@17129..17134 + IDENT@17129..17134 "patch" + COMMA@17134..17135 "," + WHITESPACE@17135..17139 "\n\n " + MEMBER_FIELD@17139..17249 + FIELD_METHOD@17139..17249 + FIELD_NAME_FIXED@17139..17142 + NAME@17139..17142 + IDENT@17139..17142 "get" + PARAMS_DESC@17142..17183 + L_PAREN@17142..17143 "(" + PARAM@17143..17144 + DESTRUCT_FULL@17143..17144 + NAME@17143..17144 + IDENT@17143..17144 "o" + COMMA@17144..17145 "," + WHITESPACE@17145..17146 " " + PARAM@17146..17147 + DESTRUCT_FULL@17146..17147 + NAME@17146..17147 + IDENT@17146..17147 "f" + COMMA@17147..17148 "," + WHITESPACE@17148..17149 " " + PARAM@17149..17163 + DESTRUCT_FULL@17149..17156 + NAME@17149..17156 + IDENT@17149..17156 "default" + WHITESPACE@17156..17157 " " + ASSIGN@17157..17158 "=" + WHITESPACE@17158..17159 " " + EXPR_LITERAL@17159..17163 + NULL_KW@17159..17163 "null" + COMMA@17163..17164 "," + WHITESPACE@17164..17165 " " + PARAM@17165..17182 + DESTRUCT_FULL@17165..17175 + NAME@17165..17175 + IDENT@17165..17175 "inc_hidden" + WHITESPACE@17175..17176 " " + ASSIGN@17176..17177 "=" + WHITESPACE@17177..17178 " " + EXPR_LITERAL@17178..17182 + TRUE_KW@17178..17182 "true" + R_PAREN@17182..17183 ")" + COLONCOLON@17183..17185 "::" + WHITESPACE@17185..17190 "\n " + EXPR_IF_THEN_ELSE@17190..17249 + IF_KW@17190..17192 "if" + WHITESPACE@17192..17193 " " + EXPR_APPLY@17193..17226 + EXPR_INDEX@17193..17208 + EXPR_VAR@17193..17196 + NAME@17193..17196 + IDENT@17193..17196 "std" + DOT@17196..17197 "." + NAME@17197..17208 + IDENT@17197..17208 "objectHasEx" + ARGS_DESC@17208..17226 + L_PAREN@17208..17209 "(" + ARG@17209..17210 + EXPR_VAR@17209..17210 + NAME@17209..17210 + IDENT@17209..17210 "o" + COMMA@17210..17211 "," + WHITESPACE@17211..17212 " " + ARG@17212..17213 + EXPR_VAR@17212..17213 + NAME@17212..17213 + IDENT@17212..17213 "f" + COMMA@17213..17214 "," + WHITESPACE@17214..17215 " " + ARG@17215..17225 + EXPR_VAR@17215..17225 + NAME@17215..17225 + IDENT@17215..17225 "inc_hidden" + R_PAREN@17225..17226 ")" + WHITESPACE@17226..17227 " " + THEN_KW@17227..17231 "then" + WHITESPACE@17231..17232 " " + TRUE_EXPR@17232..17236 + EXPR_INDEX_EXPR@17232..17236 + LHS_EXPR@17232..17233 + EXPR_VAR@17232..17233 + NAME@17232..17233 + IDENT@17232..17233 "o" + L_BRACK@17233..17234 "[" + EXPR_VAR@17234..17235 + NAME@17234..17235 + IDENT@17234..17235 "f" + R_BRACK@17235..17236 "]" + WHITESPACE@17236..17237 " " + ELSE_KW@17237..17241 "else" + WHITESPACE@17241..17242 " " + FALSE_EXPR@17242..17249 + EXPR_VAR@17242..17249 + NAME@17242..17249 + IDENT@17242..17249 "default" + COMMA@17249..17250 "," + WHITESPACE@17250..17254 "\n\n " + MEMBER_FIELD@17254..17304 + FIELD_METHOD@17254..17304 + FIELD_NAME_FIXED@17254..17266 + NAME@17254..17266 + IDENT@17254..17266 "objectFields" + PARAMS_DESC@17266..17269 + L_PAREN@17266..17267 "(" + PARAM@17267..17268 + DESTRUCT_FULL@17267..17268 + NAME@17267..17268 + IDENT@17267..17268 "o" + R_PAREN@17268..17269 ")" + COLONCOLON@17269..17271 "::" + WHITESPACE@17271..17276 "\n " + EXPR_APPLY@17276..17304 + EXPR_INDEX@17276..17294 + EXPR_VAR@17276..17279 + NAME@17276..17279 + IDENT@17276..17279 "std" + DOT@17279..17280 "." + NAME@17280..17294 + IDENT@17280..17294 "objectFieldsEx" + ARGS_DESC@17294..17304 + L_PAREN@17294..17295 "(" + ARG@17295..17296 + EXPR_VAR@17295..17296 + NAME@17295..17296 + IDENT@17295..17296 "o" + COMMA@17296..17297 "," + WHITESPACE@17297..17298 " " + ARG@17298..17303 + EXPR_LITERAL@17298..17303 + FALSE_KW@17298..17303 "false" + R_PAREN@17303..17304 ")" + COMMA@17304..17305 "," + WHITESPACE@17305..17309 "\n\n " + MEMBER_FIELD@17309..17361 + FIELD_METHOD@17309..17361 + FIELD_NAME_FIXED@17309..17324 + NAME@17309..17324 + IDENT@17309..17324 "objectFieldsAll" + PARAMS_DESC@17324..17327 + L_PAREN@17324..17325 "(" + PARAM@17325..17326 + DESTRUCT_FULL@17325..17326 + NAME@17325..17326 + IDENT@17325..17326 "o" + R_PAREN@17326..17327 ")" + COLONCOLON@17327..17329 "::" + WHITESPACE@17329..17334 "\n " + EXPR_APPLY@17334..17361 + EXPR_INDEX@17334..17352 + EXPR_VAR@17334..17337 + NAME@17334..17337 + IDENT@17334..17337 "std" + DOT@17337..17338 "." + NAME@17338..17352 + IDENT@17338..17352 "objectFieldsEx" + ARGS_DESC@17352..17361 + L_PAREN@17352..17353 "(" + ARG@17353..17354 + EXPR_VAR@17353..17354 + NAME@17353..17354 + IDENT@17353..17354 "o" + COMMA@17354..17355 "," + WHITESPACE@17355..17356 " " + ARG@17356..17360 + EXPR_LITERAL@17356..17360 + TRUE_KW@17356..17360 "true" + R_PAREN@17360..17361 ")" + COMMA@17361..17362 "," + WHITESPACE@17362..17366 "\n\n " + MEMBER_FIELD@17366..17416 + FIELD_METHOD@17366..17416 + FIELD_NAME_FIXED@17366..17375 + NAME@17366..17375 + IDENT@17366..17375 "objectHas" + PARAMS_DESC@17375..17381 + L_PAREN@17375..17376 "(" + PARAM@17376..17377 + DESTRUCT_FULL@17376..17377 + NAME@17376..17377 + IDENT@17376..17377 "o" + COMMA@17377..17378 "," + WHITESPACE@17378..17379 " " + PARAM@17379..17380 + DESTRUCT_FULL@17379..17380 + NAME@17379..17380 + IDENT@17379..17380 "f" + R_PAREN@17380..17381 ")" + COLONCOLON@17381..17383 "::" + WHITESPACE@17383..17388 "\n " + EXPR_APPLY@17388..17416 + EXPR_INDEX@17388..17403 + EXPR_VAR@17388..17391 + NAME@17388..17391 + IDENT@17388..17391 "std" + DOT@17391..17392 "." + NAME@17392..17403 + IDENT@17392..17403 "objectHasEx" + ARGS_DESC@17403..17416 + L_PAREN@17403..17404 "(" + ARG@17404..17405 + EXPR_VAR@17404..17405 + NAME@17404..17405 + IDENT@17404..17405 "o" + COMMA@17405..17406 "," + WHITESPACE@17406..17407 " " + ARG@17407..17408 + EXPR_VAR@17407..17408 + NAME@17407..17408 + IDENT@17407..17408 "f" + COMMA@17408..17409 "," + WHITESPACE@17409..17410 " " + ARG@17410..17415 + EXPR_LITERAL@17410..17415 + FALSE_KW@17410..17415 "false" + R_PAREN@17415..17416 ")" + COMMA@17416..17417 "," + WHITESPACE@17417..17421 "\n\n " + MEMBER_FIELD@17421..17473 + FIELD_METHOD@17421..17473 + FIELD_NAME_FIXED@17421..17433 + NAME@17421..17433 + IDENT@17421..17433 "objectHasAll" + PARAMS_DESC@17433..17439 + L_PAREN@17433..17434 "(" + PARAM@17434..17435 + DESTRUCT_FULL@17434..17435 + NAME@17434..17435 + IDENT@17434..17435 "o" + COMMA@17435..17436 "," + WHITESPACE@17436..17437 " " + PARAM@17437..17438 + DESTRUCT_FULL@17437..17438 + NAME@17437..17438 + IDENT@17437..17438 "f" + R_PAREN@17438..17439 ")" + COLONCOLON@17439..17441 "::" + WHITESPACE@17441..17446 "\n " + EXPR_APPLY@17446..17473 + EXPR_INDEX@17446..17461 + EXPR_VAR@17446..17449 + NAME@17446..17449 + IDENT@17446..17449 "std" + DOT@17449..17450 "." + NAME@17450..17461 + IDENT@17450..17461 "objectHasEx" + ARGS_DESC@17461..17473 + L_PAREN@17461..17462 "(" + ARG@17462..17463 + EXPR_VAR@17462..17463 + NAME@17462..17463 + IDENT@17462..17463 "o" + COMMA@17463..17464 "," + WHITESPACE@17464..17465 " " + ARG@17465..17466 + EXPR_VAR@17465..17466 + NAME@17465..17466 + IDENT@17465..17466 "f" + COMMA@17466..17467 "," + WHITESPACE@17467..17468 " " + ARG@17468..17472 + EXPR_LITERAL@17468..17472 + TRUE_KW@17468..17472 "true" + R_PAREN@17472..17473 ")" + COMMA@17473..17474 "," + WHITESPACE@17474..17478 "\n\n " + MEMBER_FIELD@17478..17535 + FIELD_METHOD@17478..17535 + FIELD_NAME_FIXED@17478..17490 + NAME@17478..17490 + IDENT@17478..17490 "objectValues" + PARAMS_DESC@17490..17493 + L_PAREN@17490..17491 "(" + PARAM@17491..17492 + DESTRUCT_FULL@17491..17492 + NAME@17491..17492 + IDENT@17491..17492 "o" + R_PAREN@17492..17493 ")" + COLONCOLON@17493..17495 "::" + WHITESPACE@17495..17500 "\n " + EXPR_ARRAY_COMP@17500..17535 + L_BRACK@17500..17501 "[" + EXPR_INDEX_EXPR@17501..17505 + LHS_EXPR@17501..17502 + EXPR_VAR@17501..17502 + NAME@17501..17502 + IDENT@17501..17502 "o" + L_BRACK@17502..17503 "[" + EXPR_VAR@17503..17504 + NAME@17503..17504 + IDENT@17503..17504 "k" + R_BRACK@17504..17505 "]" + WHITESPACE@17505..17506 " " + FOR_SPEC@17506..17534 + FOR_KW@17506..17509 "for" + WHITESPACE@17509..17510 " " + NAME@17510..17511 + IDENT@17510..17511 "k" + WHITESPACE@17511..17512 " " + IN_KW@17512..17514 "in" + WHITESPACE@17514..17515 " " + EXPR_APPLY@17515..17534 + EXPR_INDEX@17515..17531 + EXPR_VAR@17515..17518 + NAME@17515..17518 + IDENT@17515..17518 "std" + DOT@17518..17519 "." + NAME@17519..17531 + IDENT@17519..17531 "objectFields" + ARGS_DESC@17531..17534 + L_PAREN@17531..17532 "(" + ARG@17532..17533 + EXPR_VAR@17532..17533 + NAME@17532..17533 + IDENT@17532..17533 "o" + R_PAREN@17533..17534 ")" + R_BRACK@17534..17535 "]" + COMMA@17535..17536 "," + WHITESPACE@17536..17540 "\n\n " + MEMBER_FIELD@17540..17603 + FIELD_METHOD@17540..17603 + FIELD_NAME_FIXED@17540..17555 + NAME@17540..17555 + IDENT@17540..17555 "objectValuesAll" + PARAMS_DESC@17555..17558 + L_PAREN@17555..17556 "(" + PARAM@17556..17557 + DESTRUCT_FULL@17556..17557 + NAME@17556..17557 + IDENT@17556..17557 "o" + R_PAREN@17557..17558 ")" + COLONCOLON@17558..17560 "::" + WHITESPACE@17560..17565 "\n " + EXPR_ARRAY_COMP@17565..17603 + L_BRACK@17565..17566 "[" + EXPR_INDEX_EXPR@17566..17570 + LHS_EXPR@17566..17567 + EXPR_VAR@17566..17567 + NAME@17566..17567 + IDENT@17566..17567 "o" + L_BRACK@17567..17568 "[" + EXPR_VAR@17568..17569 + NAME@17568..17569 + IDENT@17568..17569 "k" + R_BRACK@17569..17570 "]" + WHITESPACE@17570..17571 " " + FOR_SPEC@17571..17602 + FOR_KW@17571..17574 "for" + WHITESPACE@17574..17575 " " + NAME@17575..17576 + IDENT@17575..17576 "k" + WHITESPACE@17576..17577 " " + IN_KW@17577..17579 "in" + WHITESPACE@17579..17580 " " + EXPR_APPLY@17580..17602 + EXPR_INDEX@17580..17599 + EXPR_VAR@17580..17583 + NAME@17580..17583 + IDENT@17580..17583 "std" + DOT@17583..17584 "." + NAME@17584..17599 + IDENT@17584..17599 "objectFieldsAll" + ARGS_DESC@17599..17602 + L_PAREN@17599..17600 "(" + ARG@17600..17601 + EXPR_VAR@17600..17601 + NAME@17600..17601 + IDENT@17600..17601 "o" + R_PAREN@17601..17602 ")" + R_BRACK@17602..17603 "]" + COMMA@17603..17604 "," + WHITESPACE@17604..17608 "\n\n " + MEMBER_FIELD@17608..17635 + FIELD_NORMAL@17608..17635 + FIELD_NAME_FIXED@17608..17614 + NAME@17608..17614 + IDENT@17608..17614 "equals" + COLONCOLON@17614..17616 "::" + WHITESPACE@17616..17617 " " + EXPR_INTRINSIC@17617..17635 + INTRINSIC@17617..17627 "$intrinsic" + L_PAREN@17627..17628 "(" + NAME@17628..17634 + IDENT@17628..17634 "equals" + R_PAREN@17634..17635 ")" + COMMA@17635..17636 "," + WHITESPACE@17636..17640 "\n\n " + MEMBER_FIELD@17640..17774 + FIELD_METHOD@17640..17774 + FIELD_NAME_FIXED@17640..17651 + NAME@17640..17651 + IDENT@17640..17651 "resolvePath" + PARAMS_DESC@17651..17657 + L_PAREN@17651..17652 "(" + PARAM@17652..17653 + DESTRUCT_FULL@17652..17653 + NAME@17652..17653 + IDENT@17652..17653 "f" + COMMA@17653..17654 "," + WHITESPACE@17654..17655 " " + PARAM@17655..17656 + DESTRUCT_FULL@17655..17656 + NAME@17655..17656 + IDENT@17655..17656 "r" + R_PAREN@17656..17657 ")" + COLONCOLON@17657..17659 "::" + WHITESPACE@17659..17664 "\n " + EXPR_LOCAL@17664..17774 + LOCAL_KW@17664..17669 "local" + WHITESPACE@17669..17670 " " + BIND_DESTRUCT@17670..17693 + DESTRUCT_FULL@17670..17673 + NAME@17670..17673 + IDENT@17670..17673 "arr" + WHITESPACE@17673..17674 " " + ASSIGN@17674..17675 "=" + WHITESPACE@17675..17676 " " + EXPR_APPLY@17676..17693 + EXPR_INDEX@17676..17685 + EXPR_VAR@17676..17679 + NAME@17676..17679 + IDENT@17676..17679 "std" + DOT@17679..17680 "." + NAME@17680..17685 + IDENT@17680..17685 "split" + ARGS_DESC@17685..17693 + L_PAREN@17685..17686 "(" + ARG@17686..17687 + EXPR_VAR@17686..17687 + NAME@17686..17687 + IDENT@17686..17687 "f" + COMMA@17687..17688 "," + WHITESPACE@17688..17689 " " + ARG@17689..17692 + EXPR_STRING@17689..17692 + STRING_SINGLE@17689..17692 "'/'" + R_PAREN@17692..17693 ")" + SEMI@17693..17694 ";" + WHITESPACE@17694..17699 "\n " + EXPR_APPLY@17699..17774 + EXPR_INDEX@17699..17707 + EXPR_VAR@17699..17702 + NAME@17699..17702 + IDENT@17699..17702 "std" + DOT@17702..17703 "." + NAME@17703..17707 + IDENT@17703..17707 "join" + ARGS_DESC@17707..17774 + L_PAREN@17707..17708 "(" + ARG@17708..17711 + EXPR_STRING@17708..17711 + STRING_SINGLE@17708..17711 "'/'" + COMMA@17711..17712 "," + WHITESPACE@17712..17713 " " + ARG@17713..17773 + EXPR_BINARY@17713..17773 + LHS_EXPR@17713..17767 + EXPR_APPLY@17713..17767 + EXPR_INDEX@17713..17726 + EXPR_VAR@17713..17716 + NAME@17713..17716 + IDENT@17713..17716 "std" + DOT@17716..17717 "." + NAME@17717..17726 + IDENT@17717..17726 "makeArray" + ARGS_DESC@17726..17767 + L_PAREN@17726..17727 "(" + ARG@17727..17746 + EXPR_BINARY@17727..17746 + LHS_EXPR@17727..17742 + EXPR_APPLY@17727..17742 + EXPR_INDEX@17727..17737 + EXPR_VAR@17727..17730 + NAME@17727..17730 + IDENT@17727..17730 "std" + DOT@17730..17731 "." + NAME@17731..17737 + IDENT@17731..17737 "length" + ARGS_DESC@17737..17742 + L_PAREN@17737..17738 "(" + ARG@17738..17741 + EXPR_VAR@17738..17741 + NAME@17738..17741 + IDENT@17738..17741 "arr" + R_PAREN@17741..17742 ")" + WHITESPACE@17742..17743 " " + MINUS@17743..17744 "-" + WHITESPACE@17744..17745 " " + EXPR_NUMBER@17745..17746 + FLOAT@17745..17746 "1" + COMMA@17746..17747 "," + WHITESPACE@17747..17748 " " + ARG@17748..17766 + EXPR_FUNCTION@17748..17766 + FUNCTION_KW@17748..17756 "function" + PARAMS_DESC@17756..17759 + L_PAREN@17756..17757 "(" + PARAM@17757..17758 + DESTRUCT_FULL@17757..17758 + NAME@17757..17758 + IDENT@17757..17758 "i" + R_PAREN@17758..17759 ")" + WHITESPACE@17759..17760 " " + EXPR_INDEX_EXPR@17760..17766 + LHS_EXPR@17760..17763 + EXPR_VAR@17760..17763 + NAME@17760..17763 + IDENT@17760..17763 "arr" + L_BRACK@17763..17764 "[" + EXPR_VAR@17764..17765 + NAME@17764..17765 + IDENT@17764..17765 "i" + R_BRACK@17765..17766 "]" + R_PAREN@17766..17767 ")" + WHITESPACE@17767..17768 " " + PLUS@17768..17769 "+" + WHITESPACE@17769..17770 " " + EXPR_ARRAY@17770..17773 + L_BRACK@17770..17771 "[" + EXPR_VAR@17771..17772 + NAME@17771..17772 + IDENT@17771..17772 "r" + R_BRACK@17772..17773 "]" + R_PAREN@17773..17774 ")" + COMMA@17774..17775 "," + WHITESPACE@17775..17779 "\n\n " + MEMBER_FIELD@17779..18232 + FIELD_METHOD@17779..18232 + FIELD_NAME_FIXED@17779..17784 + NAME@17779..17784 + IDENT@17779..17784 "prune" + PARAMS_DESC@17784..17787 + L_PAREN@17784..17785 "(" + PARAM@17785..17786 + DESTRUCT_FULL@17785..17786 + NAME@17785..17786 + IDENT@17785..17786 "a" + R_PAREN@17786..17787 ")" + COLONCOLON@17787..17789 "::" + WHITESPACE@17789..17794 "\n " + EXPR_LOCAL@17794..18232 + LOCAL_KW@17794..17799 "local" + WHITESPACE@17799..17800 " " + BIND_FUNCTION@17800..17997 + NAME@17800..17809 + IDENT@17800..17809 "isContent" + PARAMS_DESC@17809..17812 + L_PAREN@17809..17810 "(" + PARAM@17810..17811 + DESTRUCT_FULL@17810..17811 + NAME@17810..17811 + IDENT@17810..17811 "b" + R_PAREN@17811..17812 ")" + WHITESPACE@17812..17813 " " + ASSIGN@17813..17814 "=" + WHITESPACE@17814..17821 "\n " + EXPR_IF_THEN_ELSE@17821..17997 + IF_KW@17821..17823 "if" + WHITESPACE@17823..17824 " " + EXPR_BINARY@17824..17833 + LHS_EXPR@17824..17825 + EXPR_VAR@17824..17825 + NAME@17824..17825 + IDENT@17824..17825 "b" + WHITESPACE@17825..17826 " " + EQ@17826..17828 "==" + WHITESPACE@17828..17829 " " + EXPR_LITERAL@17829..17833 + NULL_KW@17829..17833 "null" + WHITESPACE@17833..17834 " " + THEN_KW@17834..17838 "then" + WHITESPACE@17838..17847 "\n " + TRUE_EXPR@17847..17852 + EXPR_LITERAL@17847..17852 + FALSE_KW@17847..17852 "false" + WHITESPACE@17852..17859 "\n " + ELSE_KW@17859..17863 "else" + WHITESPACE@17863..17864 " " + FALSE_EXPR@17864..17997 + EXPR_IF_THEN_ELSE@17864..17997 + IF_KW@17864..17866 "if" + WHITESPACE@17866..17867 " " + EXPR_APPLY@17867..17881 + EXPR_INDEX@17867..17878 + EXPR_VAR@17867..17870 + NAME@17867..17870 + IDENT@17867..17870 "std" + DOT@17870..17871 "." + NAME@17871..17878 + IDENT@17871..17878 "isArray" + ARGS_DESC@17878..17881 + L_PAREN@17878..17879 "(" + ARG@17879..17880 + EXPR_VAR@17879..17880 + NAME@17879..17880 + IDENT@17879..17880 "b" + R_PAREN@17880..17881 ")" + WHITESPACE@17881..17882 " " + THEN_KW@17882..17886 "then" + WHITESPACE@17886..17895 "\n " + TRUE_EXPR@17895..17912 + EXPR_BINARY@17895..17912 + LHS_EXPR@17895..17908 + EXPR_APPLY@17895..17908 + EXPR_INDEX@17895..17905 + EXPR_VAR@17895..17898 + NAME@17895..17898 + IDENT@17895..17898 "std" + DOT@17898..17899 "." + NAME@17899..17905 + IDENT@17899..17905 "length" + ARGS_DESC@17905..17908 + L_PAREN@17905..17906 "(" + ARG@17906..17907 + EXPR_VAR@17906..17907 + NAME@17906..17907 + IDENT@17906..17907 "b" + R_PAREN@17907..17908 ")" + WHITESPACE@17908..17909 " " + GT@17909..17910 ">" + WHITESPACE@17910..17911 " " + EXPR_NUMBER@17911..17912 + FLOAT@17911..17912 "0" + WHITESPACE@17912..17919 "\n " + ELSE_KW@17919..17923 "else" + WHITESPACE@17923..17924 " " + FALSE_EXPR@17924..17997 + EXPR_IF_THEN_ELSE@17924..17997 + IF_KW@17924..17926 "if" + WHITESPACE@17926..17927 " " + EXPR_APPLY@17927..17942 + EXPR_INDEX@17927..17939 + EXPR_VAR@17927..17930 + NAME@17927..17930 + IDENT@17927..17930 "std" + DOT@17930..17931 "." + NAME@17931..17939 + IDENT@17931..17939 "isObject" + ARGS_DESC@17939..17942 + L_PAREN@17939..17940 "(" + ARG@17940..17941 + EXPR_VAR@17940..17941 + NAME@17940..17941 + IDENT@17940..17941 "b" + R_PAREN@17941..17942 ")" + WHITESPACE@17942..17943 " " + THEN_KW@17943..17947 "then" + WHITESPACE@17947..17956 "\n " + TRUE_EXPR@17956..17973 + EXPR_BINARY@17956..17973 + LHS_EXPR@17956..17969 + EXPR_APPLY@17956..17969 + EXPR_INDEX@17956..17966 + EXPR_VAR@17956..17959 + NAME@17956..17959 + IDENT@17956..17959 "std" + DOT@17959..17960 "." + NAME@17960..17966 + IDENT@17960..17966 "length" + ARGS_DESC@17966..17969 + L_PAREN@17966..17967 "(" + ARG@17967..17968 + EXPR_VAR@17967..17968 + NAME@17967..17968 + IDENT@17967..17968 "b" + R_PAREN@17968..17969 ")" + WHITESPACE@17969..17970 " " + GT@17970..17971 ">" + WHITESPACE@17971..17972 " " + EXPR_NUMBER@17972..17973 + FLOAT@17972..17973 "0" + WHITESPACE@17973..17980 "\n " + ELSE_KW@17980..17984 "else" + WHITESPACE@17984..17993 "\n " + FALSE_EXPR@17993..17997 + EXPR_LITERAL@17993..17997 + TRUE_KW@17993..17997 "true" + SEMI@17997..17998 ";" + WHITESPACE@17998..18003 "\n " + EXPR_IF_THEN_ELSE@18003..18232 + IF_KW@18003..18005 "if" + WHITESPACE@18005..18006 " " + EXPR_APPLY@18006..18020 + EXPR_INDEX@18006..18017 + EXPR_VAR@18006..18009 + NAME@18006..18009 + IDENT@18006..18009 "std" + DOT@18009..18010 "." + NAME@18010..18017 + IDENT@18010..18017 "isArray" + ARGS_DESC@18017..18020 + L_PAREN@18017..18018 "(" + ARG@18018..18019 + EXPR_VAR@18018..18019 + NAME@18018..18019 + IDENT@18018..18019 "a" + R_PAREN@18019..18020 ")" + WHITESPACE@18020..18021 " " + THEN_KW@18021..18025 "then" + WHITESPACE@18025..18032 "\n " + TRUE_EXPR@18032..18082 + EXPR_ARRAY_COMP@18032..18082 + L_BRACK@18032..18033 "[" + EXPR_APPLY@18033..18045 + EXPR_INDEX@18033..18042 + EXPR_VAR@18033..18036 + NAME@18033..18036 + IDENT@18033..18036 "std" + DOT@18036..18037 "." + NAME@18037..18042 + IDENT@18037..18042 "prune" + ARGS_DESC@18042..18045 + L_PAREN@18042..18043 "(" + ARG@18043..18044 + EXPR_VAR@18043..18044 + NAME@18043..18044 + IDENT@18043..18044 "x" + R_PAREN@18044..18045 ")" + WHITESPACE@18045..18046 " " + FOR_SPEC@18046..18056 + FOR_KW@18046..18049 "for" + WHITESPACE@18049..18050 " " + NAME@18050..18051 + IDENT@18050..18051 "x" + WHITESPACE@18051..18052 " " + IN_KW@18052..18054 "in" + WHITESPACE@18054..18055 " " + EXPR_VAR@18055..18056 + NAME@18055..18056 + IDENT@18055..18056 "a" + WHITESPACE@18056..18057 " " + IF_SPEC@18057..18081 + IF_KW@18057..18059 "if" + WHITESPACE@18059..18060 " " + EXPR_APPLY@18060..18081 + EXPR_VAR@18060..18069 + NAME@18060..18069 + IDENT@18060..18069 "isContent" + ARGS_DESC@18069..18081 + L_PAREN@18069..18070 "(" + ARG@18070..18080 + EXPR_APPLY@18070..18080 + EXPR_INDEX@18070..18077 + EXPR_LITERAL@18070..18071 + DOLLAR@18070..18071 "$" + DOT@18071..18072 "." + NAME@18072..18077 + IDENT@18072..18077 "prune" + ARGS_DESC@18077..18080 + L_PAREN@18077..18078 "(" + ARG@18078..18079 + EXPR_VAR@18078..18079 + NAME@18078..18079 + IDENT@18078..18079 "x" + R_PAREN@18079..18080 ")" + R_PAREN@18080..18081 ")" + R_BRACK@18081..18082 "]" + WHITESPACE@18082..18087 "\n " + ELSE_KW@18087..18091 "else" + WHITESPACE@18091..18092 " " + FALSE_EXPR@18092..18232 + EXPR_IF_THEN_ELSE@18092..18232 + IF_KW@18092..18094 "if" + WHITESPACE@18094..18095 " " + EXPR_APPLY@18095..18110 + EXPR_INDEX@18095..18107 + EXPR_VAR@18095..18098 + NAME@18095..18098 + IDENT@18095..18098 "std" + DOT@18098..18099 "." + NAME@18099..18107 + IDENT@18099..18107 "isObject" + ARGS_DESC@18107..18110 + L_PAREN@18107..18108 "(" + ARG@18108..18109 + EXPR_VAR@18108..18109 + NAME@18108..18109 + IDENT@18108..18109 "a" + R_PAREN@18109..18110 ")" + WHITESPACE@18110..18111 " " + THEN_KW@18111..18115 "then" + WHITESPACE@18115..18116 " " + TRUE_EXPR@18116..18219 + EXPR_OBJECT@18116..18219 + OBJ_BODY_MEMBER_LIST@18116..18219 + L_BRACE@18116..18117 "{" + WHITESPACE@18117..18124 "\n " + MEMBER_FIELD@18124..18213 + FIELD_NORMAL@18124..18142 + FIELD_NAME_DYNAMIC@18124..18127 + L_BRACK@18124..18125 "[" + EXPR_VAR@18125..18126 + NAME@18125..18126 + IDENT@18125..18126 "x" + R_BRACK@18126..18127 "]" + COLON@18127..18128 ":" + WHITESPACE@18128..18129 " " + EXPR_APPLY@18129..18142 + EXPR_INDEX@18129..18136 + EXPR_LITERAL@18129..18130 + DOLLAR@18129..18130 "$" + DOT@18130..18131 "." + NAME@18131..18136 + IDENT@18131..18136 "prune" + ARGS_DESC@18136..18142 + L_PAREN@18136..18137 "(" + ARG@18137..18141 + EXPR_INDEX_EXPR@18137..18141 + LHS_EXPR@18137..18138 + EXPR_VAR@18137..18138 + NAME@18137..18138 + IDENT@18137..18138 "a" + L_BRACK@18138..18139 "[" + EXPR_VAR@18139..18140 + NAME@18139..18140 + IDENT@18139..18140 "x" + R_BRACK@18140..18141 "]" + R_PAREN@18141..18142 ")" + WHITESPACE@18142..18149 "\n " + FOR_SPEC@18149..18177 + FOR_KW@18149..18152 "for" + WHITESPACE@18152..18153 " " + NAME@18153..18154 + IDENT@18153..18154 "x" + WHITESPACE@18154..18155 " " + IN_KW@18155..18157 "in" + WHITESPACE@18157..18158 " " + EXPR_APPLY@18158..18177 + EXPR_INDEX@18158..18174 + EXPR_VAR@18158..18161 + NAME@18158..18161 + IDENT@18158..18161 "std" + DOT@18161..18162 "." + NAME@18162..18174 + IDENT@18162..18174 "objectFields" + ARGS_DESC@18174..18177 + L_PAREN@18174..18175 "(" + ARG@18175..18176 + EXPR_VAR@18175..18176 + NAME@18175..18176 + IDENT@18175..18176 "a" + R_PAREN@18176..18177 ")" + WHITESPACE@18177..18184 "\n " + IF_SPEC@18184..18213 + IF_KW@18184..18186 "if" + WHITESPACE@18186..18187 " " + EXPR_APPLY@18187..18213 + EXPR_VAR@18187..18196 + NAME@18187..18196 + IDENT@18187..18196 "isContent" + ARGS_DESC@18196..18213 + L_PAREN@18196..18197 "(" + ARG@18197..18212 + EXPR_APPLY@18197..18212 + EXPR_INDEX@18197..18206 + EXPR_VAR@18197..18200 + NAME@18197..18200 + IDENT@18197..18200 "std" + DOT@18200..18201 "." + NAME@18201..18206 + IDENT@18201..18206 "prune" + ARGS_DESC@18206..18212 + L_PAREN@18206..18207 "(" + ARG@18207..18211 + EXPR_INDEX_EXPR@18207..18211 + LHS_EXPR@18207..18208 + EXPR_VAR@18207..18208 + NAME@18207..18208 + IDENT@18207..18208 "a" + L_BRACK@18208..18209 "[" + EXPR_VAR@18209..18210 + NAME@18209..18210 + IDENT@18209..18210 "x" + R_BRACK@18210..18211 "]" + R_PAREN@18211..18212 ")" + R_PAREN@18212..18213 ")" + WHITESPACE@18213..18218 "\n " + R_BRACE@18218..18219 "}" + WHITESPACE@18219..18220 " " + ELSE_KW@18220..18224 "else" + WHITESPACE@18224..18231 "\n " + FALSE_EXPR@18231..18232 + EXPR_VAR@18231..18232 + NAME@18231..18232 + IDENT@18231..18232 "a" + COMMA@18232..18233 "," + WHITESPACE@18233..18237 "\n\n " + MEMBER_FIELD@18237..18755 + FIELD_METHOD@18237..18755 + FIELD_NAME_FIXED@18237..18247 + NAME@18237..18247 + IDENT@18237..18247 "findSubstr" + PARAMS_DESC@18247..18257 + L_PAREN@18247..18248 "(" + PARAM@18248..18251 + DESTRUCT_FULL@18248..18251 + NAME@18248..18251 + IDENT@18248..18251 "pat" + COMMA@18251..18252 "," + WHITESPACE@18252..18253 " " + PARAM@18253..18256 + DESTRUCT_FULL@18253..18256 + NAME@18253..18256 + IDENT@18253..18256 "str" + R_PAREN@18256..18257 ")" + COLONCOLON@18257..18259 "::" + WHITESPACE@18259..18264 "\n " + EXPR_IF_THEN_ELSE@18264..18755 + IF_KW@18264..18266 "if" + WHITESPACE@18266..18267 " " + EXPR_UNARY@18267..18285 + NOT@18267..18268 "!" + EXPR_APPLY@18268..18285 + EXPR_INDEX@18268..18280 + EXPR_VAR@18268..18271 + NAME@18268..18271 + IDENT@18268..18271 "std" + DOT@18271..18272 "." + NAME@18272..18280 + IDENT@18272..18280 "isString" + ARGS_DESC@18280..18285 + L_PAREN@18280..18281 "(" + ARG@18281..18284 + EXPR_VAR@18281..18284 + NAME@18281..18284 + IDENT@18281..18284 "pat" + R_PAREN@18284..18285 ")" + WHITESPACE@18285..18286 " " + THEN_KW@18286..18290 "then" + WHITESPACE@18290..18297 "\n " + TRUE_EXPR@18297..18372 + EXPR_ERROR@18297..18372 + ERROR_KW@18297..18302 "error" + WHITESPACE@18302..18303 " " + EXPR_BINARY@18303..18372 + LHS_EXPR@18303..18356 + EXPR_STRING@18303..18356 + STRING_SINGLE@18303..18356 "'findSubstr first par ..." + WHITESPACE@18356..18357 " " + PLUS@18357..18358 "+" + WHITESPACE@18358..18359 " " + EXPR_APPLY@18359..18372 + EXPR_INDEX@18359..18367 + EXPR_VAR@18359..18362 + NAME@18359..18362 + IDENT@18359..18362 "std" + DOT@18362..18363 "." + NAME@18363..18367 + IDENT@18363..18367 "type" + ARGS_DESC@18367..18372 + L_PAREN@18367..18368 "(" + ARG@18368..18371 + EXPR_VAR@18368..18371 + NAME@18368..18371 + IDENT@18368..18371 "pat" + R_PAREN@18371..18372 ")" + WHITESPACE@18372..18377 "\n " + ELSE_KW@18377..18381 "else" + WHITESPACE@18381..18382 " " + FALSE_EXPR@18382..18755 + EXPR_IF_THEN_ELSE@18382..18755 + IF_KW@18382..18384 "if" + WHITESPACE@18384..18385 " " + EXPR_UNARY@18385..18403 + NOT@18385..18386 "!" + EXPR_APPLY@18386..18403 + EXPR_INDEX@18386..18398 + EXPR_VAR@18386..18389 + NAME@18386..18389 + IDENT@18386..18389 "std" + DOT@18389..18390 "." + NAME@18390..18398 + IDENT@18390..18398 "isString" + ARGS_DESC@18398..18403 + L_PAREN@18398..18399 "(" + ARG@18399..18402 + EXPR_VAR@18399..18402 + NAME@18399..18402 + IDENT@18399..18402 "str" + R_PAREN@18402..18403 ")" + WHITESPACE@18403..18404 " " + THEN_KW@18404..18408 "then" + WHITESPACE@18408..18415 "\n " + TRUE_EXPR@18415..18491 + EXPR_ERROR@18415..18491 + ERROR_KW@18415..18420 "error" + WHITESPACE@18420..18421 " " + EXPR_BINARY@18421..18491 + LHS_EXPR@18421..18475 + EXPR_STRING@18421..18475 + STRING_SINGLE@18421..18475 "'findSubstr second pa ..." + WHITESPACE@18475..18476 " " + PLUS@18476..18477 "+" + WHITESPACE@18477..18478 " " + EXPR_APPLY@18478..18491 + EXPR_INDEX@18478..18486 + EXPR_VAR@18478..18481 + NAME@18478..18481 + IDENT@18478..18481 "std" + DOT@18481..18482 "." + NAME@18482..18486 + IDENT@18482..18486 "type" + ARGS_DESC@18486..18491 + L_PAREN@18486..18487 "(" + ARG@18487..18490 + EXPR_VAR@18487..18490 + NAME@18487..18490 + IDENT@18487..18490 "str" + R_PAREN@18490..18491 ")" + WHITESPACE@18491..18496 "\n " + ELSE_KW@18496..18500 "else" + WHITESPACE@18500..18507 "\n " + FALSE_EXPR@18507..18755 + EXPR_LOCAL@18507..18755 + LOCAL_KW@18507..18512 "local" + WHITESPACE@18512..18513 " " + BIND_DESTRUCT@18513..18538 + DESTRUCT_FULL@18513..18520 + NAME@18513..18520 + IDENT@18513..18520 "pat_len" + WHITESPACE@18520..18521 " " + ASSIGN@18521..18522 "=" + WHITESPACE@18522..18523 " " + EXPR_APPLY@18523..18538 + EXPR_INDEX@18523..18533 + EXPR_VAR@18523..18526 + NAME@18523..18526 + IDENT@18523..18526 "std" + DOT@18526..18527 "." + NAME@18527..18533 + IDENT@18527..18533 "length" + ARGS_DESC@18533..18538 + L_PAREN@18533..18534 "(" + ARG@18534..18537 + EXPR_VAR@18534..18537 + NAME@18534..18537 + IDENT@18534..18537 "pat" + R_PAREN@18537..18538 ")" + SEMI@18538..18539 ";" + WHITESPACE@18539..18546 "\n " + EXPR_LOCAL@18546..18755 + LOCAL_KW@18546..18551 "local" + WHITESPACE@18551..18552 " " + BIND_DESTRUCT@18552..18577 + DESTRUCT_FULL@18552..18559 + NAME@18552..18559 + IDENT@18552..18559 "str_len" + WHITESPACE@18559..18560 " " + ASSIGN@18560..18561 "=" + WHITESPACE@18561..18562 " " + EXPR_APPLY@18562..18577 + EXPR_INDEX@18562..18572 + EXPR_VAR@18562..18565 + NAME@18562..18565 + IDENT@18562..18565 "std" + DOT@18565..18566 "." + NAME@18566..18572 + IDENT@18566..18572 "length" + ARGS_DESC@18572..18577 + L_PAREN@18572..18573 "(" + ARG@18573..18576 + EXPR_VAR@18573..18576 + NAME@18573..18576 + IDENT@18573..18576 "str" + R_PAREN@18576..18577 ")" + SEMI@18577..18578 ";" + WHITESPACE@18578..18585 "\n " + EXPR_IF_THEN_ELSE@18585..18755 + IF_KW@18585..18587 "if" + WHITESPACE@18587..18588 " " + EXPR_BINARY@18588..18637 + LHS_EXPR@18588..18616 + EXPR_BINARY@18588..18616 + LHS_EXPR@18588..18600 + EXPR_BINARY@18588..18600 + LHS_EXPR@18588..18595 + EXPR_VAR@18588..18595 + NAME@18588..18595 + IDENT@18588..18595 "pat_len" + WHITESPACE@18595..18596 " " + EQ@18596..18598 "==" + WHITESPACE@18598..18599 " " + EXPR_NUMBER@18599..18600 + FLOAT@18599..18600 "0" + WHITESPACE@18600..18601 " " + OR@18601..18603 "||" + WHITESPACE@18603..18604 " " + EXPR_BINARY@18604..18616 + LHS_EXPR@18604..18611 + EXPR_VAR@18604..18611 + NAME@18604..18611 + IDENT@18604..18611 "str_len" + WHITESPACE@18611..18612 " " + EQ@18612..18614 "==" + WHITESPACE@18614..18615 " " + EXPR_NUMBER@18615..18616 + FLOAT@18615..18616 "0" + WHITESPACE@18616..18617 " " + OR@18617..18619 "||" + WHITESPACE@18619..18620 " " + EXPR_BINARY@18620..18637 + LHS_EXPR@18620..18627 + EXPR_VAR@18620..18627 + NAME@18620..18627 + IDENT@18620..18627 "pat_len" + WHITESPACE@18627..18628 " " + GT@18628..18629 ">" + WHITESPACE@18629..18630 " " + EXPR_VAR@18630..18637 + NAME@18630..18637 + IDENT@18630..18637 "str_len" + WHITESPACE@18637..18638 " " + THEN_KW@18638..18642 "then" + WHITESPACE@18642..18651 "\n " + TRUE_EXPR@18651..18653 + EXPR_ARRAY@18651..18653 + L_BRACK@18651..18652 "[" + R_BRACK@18652..18653 "]" + WHITESPACE@18653..18660 "\n " + ELSE_KW@18660..18664 "else" + WHITESPACE@18664..18673 "\n " + FALSE_EXPR@18673..18755 + EXPR_APPLY@18673..18755 + EXPR_INDEX@18673..18683 + EXPR_VAR@18673..18676 + NAME@18673..18676 + IDENT@18673..18676 "std" + DOT@18676..18677 "." + NAME@18677..18683 + IDENT@18677..18683 "filter" + ARGS_DESC@18683..18755 + L_PAREN@18683..18684 "(" + ARG@18684..18721 + EXPR_FUNCTION@18684..18721 + FUNCTION_KW@18684..18692 "function" + PARAMS_DESC@18692..18695 + L_PAREN@18692..18693 "(" + PARAM@18693..18694 + DESTRUCT_FULL@18693..18694 + NAME@18693..18694 + IDENT@18693..18694 "i" + R_PAREN@18694..18695 ")" + WHITESPACE@18695..18696 " " + EXPR_BINARY@18696..18721 + LHS_EXPR@18696..18714 + EXPR_SLICE@18696..18714 + EXPR_VAR@18696..18699 + NAME@18696..18699 + IDENT@18696..18699 "str" + SLICE_DESC@18699..18714 + L_BRACK@18699..18700 "[" + EXPR_VAR@18700..18701 + NAME@18700..18701 + IDENT@18700..18701 "i" + COLON@18701..18702 ":" + SLICE_DESC_END@18702..18713 + EXPR_BINARY@18702..18713 + LHS_EXPR@18702..18703 + EXPR_VAR@18702..18703 + NAME@18702..18703 + IDENT@18702..18703 "i" + WHITESPACE@18703..18704 " " + PLUS@18704..18705 "+" + WHITESPACE@18705..18706 " " + EXPR_VAR@18706..18713 + NAME@18706..18713 + IDENT@18706..18713 "pat_len" + R_BRACK@18713..18714 "]" + WHITESPACE@18714..18715 " " + EQ@18715..18717 "==" + WHITESPACE@18717..18718 " " + EXPR_VAR@18718..18721 + NAME@18718..18721 + IDENT@18718..18721 "pat" + COMMA@18721..18722 "," + WHITESPACE@18722..18723 " " + ARG@18723..18754 + EXPR_APPLY@18723..18754 + EXPR_INDEX@18723..18732 + EXPR_VAR@18723..18726 + NAME@18723..18726 + IDENT@18723..18726 "std" + DOT@18726..18727 "." + NAME@18727..18732 + IDENT@18727..18732 "range" + ARGS_DESC@18732..18754 + L_PAREN@18732..18733 "(" + ARG@18733..18734 + EXPR_NUMBER@18733..18734 + FLOAT@18733..18734 "0" + COMMA@18734..18735 "," + WHITESPACE@18735..18736 " " + ARG@18736..18753 + EXPR_BINARY@18736..18753 + LHS_EXPR@18736..18743 + EXPR_VAR@18736..18743 + NAME@18736..18743 + IDENT@18736..18743 "str_len" + WHITESPACE@18743..18744 " " + MINUS@18744..18745 "-" + WHITESPACE@18745..18746 " " + EXPR_VAR@18746..18753 + NAME@18746..18753 + IDENT@18746..18753 "pat_len" + R_PAREN@18753..18754 ")" + R_PAREN@18754..18755 ")" + COMMA@18755..18756 "," + WHITESPACE@18756..18760 "\n\n " + MEMBER_FIELD@18760..18975 + FIELD_METHOD@18760..18975 + FIELD_NAME_FIXED@18760..18764 + NAME@18760..18764 + IDENT@18760..18764 "find" + PARAMS_DESC@18764..18776 + L_PAREN@18764..18765 "(" + PARAM@18765..18770 + DESTRUCT_FULL@18765..18770 + NAME@18765..18770 + IDENT@18765..18770 "value" + COMMA@18770..18771 "," + WHITESPACE@18771..18772 " " + PARAM@18772..18775 + DESTRUCT_FULL@18772..18775 + NAME@18772..18775 + IDENT@18772..18775 "arr" + R_PAREN@18775..18776 ")" + COLONCOLON@18776..18778 "::" + WHITESPACE@18778..18783 "\n " + EXPR_IF_THEN_ELSE@18783..18975 + IF_KW@18783..18785 "if" + WHITESPACE@18785..18786 " " + EXPR_UNARY@18786..18803 + NOT@18786..18787 "!" + EXPR_APPLY@18787..18803 + EXPR_INDEX@18787..18798 + EXPR_VAR@18787..18790 + NAME@18787..18790 + IDENT@18787..18790 "std" + DOT@18790..18791 "." + NAME@18791..18798 + IDENT@18791..18798 "isArray" + ARGS_DESC@18798..18803 + L_PAREN@18798..18799 "(" + ARG@18799..18802 + EXPR_VAR@18799..18802 + NAME@18799..18802 + IDENT@18799..18802 "arr" + R_PAREN@18802..18803 ")" + WHITESPACE@18803..18804 " " + THEN_KW@18804..18808 "then" + WHITESPACE@18808..18815 "\n " + TRUE_EXPR@18815..18885 + EXPR_ERROR@18815..18885 + ERROR_KW@18815..18820 "error" + WHITESPACE@18820..18821 " " + EXPR_BINARY@18821..18885 + LHS_EXPR@18821..18869 + EXPR_STRING@18821..18869 + STRING_SINGLE@18821..18869 "'find second paramete ..." + WHITESPACE@18869..18870 " " + PLUS@18870..18871 "+" + WHITESPACE@18871..18872 " " + EXPR_APPLY@18872..18885 + EXPR_INDEX@18872..18880 + EXPR_VAR@18872..18875 + NAME@18872..18875 + IDENT@18872..18875 "std" + DOT@18875..18876 "." + NAME@18876..18880 + IDENT@18876..18880 "type" + ARGS_DESC@18880..18885 + L_PAREN@18880..18881 "(" + ARG@18881..18884 + EXPR_VAR@18881..18884 + NAME@18881..18884 + IDENT@18881..18884 "arr" + R_PAREN@18884..18885 ")" + WHITESPACE@18885..18890 "\n " + ELSE_KW@18890..18894 "else" + WHITESPACE@18894..18901 "\n " + FALSE_EXPR@18901..18975 + EXPR_APPLY@18901..18975 + EXPR_INDEX@18901..18911 + EXPR_VAR@18901..18904 + NAME@18901..18904 + IDENT@18901..18904 "std" + DOT@18904..18905 "." + NAME@18905..18911 + IDENT@18905..18911 "filter" + ARGS_DESC@18911..18975 + L_PAREN@18911..18912 "(" + ARG@18912..18939 + EXPR_FUNCTION@18912..18939 + FUNCTION_KW@18912..18920 "function" + PARAMS_DESC@18920..18923 + L_PAREN@18920..18921 "(" + PARAM@18921..18922 + DESTRUCT_FULL@18921..18922 + NAME@18921..18922 + IDENT@18921..18922 "i" + R_PAREN@18922..18923 ")" + WHITESPACE@18923..18924 " " + EXPR_BINARY@18924..18939 + LHS_EXPR@18924..18930 + EXPR_INDEX_EXPR@18924..18930 + LHS_EXPR@18924..18927 + EXPR_VAR@18924..18927 + NAME@18924..18927 + IDENT@18924..18927 "arr" + L_BRACK@18927..18928 "[" + EXPR_VAR@18928..18929 + NAME@18928..18929 + IDENT@18928..18929 "i" + R_BRACK@18929..18930 "]" + WHITESPACE@18930..18931 " " + EQ@18931..18933 "==" + WHITESPACE@18933..18934 " " + EXPR_VAR@18934..18939 + NAME@18934..18939 + IDENT@18934..18939 "value" + COMMA@18939..18940 "," + WHITESPACE@18940..18941 " " + ARG@18941..18974 + EXPR_APPLY@18941..18974 + EXPR_INDEX@18941..18950 + EXPR_VAR@18941..18944 + NAME@18941..18944 + IDENT@18941..18944 "std" + DOT@18944..18945 "." + NAME@18945..18950 + IDENT@18945..18950 "range" + ARGS_DESC@18950..18974 + L_PAREN@18950..18951 "(" + ARG@18951..18952 + EXPR_NUMBER@18951..18952 + FLOAT@18951..18952 "0" + COMMA@18952..18953 "," + WHITESPACE@18953..18954 " " + ARG@18954..18973 + EXPR_BINARY@18954..18973 + LHS_EXPR@18954..18969 + EXPR_APPLY@18954..18969 + EXPR_INDEX@18954..18964 + EXPR_VAR@18954..18957 + NAME@18954..18957 + IDENT@18954..18957 "std" + DOT@18957..18958 "." + NAME@18958..18964 + IDENT@18958..18964 "length" + ARGS_DESC@18964..18969 + L_PAREN@18964..18965 "(" + ARG@18965..18968 + EXPR_VAR@18965..18968 + NAME@18965..18968 + IDENT@18965..18968 "arr" + R_PAREN@18968..18969 ")" + WHITESPACE@18969..18970 " " + MINUS@18970..18971 "-" + WHITESPACE@18971..18972 " " + EXPR_NUMBER@18972..18973 + FLOAT@18972..18973 "1" + R_PAREN@18973..18974 ")" + R_PAREN@18974..18975 ")" + COMMA@18975..18976 "," + WHITESPACE@18976..18977 "\n" + R_BRACE@18977..18978 "}" + --- /dev/null +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__str_block_missing_indent.snap @@ -0,0 +1,8 @@ +--- +source: crates/jrsonnet-rowan-parser/src/tests.rs +expression: "|||\n" +--- +SOURCE_FILE@0..4 + EXPR_STRING@0..4 + ERROR_STRING_BLOCK_MISSING_INDENT@0..4 "|||\n" + --- /dev/null +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__str_block_missing_indent_text.snap @@ -0,0 +1,8 @@ +--- +source: crates/jrsonnet-rowan-parser/src/tests.rs +expression: "|||\nhello\n" +--- +SOURCE_FILE@0..10 + EXPR_STRING@0..10 + ERROR_STRING_BLOCK_MISSING_INDENT@0..10 "|||\nhello\n" + --- /dev/null +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__str_block_missing_newline.snap @@ -0,0 +1,8 @@ +--- +source: crates/jrsonnet-rowan-parser/src/tests.rs +expression: "|||hello\n" +--- +SOURCE_FILE@0..9 + EXPR_STRING@0..9 + ERROR_STRING_BLOCK_MISSING_NEW_LINE@0..9 "|||hello\n" + --- /dev/null +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__str_block_missing_termination.snap @@ -0,0 +1,8 @@ +--- +source: crates/jrsonnet-rowan-parser/src/tests.rs +expression: "|||\n\thello\n" +--- +SOURCE_FILE@0..11 + EXPR_STRING@0..11 + ERROR_STRING_BLOCK_UNEXPECTED_END@0..11 "|||\n\thello\n" + --- /dev/null +++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__wrong_field_end.snap @@ -0,0 +1,30 @@ +--- +source: crates/jrsonnet-rowan-parser/src/tests.rs +expression: "{\n\ta: 1;\n\tb: 2;\n}\n" +--- +SOURCE_FILE@0..10 + OBJ_BODY@0..7 + L_BRACE@0..1 "{" + WHITESPACE@1..3 "\n\t" + MEMBER@3..7 + IDENT@3..4 "a" + COLON@4..5 ":" + WHITESPACE@5..6 " " + EXPR_NUMBER@6..7 + NUMBER@6..7 "1" + SEMI@7..8 ";" + WHITESPACE@8..10 "\n\t" +=== +Missing { expected: Unnamed(R_BRACE), offset: 7 } +Custom { error: "unexpected input after expression", range: 7..8 } +=== + x syntax error + ,-[1:1] + 1 | { + 2 | a: 1; + : ^ + : |`-- unexpected input after expression + : `-- missing R_BRACE + 3 | b: 2; + `---- + --- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__wrong_field_end.snap.new +++ /dev/null @@ -1,41 +0,0 @@ ---- -source: crates/jrsonnet-rowan-parser/src/lib.rs -assertion_line: 88 -expression: "{\n\ta: 1;\n\tb: 2;\n}\n" - ---- -Root@0..18 - Object@0..7 - SymbolLeftBrace@0..1 "{" - Whitespace@1..3 "\n\t" - Field@3..7 - Ident@3..4 "a" - SymbolColon@4..5 ":" - Whitespace@5..6 " " - Literal@6..7 - Number@6..7 "1" - SymbolSemi@7..8 ";" - Whitespace@8..10 "\n\t" - Ident@10..11 "b" - SymbolColon@11..12 ":" - Whitespace@12..13 " " - Number@13..14 "2" - SymbolSemi@14..15 ";" - Whitespace@15..16 "\n" - SymbolRightBrace@16..17 "}" - Whitespace@17..18 "\n" -=== -Missing { expected: Unnamed(SymbolRightBrace), offset: 7 } -Custom { error: "unexpected input after expression", range: 7..17 } -=== - × syntax error - ╭─[1:1] - 1 │ { - 2 │ ╭─▶ a: 1; - · ││ ▲ - · ││ ╰── missing SymbolRightBrace - 3 │ │ b: 2; - 4 │ ├─▶ } - · ╰──── unexpected input after expression - ╰──── - --- a/crates/jrsonnet-rowan-parser/src/string_block.rs +++ b/crates/jrsonnet-rowan-parser/src/string_block.rs @@ -1,23 +1,23 @@ #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum StringBlockToken { - Valid, - UnexpectedEndOfString, - MissingTextBlockNewLine, - MissingTextBlockTermination, - MissingTextBlockIndent, +pub enum StringBlockError { + UnexpectedEnd, + MissingNewLine, + MissingTermination, + MissingIndent, } use std::ops::Range; -use StringBlockToken::*; +use logos::Lexer; +use StringBlockError::*; use crate::SyntaxKind; -pub fn lex_str_block_test<'a>(lex: &mut logos::Lexer<'a, SyntaxKind>) { - lex_str_block(lex); +pub fn lex_str_block_test(lex: &mut Lexer) { + let _ = lex_str_block(lex); } -fn lex_str_block<'a>(lex: &mut logos::Lexer<'a, SyntaxKind>) -> StringBlockToken { +pub fn lex_str_block(lex: &mut Lexer) -> Result<(), StringBlockError> { struct Context<'a> { source: &'a str, index: usize, @@ -116,7 +116,7 @@ a.len() } - fn guess_token_end_and_bump<'a>(lex: &mut logos::Lexer<'a, SyntaxKind>, ctx: &Context<'a>) { + fn guess_token_end_and_bump<'a>(lex: &mut Lexer<'a, SyntaxKind>, ctx: &Context<'a>) { let end_index = ctx .rest() .find("|||") @@ -140,12 +140,12 @@ Some('\n') => (), None => { guess_token_end_and_bump(lex, &ctx); - return UnexpectedEndOfString; + return Err(UnexpectedEnd); } // Text block requires new line after |||. Some(_) => { guess_token_end_and_bump(lex, &ctx); - return MissingTextBlockNewLine; + return Err(MissingNewLine); } } @@ -160,7 +160,7 @@ if num_whitespace == 0 { // Text block's first line must start with whitespace guess_token_end_and_bump(lex, &ctx); - return MissingTextBlockIndent; + return Err(MissingIndent); } loop { @@ -171,7 +171,7 @@ match ctx.next() { None => { guess_token_end_and_bump(lex, &ctx); - return UnexpectedEndOfString; + return Err(UnexpectedEnd); } Some('\n') => break, Some(_) => (), @@ -188,26 +188,21 @@ if num_whitespace == 0 { // End of the text block let mut term_indent = String::with_capacity(num_whitespace); - loop { - match ctx.peek() { - Some(' ') | Some('\t') => { - term_indent.push(ctx.next().unwrap()); - } - _ => break, - } + while let Some(' ' | '\t') = ctx.peek() { + term_indent.push(ctx.next().unwrap()); } if !ctx.rest().starts_with("|||") { // Text block not terminated with ||| let pos = ctx.pos(); - if pos.len() == 0 { + if pos.is_empty() { // eof lex.bump(ctx.index); - return UnexpectedEndOfString; + return Err(UnexpectedEnd); } guess_token_end_and_bump(lex, &ctx); - return MissingTextBlockTermination; + return Err(MissingTermination); } // Skip '|||' @@ -217,5 +212,5 @@ } lex.bump(ctx.index); - Valid + Ok(()) } --- a/crates/jrsonnet-rowan-parser/src/tests.rs +++ b/crates/jrsonnet-rowan-parser/src/tests.rs @@ -1,9 +1,11 @@ #![cfg(test)] -use miette::{Diagnostic, GraphicalReportHandler, LabeledSpan}; +use miette::{ + Diagnostic, GraphicalReportHandler, GraphicalTheme, LabeledSpan, ThemeCharacters, ThemeStyles, +}; use thiserror::Error; -use crate::parser::parse; +use crate::{parse, AstNode}; #[derive(Debug, Error)] #[error("syntax error")] @@ -44,19 +46,22 @@ fn process(text: &str) -> String { use std::fmt::Write; let mut out = String::new(); - let node = parse(text); + let (node, errors) = parse(text); write!(out, "{:#?}", node.syntax()).unwrap(); - if !node.errors.is_empty() && !text.is_empty() { + if !errors.is_empty() && !text.is_empty() { writeln!(out, "===").unwrap(); - for err in &node.errors { + for err in &errors { writeln!(out, "{:?}", err).unwrap(); } let diag = MyDiagnostic { code: text.to_string(), - spans: node.errors.into_iter().map(|e| e.into()).collect(), + spans: errors.into_iter().map(|e| e.into()).collect(), }; - let handler = GraphicalReportHandler::new(); + let handler = GraphicalReportHandler::new_themed(GraphicalTheme { + characters: ThemeCharacters::ascii(), + styles: ThemeStyles::none(), + }); write!(out, "===").unwrap(); handler.render_report(&mut out, &diag).unwrap(); @@ -77,51 +82,94 @@ mk_test!( empty => r#" "# function => r#" - function(a, b = 1) a + b - "# + function(a, b = 1) a + b + "# function_error_no_value => r#" - function(a, b = ) a + b - "# + function(a, b = ) a + b + "# function_error_rparen => r#" - function(a, b - "# + function(a, b + "# function_error_body => r#" - function(a, b) - "# + function(a, b) + "# local_novalue => r#" - local a = - "# + local a = + "# local_no_value_recovery => r#" - local a = - local b = 3; - 1 - "# + local a = + local b = 3; + 1 + "# array_comp => r#" - [a for a in [1, 2, 3]] - "# + [a for a in [1, 2, 3]] + "# array_comp_incompatible_with_multiple_elems => r#" - [a for a in [1, 2, 3], b] - "# + [a for a in [1, 2, 3], b] + "# no_rhs => r#" - a + - "# + a + + "# no_lhs => r#" - + 2 - "# + + 2 + "# no_operator => " - 2 2 - " + 2 2 + " named_before_positional => " - a(1, 2, b=4, 3, 5, k = 12, 6) - " + a(1, 2, b=4, 3, 5, k = 12, 6) + " wrong_field_end => " - { - a: 1; - b: 2; - } - " + { + a: 1; + b: 2; + } + " + + + plain_call => " + std.substr(a, 0, std.length(b)) == b + " + + destruct => " + local [a, b, c] = arr; + local [a, ...] = arr_rest; + local [..., a] = rest_arr; + local [...] = rest_in_arr; + local [a, ...n] = arr_rest_n; + local [...n, a] = rest_arr_n; + local [...n] = rest_in_arr_n; + + local {a, b, c} = obj; + local {a, b, c, ...} = obj_rest; + local {a, b, c, ...n} = obj_rest_n; + + null + " + + str_block_missing_indent => " + ||| + " + str_block_missing_termination => " + ||| + hello + " + str_block_missing_newline => " + |||hello + " + str_block_missing_indent_text => " + ||| + hello + " ); + +#[test] +fn stdlib() { + let src = jrsonnet_stdlib::STDLIB_STR; + let result = process(src); + insta::assert_snapshot!("stdlib", result, src); +} --- a/crates/jrsonnet-rowan-parser/src/token_set.rs +++ b/crates/jrsonnet-rowan-parser/src/token_set.rs @@ -1,14 +1,15 @@ use crate::SyntaxKind; #[derive(Clone, Copy, Default)] -pub struct SyntaxKindSet(u64); +pub struct SyntaxKindSet(u128); impl SyntaxKindSet { + #[allow(dead_code)] pub const EMPTY: Self = Self(0); - pub const ALL: Self = Self(u64::MAX); + pub const ALL: Self = Self(u128::MAX); pub const fn new(kinds: &[SyntaxKind]) -> SyntaxKindSet { - let mut res = 0u64; + let mut res = 0u128; let mut i = 0; while i < kinds.len() { res |= mask(kinds[i]); @@ -26,8 +27,8 @@ } } -const fn mask(kind: SyntaxKind) -> u64 { - 1u64 << (kind as usize) +const fn mask(kind: SyntaxKind) -> u128 { + 1u128 << (kind as u128) } #[macro_export] @@ -40,3 +41,11 @@ ]) }; } + +#[test] +fn sanity() { + assert!( + (SyntaxKind::ERROR as u32) < 127, + "can't keep KindSet as bitset" + ); +} --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -5,6 +5,7 @@ [dependencies] anyhow = "1.0.57" +indexmap = "1.9.0" itertools = "0.10.3" proc-macro2 = "1.0.39" quote = "1.0.18" --- a/xtask/src/sourcegen/ast.rs +++ b/xtask/src/sourcegen/ast.rs @@ -1,7 +1,13 @@ +use std::collections::{BTreeSet, HashMap}; + use proc_macro2::TokenStream; -use quote::{format_ident, quote}; +use quote::format_ident; +use ungrammar::{Grammar, Rule}; -use super::{escape_token_macro, KindsSrc}; +use super::{ + util::{pluralize, to_lower_snake_case}, + KindsSrc, +}; impl AstNodeSrc { pub fn remove_field(&mut self, to_remove: Vec) { @@ -14,9 +20,9 @@ #[allow(dead_code)] #[derive(Default, Debug)] pub struct AstSrc { - pub tokens: Vec, pub nodes: Vec, pub enums: Vec, + pub token_enums: Vec, } #[derive(Debug)] pub struct AstNodeSrc { @@ -38,7 +44,11 @@ #[derive(Debug, Eq, PartialEq)] pub enum Cardinality { + /// This field may not exist in code Optional, + /// This field should exist in correctly parsed code + Required, + /// There may be multiple field values of this kind Many, } @@ -50,6 +60,13 @@ pub variants: Vec, } +#[derive(Debug, Clone)] +pub struct AstTokenEnumSrc { + pub doc: Vec, + pub name: String, + pub variants: Vec, +} + impl Field { pub fn is_many(&self) -> bool { matches!( @@ -60,25 +77,29 @@ } ) } - pub fn token_kind(&self) -> Option { + + pub fn token_name(&self) -> Option { + match self { + Field::Token(token) => Some(token.clone()), + _ => None, + } + } + pub fn token_kind(&self, kinds: &KindsSrc) -> Option { match self { - Field::Token(token) => { - let token: TokenStream = escape_token_macro(token); - Some(quote! { T![#token] }) - } + Field::Token(token) => Some(kinds.token(token).expect("token exists").reference()), _ => None, } } + pub fn is_token_enum(&self, grammar: &AstSrc) -> bool { + match self { + Field::Node { ty, .. } => grammar.token_enums.iter().any(|e| &e.name == ty), + _ => false, + } + } pub fn method_name(&self, kinds: &KindsSrc) -> proc_macro2::Ident { match self { - Field::Token(name) => { - if let Some(punct_name) = kinds.get_punct_name(name) { - format_ident!("{}_token", punct_name.to_lowercase()) - } else { - format_ident!("{}_token", name.to_lowercase()) - } - } + Field::Token(name) => kinds.token(name).expect("token exists").method_name(), Field::Node { name, .. } => { format_ident!("{}", name) } @@ -91,3 +112,275 @@ } } } + +pub fn lower(kinds: &KindsSrc, grammar: &Grammar) -> AstSrc { + let mut res = AstSrc { + // tokens, + ..Default::default() + }; + + let nodes = grammar.iter().collect::>(); + + for &node in &nodes { + let name = grammar[node].name.clone(); + let rule = &grammar[node].rule; + match lower_enum(grammar, rule) { + Some(variants) => { + let enum_src = AstEnumSrc { + doc: Vec::new(), + name, + traits: Vec::new(), + variants, + }; + res.enums.push(enum_src); + } + None => match lower_token_enum(grammar, rule) { + Some(variants) => { + let tokens_enum_src = AstTokenEnumSrc { + doc: Vec::new(), + name, + variants, + }; + res.token_enums.push(tokens_enum_src); + } + None => { + let mut fields = Vec::new(); + lower_rule(&mut fields, grammar, None, rule, false); + let mut types = HashMap::new(); + for field in fields.iter().filter(|f| f.token_name().is_none()) { + if let Some(old) = types.insert(field.ty(), field.method_name(kinds)) { + panic!("{name}.{} has same type as {name}.{}, resolve conflict by wrapping one field: {}", old, field.method_name(kinds), field.ty()); + } + } + res.nodes.push(AstNodeSrc { + doc: Vec::new(), + name, + traits: Vec::new(), + fields, + }); + } + }, + } + } + + deduplicate_fields(&mut res); + extract_struct_traits(kinds, &mut res); + extract_enum_traits(&mut res); + res +} + +fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option> { + let alternatives = match rule { + Rule::Alt(it) => it, + _ => return None, + }; + let mut variants = Vec::new(); + for alternative in alternatives { + match alternative { + Rule::Node(it) => variants.push(grammar[*it].name.clone()), + Rule::Token(it) if grammar[*it].name == ";" => (), + _ => return None, + } + } + Some(variants) +} +fn lower_token_enum(grammar: &Grammar, rule: &Rule) -> Option> { + let alternatives = match rule { + Rule::Alt(it) => it, + _ => return None, + }; + let mut variants = Vec::new(); + for alternative in alternatives { + match alternative { + Rule::Token(it) => variants.push(grammar[*it].name.clone()), + _ => return None, + } + } + Some(variants) +} + +fn lower_rule( + acc: &mut Vec, + grammar: &Grammar, + label: Option<&String>, + rule: &Rule, + in_optional: bool, +) { + if lower_comma_list(acc, grammar, label, rule) { + return; + } + + match rule { + Rule::Node(node) => { + let ty = grammar[*node].name.clone(); + let name = label.cloned().unwrap_or_else(|| to_lower_snake_case(&ty)); + let field = Field::Node { + name, + ty, + cardinality: if in_optional { + Cardinality::Optional + } else { + Cardinality::Required + }, + }; + acc.push(field); + } + Rule::Token(token) => { + assert!(label.is_none(), "uexpected label: {:?}", label); + let name = grammar[*token].name.clone(); + let field = Field::Token(name); + acc.push(field); + } + Rule::Rep(inner) => { + if let Rule::Node(node) = &**inner { + let ty = grammar[*node].name.clone(); + let name = label + .cloned() + .unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty))); + let field = Field::Node { + name, + ty, + cardinality: Cardinality::Many, + }; + acc.push(field); + return; + } + todo!("unsupported repitition: {:?}", rule) + } + Rule::Labeled { label: l, rule } => { + assert!(label.is_none()); + lower_rule(acc, grammar, Some(l), rule, in_optional); + } + Rule::Seq(rules) | Rule::Alt(rules) => { + for rule in rules { + lower_rule(acc, grammar, label, rule, in_optional) + } + } + Rule::Opt(rule) => lower_rule(acc, grammar, label, rule, true), + } +} + +// (T (',' T)* ','?) +fn lower_comma_list( + acc: &mut Vec, + grammar: &Grammar, + label: Option<&String>, + rule: &Rule, +) -> bool { + let rule = match rule { + Rule::Seq(it) => it, + _ => return false, + }; + let (node, repeat, trailing_comma) = match rule.as_slice() { + [Rule::Node(node), Rule::Rep(repeat), Rule::Opt(trailing_comma)] => { + (node, repeat, trailing_comma) + } + _ => return false, + }; + let repeat = match &**repeat { + Rule::Seq(it) => it, + _ => return false, + }; + match repeat.as_slice() { + [comma, Rule::Node(n)] if comma == &**trailing_comma && n == node => (), + _ => return false, + } + let ty = grammar[*node].name.clone(); + let name = label + .cloned() + .unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty))); + let field = Field::Node { + name, + ty, + cardinality: Cardinality::Many, + }; + acc.push(field); + true +} + +fn deduplicate_fields(ast: &mut AstSrc) { + for node in &mut ast.nodes { + let mut i = 0; + 'outer: while i < node.fields.len() { + for j in 0..i { + let f1 = &node.fields[i]; + let f2 = &node.fields[j]; + if f1 == f2 { + node.fields.remove(i); + continue 'outer; + } + } + i += 1; + } + } +} + +fn extract_struct_traits(kinds: &KindsSrc, ast: &mut AstSrc) { + // TODO: add common accessor traits here. + let traits: &[(&str, &[&str])] = &[]; + + for node in &mut ast.nodes { + for (name, methods) in traits { + extract_struct_trait(kinds, node, name, methods); + } + } +} + +fn extract_struct_trait( + kinds: &KindsSrc, + node: &mut AstNodeSrc, + trait_name: &str, + methods: &[&str], +) { + let mut to_remove = Vec::new(); + for (i, field) in node.fields.iter().enumerate() { + let method_name = field.method_name(kinds).to_string(); + if methods.iter().any(|&it| it == method_name) { + to_remove.push(i); + } + } + if to_remove.len() == methods.len() { + node.traits.push(trait_name.to_string()); + node.remove_field(to_remove); + } +} + +fn extract_enum_traits(ast: &mut AstSrc) { + let enums = ast.enums.clone(); + for enm in &mut ast.enums { + let nodes = &ast.nodes; + + let mut variant_traits = enm.variants.iter().map(|var| { + nodes + .iter() + .find_map(|node| { + if &node.name != var { + return None; + } + Some(node.traits.iter().cloned().collect::>()) + }) + .unwrap_or_else(|| { + enums + .iter() + .find_map(|node| { + if &node.name != var { + return None; + } + Some(node.traits.iter().cloned().collect::>()) + }) + .unwrap_or_else(|| { + panic!("could not find struct {var} for enum {}::{var}", enm.name) + }) + }) + }); + + let mut enum_traits = match variant_traits.next() { + Some(it) => it, + None => continue, + }; + for traits in variant_traits { + enum_traits = enum_traits.intersection(&traits).cloned().collect(); + } + enm.traits = enum_traits.into_iter().collect(); + } +} --- /dev/null +++ b/xtask/src/sourcegen/kinds.rs @@ -0,0 +1,274 @@ +#[derive(Debug)] +pub struct KindsSrc { + /// Key - how this token appears in ungrammar + defined_tokens: IndexMap, + defined_node_names: HashSet, + pub nodes: Vec, +} + +#[derive(Debug, Clone)] +pub enum TokenKind { + /// May exist in token tree, but never in source code + Meta { grammar_name: String, name: String }, + /// Specific parsing errors may be emitted as this type of kind + Error { + grammar_name: String, + name: String, + regex: Option, + priority: Option, + }, + /// Keyword - literal match of token + Keyword { + /// How this keyword appears in grammar/code, should be same as Kinds key + code: String, + name: String, + }, + /// Literal - something defined by user, i.e strings, identifiers, smth + Literal { + /// How this keyword appears in grammar, should be same as Kinds key + grammar_name: String, + name: String, + /// Regex for Logos lexer + regex: String, + /// Path to custom lexer + lexer: Option, + }, +} + +impl TokenKind { + pub fn grammar_name(&self) -> &str { + match self { + TokenKind::Keyword { code, .. } => code, + TokenKind::Literal { grammar_name, .. } => grammar_name, + TokenKind::Meta { grammar_name, .. } => grammar_name, + TokenKind::Error { grammar_name, .. } => grammar_name, + } + } + /// How this keyword should appear in kinds enum, screaming snake cased + pub fn name(&self) -> &str { + match self { + TokenKind::Keyword { name, .. } => name, + TokenKind::Literal { name, .. } => name, + TokenKind::Meta { name, .. } => name, + TokenKind::Error { name, .. } => name, + } + } + pub fn expand_kind(&self) -> TokenStream { + let name = format_ident!("{}", self.name()); + let attr = match self { + TokenKind::Keyword { code, .. } => quote! {#[token(#code)]}, + TokenKind::Literal { regex, lexer, .. } => { + let lexer = lexer + .as_deref() + .map(TokenStream::from_str) + .map(|r| r.expect("path is correct")); + quote! {#[regex(#regex, #lexer)]} + } + TokenKind::Error { + regex, priority, .. + } if regex.is_some() => { + let priority = priority.map(|p| quote! {, priority = #p}); + quote! {#[regex(#regex #priority)]} + } + _ => quote! {}, + }; + quote! { + #attr + #name + } + } + pub fn expand_t_macros(&self) -> Option { + match self { + TokenKind::Keyword { code, name } => { + let code = escape_token_macro(code); + let name = format_ident!("{name}"); + Some(quote! { + [#code] => {$crate::SyntaxKind::#name} + }) + } + // Meta items should not appear in T![_] + _ => None, + } + } + + /// How this token should be referenced in code + /// Keywords are referenced with `T![_]` macro, + /// and literals are referenced directly by name + pub fn reference(&self) -> TokenStream { + match self { + TokenKind::Keyword { code, .. } => { + let code = escape_token_macro(code); + quote! {T![#code]} + } + _ => { + let name = self.name(); + let ident = format_ident!("{name}"); + quote! {#ident} + } + } + } + + pub fn method_name(&self) -> Ident { + match self { + TokenKind::Keyword { name, .. } => { + format_ident!("{}_token", name.to_lowercase()) + } + TokenKind::Literal { name, .. } => { + format_ident!("{}_lit", name.to_lowercase()) + } + TokenKind::Meta { name, .. } => format_ident!("{}_meta", name.to_lowercase()), + TokenKind::Error { name, .. } => format_ident!("{}_error", name.to_lowercase()), + } + } +} + +#[macro_export] +macro_rules! define_kinds { + ($into:ident = lit($name:literal) => $regex:literal $(, $lexer:literal)? $(; $($rest:tt)*)?) => {{ + $into.define_token(TokenKind::Literal { + grammar_name: format!("LIT_{}!", $name), + name: $name.to_owned(), + regex: $regex.to_owned(), + lexer: None $(.or_else(|| Some($lexer.to_string())))?, + }); + $(define_kinds!($into = $($rest)*))? + }}; + ($into:ident = error($name:literal$(, priority = $priority:literal)?) $(=> $regex:literal)? $(; $($rest:tt)*)?) => {{ + $into.define_token(TokenKind::Error { + grammar_name: format!("ERROR_{}!", $name), + name: format!("ERROR_{}", $name), + regex: None$(.or(Some($regex.to_owned())))?, + priority: None$(.or(Some($priority)))?, + }); + $(define_kinds!($into = $($rest)*))? + }}; + ($into:ident = $tok:literal => $name:literal $(; $($rest:tt)*)?) => {{ + $into.define_token(TokenKind::Keyword { + code: format!("{}", $tok), + name: $name.to_owned(), + }); + $(define_kinds!($into = $($rest)*))? + }}; + ($into:ident =) => {{}} +} +use std::{collections::HashSet, str::FromStr}; + +pub use define_kinds; +use indexmap::IndexMap; +use proc_macro2::{Ident, TokenStream}; +use quote::{format_ident, quote}; + +use super::escape_token_macro; + +impl KindsSrc { + pub fn new() -> Self { + Self { + defined_tokens: IndexMap::new(), + defined_node_names: HashSet::new(), + nodes: Vec::new(), + } + } + pub fn define_token(&mut self, token: TokenKind) { + assert!( + self.defined_node_names.insert(token.name().to_owned()), + "node name already defined: {}", + token.name() + ); + assert!( + self.defined_tokens + .insert(token.grammar_name().to_owned(), token.clone()) + .is_none(), + "token already defined: {}", + token.grammar_name() + ) + } + pub fn define_node(&mut self, node: &str) { + assert!( + self.defined_node_names.insert(node.to_owned()), + "node name already defined: {}", + node + ); + self.nodes.push(node.to_string()) + } + pub fn token(&self, tok: &str) -> Option<&TokenKind> { + self.defined_tokens.get(tok) + } + pub fn is_token(&self, tok: &str) -> bool { + self.defined_tokens.contains_key(tok) + } + pub fn tokens(&self) -> impl Iterator { + self.defined_tokens.iter().map(|(_, v)| v) + } +} + +pub fn jsonnet_kinds() -> KindsSrc { + let mut kinds = KindsSrc::new(); + define_kinds![kinds = + "||" => "OR"; + "&&" => "AND"; + "|" => "BIT_OR"; + "^" => "BIT_XOR"; + "&" => "BIT_AND"; + "==" => "EQ"; + "!=" => "NE"; + "<" => "LT"; + ">" => "GT"; + "<=" => "LE"; + ">=" => "GE"; + "<<" => "LHS"; + ">>" => "RHS"; + "+" => "PLUS"; + "-" => "MINUS"; + "*" => "MUL"; + "/" => "DIV"; + "%" => "MODULO"; + "!" => "NOT"; + "~" => "BIT_NOT"; + "[" => "L_BRACK"; + "]" => "R_BRACK"; + "(" => "L_PAREN"; + ")" => "R_PAREN"; + "{" => "L_BRACE"; + "}" => "R_BRACE"; + ":" => "COLON"; + "::" => "COLONCOLON"; + ":::" => "COLONCOLONCOLON"; + ";" => "SEMI"; + "." => "DOT"; + "..." => "DOTDOTDOT"; + "," => "COMMA"; + "$" => "DOLLAR"; + "=" => "ASSIGN"; + "?" => "QUESTION_MARK"; + "$intrinsicThisFile" => "INTRINSIC_THIS_FILE"; + "$intrinsicId" => "INTRINSIC_ID"; + "$intrinsic" => "INTRINSIC"; + // Literals + lit("FLOAT") => r"(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?"; + error("FLOAT_JUNK_AFTER_POINT") => r"(?:0|[1-9][0-9]*)\.[^0-9]"; + error("FLOAT_JUNK_AFTER_EXPONENT") => r"(?:0|[1-9][0-9]*)(?:\.[0-9]+)?[eE][^+\-0-9]"; + error("FLOAT_JUNK_AFTER_EXPONENT_SIGN") => r"(?:0|[1-9][0-9]*)(?:\.[0-9]+)?[eE][+-][^0-9]"; + lit("STRING_DOUBLE") => "\"(?s:[^\"\\\\]|\\\\.)*\""; + error("STRING_DOUBLE_UNTERMINATED") => "\"(?s:[^\"\\\\]|\\\\.)*"; + lit("STRING_SINGLE") => "'(?s:[^'\\\\]|\\\\.)*'"; + error("STRING_SINGLE_UNTERMINATED") => "'(?s:[^'\\\\]|\\\\.)*"; + lit("STRING_DOUBLE_VERBATIM") => "@\"(?:[^\"]|\"\")*\""; + error("STRING_DOUBLE_VERBATIM_UNTERMINATED") => "@\"(?:[^\"]|\"\")*"; + lit("STRING_SINGLE_VERBATIM") => "@'(?:[^']|'')*'"; + error("STRING_SINGLE_VERBATIM_UNTERMINATED") => "@'(?:[^']|'')*"; + error("STRING_VERBATIM_MISSING_QUOTES") => "@[^\"'\\s]\\S+"; + lit("STRING_BLOCK") => r"\|\|\|", "crate::string_block::lex_str_block_test"; + error("STRING_BLOCK_UNEXPECTED_END"); + error("STRING_BLOCK_MISSING_NEW_LINE"); + error("STRING_BLOCK_MISSING_TERMINATION"); + error("STRING_BLOCK_MISSING_INDENT"); + lit("IDENT") => r"[_a-zA-Z][_a-zA-Z0-9]*"; + lit("WHITESPACE") => r"[ \t\n\r]+"; + lit("SINGLE_LINE_SLASH_COMMENT") => r"//[^\r\n]*(\r\n|\n)?"; + lit("SINGLE_LINE_HASH_COMMENT") => r"#[^\r\n]*(\r\n|\n)?"; + lit("MULTI_LINE_COMMENT") => r"/\*([^*]|\*[^/])*\*/"; + error("COMMENT_TOO_SHORT") => r"/\*/"; + error("COMMENT_UNTERMINATED") => r"/\*([^*]|\*[^/])+"; + ]; + kinds +} --- a/xtask/src/sourcegen/mod.rs +++ b/xtask/src/sourcegen/mod.rs @@ -1,22 +1,36 @@ -use std::{ - collections::{BTreeSet, HashSet}, - path::PathBuf, -}; +use std::path::PathBuf; use anyhow::Result; -use ast::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field}; +use ast::{lower, AstSrc}; use itertools::Itertools; +use kinds::{KindsSrc, TokenKind}; use proc_macro2::{Punct, Spacing, TokenStream}; use quote::{format_ident, quote}; -use ungrammar::{Grammar, Rule}; -use util::{ - ensure_file_contents, pluralize, reformat, to_lower_snake_case, to_pascal_case, - to_upper_snake_case, -}; +use ungrammar::Grammar; +use util::{ensure_file_contents, reformat, to_pascal_case, to_upper_snake_case}; mod ast; +mod kinds; mod util; +enum SpecialName { + Literal, + Meta, + Error, +} +fn classify_special(name: &str) -> Option<(SpecialName, &str)> { + let name = name.strip_suffix('!')?; + Some(if let Some(name) = name.strip_prefix("LIT_") { + (SpecialName::Literal, name) + } else if let Some(name) = name.strip_prefix("META_") { + (SpecialName::Meta, name) + } else if let Some(name) = name.strip_prefix("ERROR_") { + (SpecialName::Error, name) + } else { + return None; + }) +} + pub fn generate_ungrammar() -> Result<()> { let grammar: Grammar = include_str!(concat!( env!("CARGO_MANIFEST_DIR"), @@ -24,93 +38,51 @@ )) .parse()?; - let mut kinds: KindsSrc = KindsSrc { - punct: puncts![ - "||" => "OR"; - "&&" => "AND"; - "|" => "BIT_OR"; - "^" => "BIT_XOR"; - "&" => "BIT_AND"; - "==" => "EQ"; - "!=" => "NE"; - "<" => "LT"; - ">" => "GT"; - "<=" => "LE"; - ">=" => "GE"; - "<<" => "LHS"; - ">>" => "RHS"; - "+" => "PLUS"; - "-" => "MINUS"; - "*" => "MUL"; - "/" => "DIV"; - "%" => "MODULO"; - "!" => "NOT"; - "~" => "BIT_NOT"; - "[" => "L_BRACK"; - "]" => "R_BRACK"; - "(" => "L_PAREN"; - ")" => "R_PAREN"; - "{" => "L_BRACE"; - "}" => "R_BRACE"; - ":" => "COLON"; - "::" => "COLONCOLON"; - ":::" => "COLONCOLONCOLON"; - ";" => "SEMI"; - "." => "DOT"; - "..." => "DOTDOTDOT"; - "," => "COMMA"; - "$" => "DOLLAR"; - "=" => "ASSIGN"; - "?" => "QUESTION_MARK"; - "$intrinsicThisFile" => "INTRINSIC_THIS_FILE"; - "$intrinsicId" => "INTRINSIC_ID"; - "$intrinsic" => "INTRINSIC"; - ], - keywords: vec![], - literals: literals![ - "NUMBER" => r"(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?"; - "STRING_DOUBLE" => "\"(?s:[^\"\\\\]|\\\\.)*\""; - "STRING_SINGLE" => "'(?s:[^'\\\\]|\\\\.)*'"; - "STRING_DOUBLE_VERBATIM" => "@\"(?:[^\"]|\"\")*\""; - "STRING_SINGLE_VERBATIM" => "@'(?:[^']|'')*'"; - "STRING_BLOCK" => r"\|\|\|"; - - "IDENT" => r"[_a-zA-Z][_a-zA-Z0-9]*"; - "WHITESPACE" => r"[ \t\n\r]+"; - "SINGLE_LINE_SLASH_COMMENT" => r"//[^\r\n]*(\r\n|\n)?"; - "SINGLE_LINE_HASH_COMMENT" => r"#[^\r\n]*(\r\n|\n)?"; - "MULTI_LINE_COMMENT" => r"/\*([^*]|\*[^/])*\*/"; - ], - nodes: vec![], - }; - + let mut kinds = kinds::jsonnet_kinds(); let ast = lower(&kinds, &grammar); + for token in grammar.tokens() { + let token = &grammar[token]; + let token = &token.name.clone(); + if !kinds.is_token(token) { + if let Some((special, name)) = classify_special(token) { + match special { + SpecialName::Literal => panic!("literal is not defined: {name}"), + SpecialName::Meta => kinds.define_token(TokenKind::Meta { + grammar_name: token.to_owned(), + name: format!("META_{}", name), + }), + SpecialName::Error => kinds.define_token(TokenKind::Error { + grammar_name: token.to_owned(), + name: format!("ERROR_{}", name), + regex: None, + priority: None, + }), + }; + continue; + }; + let name = to_upper_snake_case(token); + kinds.define_token(TokenKind::Keyword { + code: token.to_owned(), + name: format!("{name}_KW"), + }); + } + } for node in &ast.nodes { let name = to_upper_snake_case(&node.name); - if !kinds.is_literal(&name) { - kinds.nodes.push(name); - } + kinds.define_node(&name); } for enum_ in &ast.enums { let name = to_upper_snake_case(&enum_.name); - if !kinds.is_literal(&name) { - kinds.nodes.push(name); - } + kinds.define_node(&name); } - for token in grammar.tokens() { - let token = &grammar[token]; - let token = &token.name.clone(); - let name = to_upper_snake_case(token); - if !kinds.is_punct(token) && !kinds.is_literal(&name) { - kinds.keywords.push(token.to_owned()); - } + for token_enum in &ast.token_enums { + let name = to_upper_snake_case(&token_enum.name); + kinds.define_node(&name); } - let syntax_kinds = generate_syntax_kinds(&kinds)?; + let syntax_kinds = generate_syntax_kinds(&kinds, &ast)?; - let tokens = generate_tokens(&ast)?; - let nodes = generate_nodes(&kinds, &ast)?; ensure_file_contents( &PathBuf::from(concat!( @@ -118,13 +90,6 @@ "/../crates/jrsonnet-rowan-parser/src/generated/syntax_kinds.rs", )), &syntax_kinds, - )?; - ensure_file_contents( - &PathBuf::from(concat!( - env!("CARGO_MANIFEST_DIR"), - "/../crates/jrsonnet-rowan-parser/src/generated/tokens.rs", - )), - &tokens, )?; ensure_file_contents( &PathBuf::from(concat!( @@ -134,123 +99,37 @@ &nodes, )?; Ok(()) -} - -fn generate_tokens(grammar: &AstSrc) -> Result { - let tokens = grammar.tokens.iter().map(|token| { - let name = format_ident!("{}", token); - let kind = format_ident!("{}", to_upper_snake_case(token)); - quote! { - #[derive(Debug, Clone, PartialEq, Eq, Hash)] - pub struct #name { - pub(crate) syntax: SyntaxToken, - } - impl std::fmt::Display for #name { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.syntax, f) - } - } - impl AstToken for #name { - fn can_cast(kind: SyntaxKind) -> bool { kind == #kind } - fn cast(syntax: SyntaxToken) -> Option { - if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } - } - fn syntax(&self) -> &SyntaxToken { &self.syntax } - } - } - }); - - Ok(reformat( - "e! { - use crate::{SyntaxKind::{self, *}, SyntaxToken, ast::AstToken}; - #(#tokens)* - } - .to_string(), - )? - .replace("#[derive", "\n#[derive")) } -fn generate_syntax_kinds(grammar: &KindsSrc) -> Result { - let (single_byte_tokens_values, single_byte_tokens): (Vec<_>, Vec<_>) = grammar - .punct - .iter() - .filter(|(token, _name)| token.len() == 1) - .map(|(token, name)| (token.chars().next().unwrap(), format_ident!("{}", name))) - .unzip(); +fn generate_syntax_kinds(kinds: &KindsSrc, grammar: &AstSrc) -> Result { + let t_macros = kinds.tokens().filter_map(TokenKind::expand_t_macros); + let token_kinds = kinds.tokens().map(TokenKind::expand_kind); - let punctuation_values = grammar - .punct - .iter() - .map(|(token, _name)| escape_token_macro(token)); - let punctuation = grammar - .punct - .iter() - .map(|(_token, name)| format_ident!("{}", name)) - .collect::>(); - let punctuation_enum = grammar - .punct - .iter() - .map(|(token, name)| { - let id = format_ident!("{}", name); - quote! { - #[token(#token)] - #id - } - }) - .collect::>(); + let keywords = kinds + .tokens() + .filter(|k| matches!(k, TokenKind::Keyword { .. })) + .map(TokenKind::name) + .map(|n| format_ident!("{n}")); - let x = |name: &str| format_ident!("{}_KW", to_upper_snake_case(name)); - let full_keywords_values = &grammar.keywords; - let full_keywords = full_keywords_values.iter().map(|s| x(s.as_str())); - - let all_keywords_values = grammar.keywords.to_vec(); - let all_keywords_idents = all_keywords_values.iter().map(|kw| format_ident!("{}", kw)); - let all_keywords = all_keywords_values + let nodes = kinds + .nodes .iter() - .map(|s| x(&**s)) + .map(|name| format_ident!("{}", name)) .collect::>(); - let all_keywords_enum = all_keywords_values - .iter() - .map(|s| { - let id = x(&**s); - quote! { - #[token(#s)] - #id - } - }) - .collect::>(); - let tokens_enum = grammar - .literals + let enums = grammar + .enums .iter() - .map(|l| { - let regex = &l.regex; - let id = format_ident!("{}", l.name); - let lexer = l - .lexer - .as_ref() - .map(|l| { - let id: TokenStream = l.parse().expect("path"); - quote! { - , #id - } - }) - .unwrap_or_else(|| quote! {}); - quote! { - #[regex(#regex #lexer)] - #id - } - }) - .collect::>(); - - let nodes = grammar - .nodes - .iter() - .map(|name| format_ident!("{}", name)) - .collect::>(); + .map(|e| format_ident!("{}", to_upper_snake_case(&e.name))) + .chain( + grammar + .token_enums + .iter() + .map(|e| format_ident!("{}", to_upper_snake_case(&e.name))), + ); let ast = quote! { - #![allow(bad_style, missing_docs, unreachable_pub)] + #![allow(bad_style, missing_docs, unreachable_pub, clippy::manual_non_exhaustive, clippy::match_like_matches_macro)] use logos::Logos; /// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT`. @@ -261,9 +140,7 @@ TOMBSTONE, #[doc(hidden)] EOF, - #(#punctuation_enum,)* - #(#all_keywords_enum,)* - #(#tokens_enum,)* + #(#token_kinds,)* #[error] ERROR, #(#nodes,)* @@ -275,32 +152,15 @@ impl SyntaxKind { pub fn is_keyword(self) -> bool { match self { - #(#all_keywords)|* => true, + #(#keywords)|* => true, _ => false, } } - - pub fn is_punct(self) -> bool { + pub fn is_enum(self) -> bool { match self { - #(#punctuation)|* => true, + #(#enums)|* => true, _ => false, } - } - - pub fn from_keyword(ident: &str) -> Option { - let kw = match ident { - #(#full_keywords_values => #full_keywords,)* - _ => return None, - }; - Some(kw) - } - - pub fn from_char(c: char) -> Option { - let tok = match c { - #(#single_byte_tokens_values => #single_byte_tokens,)* - _ => return None, - }; - Some(tok) } pub fn from_raw(r: u16) -> Self { @@ -313,71 +173,13 @@ } #[macro_export] - macro_rules! T { - #([#punctuation_values] => { $crate::SyntaxKind::#punctuation };)* - #([#all_keywords_idents] => { $crate::SyntaxKind::#all_keywords };)* - [lifetime_ident] => { $crate::SyntaxKind::LIFETIME_IDENT }; - [ident] => { $crate::SyntaxKind::IDENT }; - [shebang] => { $crate::SyntaxKind::SHEBANG }; - } + macro_rules! T {#(#t_macros);*} pub use T; }; reformat(&ast.to_string()) -} - -pub struct KindsSrc { - pub punct: Vec<(String, String)>, - pub keywords: Vec, - pub literals: Vec, - pub nodes: Vec, -} - -pub struct LiteralKind { - name: String, - regex: String, - lexer: Option, -} - -#[macro_export] -macro_rules! literals { - ($($name:expr => $regex:expr $(, $lexer:expr)?);* $(;)?) => { - vec![ - $(LiteralKind { - name: $name.to_owned(), - regex: $regex.to_owned(), - lexer: None $(.or_else(|| Some($lexer.to_string())))?, - }),* - ] - }; -} - -#[macro_export] -macro_rules! puncts { - ($($tok:expr => $name:expr);* $(;)?) => { - vec![ - $(($tok.to_owned(), $name.to_owned())),* - ] - }; } -use crate::{literals, puncts}; - -impl KindsSrc { - pub fn is_punct(&self, tok: &str) -> bool { - self.punct.iter().any(|(t, _)| *t == tok) - } - pub fn is_literal(&self, tok: &str) -> bool { - self.literals.iter().any(|l| l.name == tok) - } - fn get_punct_name(&self, tok: &str) -> Option<&str> { - self.punct - .iter() - .find(|(t, _)| *t == tok) - .map(|(_, n)| n.as_str()) - } -} - fn generate_nodes(kinds: &KindsSrc, grammar: &AstSrc) -> Result { let (node_defs, node_boilerplate_impls): (Vec<_>, Vec<_>) = grammar .nodes @@ -400,12 +202,18 @@ support::children(&self.syntax) } } - } else if let Some(token_kind) = field.token_kind() { + } else if let Some(token_kind) = field.token_kind(kinds) { quote! { pub fn #method_name(&self) -> Option<#ty> { support::token(&self.syntax, #token_kind) } } + } else if field.is_token_enum(grammar) { + quote! { + pub fn #method_name(&self) -> Option<#ty> { + support::token_child(&self.syntax) + } + } } else { quote! { pub fn #method_name(&self) -> Option<#ty> { @@ -513,6 +321,80 @@ }) .unzip(); + let (token_enum_defs, token_enum_boilerplate_impls): (Vec<_>, Vec<_>) = grammar + .token_enums + .iter() + .map(|en| { + let variants: Vec<_> = en + .variants + .iter() + .map(|token| { + format_ident!( + "{}", + to_pascal_case(kinds.token(token).expect("token exists").name()) + ) + }) + .collect(); + let name = format_ident!("{}", en.name); + let kind_name = format_ident!("{}Kind", en.name); + let kinds: Vec<_> = variants + .iter() + .map(|name| format_ident!("{}", to_upper_snake_case(&name.to_string()))) + .collect(); + + let ast_node = quote! { + impl AstToken for #name { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + #(#kinds)|* => true, + _ => false, + } + } + fn cast(syntax: SyntaxToken) -> Option { + let res = match syntax.kind() { + #( + #kinds => #name { syntax, kind: #kind_name::#variants }, + )* + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxToken { + &self.syntax + } + } + }; + + ( + quote! { + #[pretty_doc_comment_placeholder_workaround] + #[derive(Debug, Clone, PartialEq, Eq, Hash)] + pub struct #name { syntax: SyntaxToken, kind: #kind_name } + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum #kind_name { + #(#variants,)* + } + }, + quote! { + #ast_node + + impl #name { + pub fn kind(&self) -> #kind_name { + self.kind + } + } + + impl std::fmt::Display for #name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } + } + }, + ) + }) + .unzip(); + let (any_node_defs, any_node_boilerplate_impls): (Vec<_>, Vec<_>) = grammar .nodes .iter() @@ -581,32 +463,22 @@ } }); - let defined_nodes: HashSet<_> = node_names.collect(); - - for node in kinds - .nodes - .iter() - .map(|kind| to_pascal_case(kind)) - .filter(|name| !defined_nodes.iter().any(|&it| it == name)) - { - drop(node) - // FIXME: restore this - // eprintln!("Warning: node {} not defined in ast source", node); - } - let ast = quote! { - #![allow(non_snake_case)] + #![allow(non_snake_case, clippy::match_like_matches_macro)] + use crate::{ SyntaxNode, SyntaxToken, SyntaxKind::{self, *}, - ast::{self, AstNode, AstChildren, support}, + ast::{AstNode, AstToken, AstChildren, support}, T, }; #(#node_defs)* #(#enum_defs)* + #(#token_enum_defs)* #(#any_node_defs)* #(#node_boilerplate_impls)* #(#enum_boilerplate_impls)* + #(#token_enum_boilerplate_impls)* #(#any_node_boilerplate_impls)* #(#display_impls)* }; @@ -636,276 +508,6 @@ use std::fmt::Write; for line in contents { writeln!(dest, "///{}", line).unwrap(); - } -} - -fn lower(kinds: &KindsSrc, grammar: &Grammar) -> AstSrc { - let tokens = "Whitespace Comment String StringVerbantim StringBlock Number Ident" - .split_ascii_whitespace() - .map(|it| it.to_string()) - .collect::>(); - - let mut res = AstSrc { - tokens, - ..Default::default() - }; - - let nodes = grammar.iter().collect::>(); - - for &node in &nodes { - let name = grammar[node].name.clone(); - let rule = &grammar[node].rule; - match lower_enum(grammar, rule) { - Some(variants) => { - let enum_src = AstEnumSrc { - doc: Vec::new(), - name, - traits: Vec::new(), - variants, - }; - res.enums.push(enum_src); - } - None => { - let mut fields = Vec::new(); - lower_rule(&mut fields, grammar, None, rule); - res.nodes.push(AstNodeSrc { - doc: Vec::new(), - name, - traits: Vec::new(), - fields, - }); - } - } - } - - deduplicate_fields(&mut res); - extract_enums(&mut res); - extract_struct_traits(kinds, &mut res); - extract_enum_traits(&mut res); - res -} - -fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option> { - let alternatives = match rule { - Rule::Alt(it) => it, - _ => return None, - }; - let mut variants = Vec::new(); - for alternative in alternatives { - match alternative { - Rule::Node(it) => variants.push(grammar[*it].name.clone()), - Rule::Token(it) if grammar[*it].name == ";" => (), - _ => return None, - } - } - Some(variants) -} - -fn lower_rule(acc: &mut Vec, grammar: &Grammar, label: Option<&String>, rule: &Rule) { - if lower_comma_list(acc, grammar, label, rule) { - return; - } - - match rule { - Rule::Node(node) => { - let ty = grammar[*node].name.clone(); - let name = label.cloned().unwrap_or_else(|| to_lower_snake_case(&ty)); - let field = Field::Node { - name, - ty, - cardinality: Cardinality::Optional, - }; - acc.push(field); - } - Rule::Token(token) => { - assert!(label.is_none(), "uexpected label: {:?}", label); - let name = grammar[*token].name.clone(); - let field = Field::Token(name); - acc.push(field); - } - Rule::Rep(inner) => { - if let Rule::Node(node) = &**inner { - let ty = grammar[*node].name.clone(); - let name = label - .cloned() - .unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty))); - let field = Field::Node { - name, - ty, - cardinality: Cardinality::Many, - }; - acc.push(field); - return; - } - todo!("unsupported repitition: {:?}", rule) - } - Rule::Labeled { label: l, rule } => { - assert!(label.is_none()); - lower_rule(acc, grammar, Some(l), rule); - } - Rule::Seq(rules) | Rule::Alt(rules) => { - for rule in rules { - lower_rule(acc, grammar, label, rule) - } - } - Rule::Opt(rule) => lower_rule(acc, grammar, label, rule), - } -} - -// (T (',' T)* ','?) -fn lower_comma_list( - acc: &mut Vec, - grammar: &Grammar, - label: Option<&String>, - rule: &Rule, -) -> bool { - let rule = match rule { - Rule::Seq(it) => it, - _ => return false, - }; - let (node, repeat, trailing_comma) = match rule.as_slice() { - [Rule::Node(node), Rule::Rep(repeat), Rule::Opt(trailing_comma)] => { - (node, repeat, trailing_comma) - } - _ => return false, - }; - let repeat = match &**repeat { - Rule::Seq(it) => it, - _ => return false, - }; - match repeat.as_slice() { - [comma, Rule::Node(n)] if comma == &**trailing_comma && n == node => (), - _ => return false, - } - let ty = grammar[*node].name.clone(); - let name = label - .cloned() - .unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty))); - let field = Field::Node { - name, - ty, - cardinality: Cardinality::Many, - }; - acc.push(field); - true -} - -fn deduplicate_fields(ast: &mut AstSrc) { - for node in &mut ast.nodes { - let mut i = 0; - 'outer: while i < node.fields.len() { - for j in 0..i { - let f1 = &node.fields[i]; - let f2 = &node.fields[j]; - if f1 == f2 { - node.fields.remove(i); - continue 'outer; - } - } - i += 1; - } - } -} - -fn extract_enums(ast: &mut AstSrc) { - for node in &mut ast.nodes { - for enm in &ast.enums { - let mut to_remove = Vec::new(); - for (i, field) in node.fields.iter().enumerate() { - let ty = field.ty().to_string(); - if enm.variants.iter().any(|it| it == &ty) { - to_remove.push(i); - } - } - if to_remove.len() == enm.variants.len() { - node.remove_field(to_remove); - let ty = enm.name.clone(); - let name = to_lower_snake_case(&ty); - node.fields.push(Field::Node { - name, - ty, - cardinality: Cardinality::Optional, - }); - } - } - } -} - -fn extract_struct_traits(kinds: &KindsSrc, ast: &mut AstSrc) { - // TODO: add common accessor traits here. - let traits: &[(&str, &[&str])] = &[]; - - for node in &mut ast.nodes { - for (name, methods) in traits { - extract_struct_trait(kinds, node, name, methods); - } - } -} - -fn extract_struct_trait( - kinds: &KindsSrc, - node: &mut AstNodeSrc, - trait_name: &str, - methods: &[&str], -) { - let mut to_remove = Vec::new(); - for (i, field) in node.fields.iter().enumerate() { - let method_name = field.method_name(kinds).to_string(); - if methods.iter().any(|&it| it == method_name) { - to_remove.push(i); - } - } - if to_remove.len() == methods.len() { - node.traits.push(trait_name.to_string()); - node.remove_field(to_remove); - } -} - -fn extract_enum_traits(ast: &mut AstSrc) { - let enums = ast.enums.clone(); - for enm in &mut ast.enums { - if enm.name == "Stmt" { - continue; - } - let nodes = &ast.nodes; - - let mut variant_traits = enm.variants.iter().map(|var| { - nodes - .iter() - .find_map(|node| { - if &node.name != var { - return None; - } - Some(node.traits.iter().cloned().collect::>()) - }) - .unwrap_or_else(|| { - enums - .iter() - .find_map(|node| { - if &node.name != var { - return None; - } - Some(node.traits.iter().cloned().collect::>()) - }) - .unwrap_or_else(|| { - panic!("{}", { - &format!( - "Could not find a struct `{}` for enum `{}::{}`", - var, enm.name, var - ) - }) - }) - }) - }); - - let mut enum_traits = match variant_traits.next() { - Some(it) => it, - None => continue, - }; - for traits in variant_traits { - enum_traits = enum_traits.intersection(&traits).cloned().collect(); - } - enm.traits = enum_traits.into_iter().collect(); } } --- a/xtask/src/sourcegen/util.rs +++ b/xtask/src/sourcegen/util.rs @@ -1,6 +1,6 @@ use std::{fs, path::Path}; -use anyhow::{bail, Result}; +use anyhow::Result; use xshell::{cmd, Shell}; /// Checks that the `file` has the specified `contents`. If that is not the @@ -15,13 +15,13 @@ eprintln!(" {} was not up-to-date, updating\n", file.display()); if std::env::var("CI").is_ok() { - eprintln!("NOTE: run `cargo test` locally and commit the updated files\n"); + eprintln!("NOTE: run `cargo xtask` locally and commit the updated files\n"); } if let Some(parent) = file.parent() { let _ = fs::create_dir_all(parent); } fs::write(file, contents).unwrap(); - bail!("some file was not up to date and has been updated, simply re-run the tests"); + Ok(()) } // Eww, someone configured git to use crlf? @@ -80,9 +80,7 @@ // let _e = pushenv("RUSTUP_TOOLCHAIN", "stable"); // rustfmt()?; let sh = Shell::new()?; - let stdout = cmd!(sh, "rustfmt --config fn_single_line=true") - .stdin(text) - .read()?; + let stdout = cmd!(sh, "rustfmt").stdin(text).read()?; Ok(format!( "{}\n\n{}\n", "//! This is a generated file, please do not edit manually. Changes can be -- gitstuff