Compare commits

..

2 Commits

6 changed files with 204 additions and 12 deletions

View File

@ -93,7 +93,6 @@ describe('pipe expressions', () => {
`).toEvaluateTo(5) `).toEvaluateTo(5)
}) })
test('string literals can be piped', () => { test('string literals can be piped', () => {
expect(`'hey there' | str.to-upper`).toEvaluateTo('HEY THERE') expect(`'hey there' | str.to-upper`).toEvaluateTo('HEY THERE')
}) })

View File

@ -21,7 +21,7 @@
("-" | "+")? $[0-9]+ ("_"? $[0-9]+)* ('.' $[0-9]+ ("_"? $[0-9]+)*)? ("-" | "+")? $[0-9]+ ("_"? $[0-9]+)* ('.' $[0-9]+ ("_"? $[0-9]+)*)?
} }
Boolean { "true" | "false" } Boolean { "true" | "false" }
newlineOrSemicolon { "\n" | ";" } semicolon { ";" }
eof { @eof } eof { @eof }
space { " " | "\t" } space { " " | "\t" }
Comment { "#" ![\n]* } Comment { "#" ![\n]* }
@ -34,6 +34,8 @@
"|"[@name=operator] "|"[@name=operator]
} }
newlineOrSemicolon { newline | semicolon }
end { @specialize[@name=keyword]<Identifier, "end"> } end { @specialize[@name=keyword]<Identifier, "end"> }
while { @specialize[@name=keyword]<Identifier, "while"> } while { @specialize[@name=keyword]<Identifier, "while"> }
if { @specialize[@name=keyword]<Identifier, "if"> } if { @specialize[@name=keyword]<Identifier, "if"> }
@ -46,6 +48,7 @@ import { @specialize[@name=keyword]<Identifier, "import"> }
null { @specialize[@name=Null]<Identifier, "null"> } null { @specialize[@name=Null]<Identifier, "null"> }
@external tokens tokenizer from "./tokenizer" { Identifier, AssignableIdentifier, Word, IdentifierBeforeDot, CurlyString } @external tokens tokenizer from "./tokenizer" { Identifier, AssignableIdentifier, Word, IdentifierBeforeDot, CurlyString }
@external tokens pipeStartsLineTokenizer from "./tokenizer" { newline, pipeStartsLine }
@external specialize {Identifier} specializeKeyword from "./tokenizer" { Do } @external specialize {Identifier} specializeKeyword from "./tokenizer" { Do }
@precedence { @precedence {
@ -85,7 +88,7 @@ consumeToTerminator {
} }
PipeExpr { PipeExpr {
pipeOperand (!pipe "|" pipeOperand)+ pipeOperand (!pipe (pipeStartsLine? "|") newlineOrSemicolon* pipeOperand)+
} }
pipeOperand { pipeOperand {

View File

@ -32,6 +32,8 @@ export const
Word = 30, Word = 30,
IdentifierBeforeDot = 31, IdentifierBeforeDot = 31,
CurlyString = 32, CurlyString = 32,
newline = 101,
pipeStartsLine = 102,
Do = 33, Do = 33,
Comment = 34, Comment = 34,
Program = 35, Program = 35,

View File

@ -1,17 +1,17 @@
// This file was generated by lezer-generator. You probably shouldn't edit it. // This file was generated by lezer-generator. You probably shouldn't edit it.
import {LRParser, LocalTokenGroup} from "@lezer/lr" import {LRParser, LocalTokenGroup} from "@lezer/lr"
import {operatorTokenizer} from "./operatorTokenizer" import {operatorTokenizer} from "./operatorTokenizer"
import {tokenizer, specializeKeyword} from "./tokenizer" import {tokenizer, pipeStartsLineTokenizer, specializeKeyword} from "./tokenizer"
import {trackScope} from "./parserScopeContext" import {trackScope} from "./parserScopeContext"
import {highlighting} from "./highlight" import {highlighting} from "./highlight"
const spec_Identifier = {__proto__:null,while:78, null:116, catch:122, finally:128, end:130, if:138, else:144, try:160, throw:164, import:168} const spec_Identifier = {__proto__:null,while:78, null:116, catch:122, finally:128, end:130, if:138, else:144, try:160, throw:164, import:168}
export const parser = LRParser.deserialize({ export const parser = LRParser.deserialize({
version: 14, version: 14,
states: ">`QYQbOOO!pOpO'#DXO%eQcO'#DdO%{OSO'#DaOOQa'#Da'#DaO(vQcO'#EjOOQ`'#Ex'#ExO)aQRO'#DxO+fQcO'#EhO,PQbO'#DVOOQa'#Dz'#DzO.kQbO'#D{OOQa'#Ej'#EjO.rQcO'#EjO0pQcO'#EiO1uQcO'#EhO2SQRO'#ETOOQ`'#Eh'#EhO2kQbO'#EhO2rQQO'#EgOOQ`'#Eg'#EgOOQ`'#EV'#EVQYQbOOO2}QbO'#D]O3YQbO'#DrO4WQbO'#DSO5UQQO'#D}O4WQbO'#EPO5ZQbO'#ERO5cObO,59sOOQ`'#D['#D[O5tQbO'#DqOOQ`'#En'#EnOOQ`'#E_'#E_O6OQbO,5:`OOQa'#Ei'#EiO6xQbO'#DcO7WQWO'#DeOOOO'#Ep'#EpOOOO'#E['#E[O7lOSO,59{OOQa,59{,59{O4WQbO,5:dO4WQbO,5:dO4WQbO,5:dO4WQbO,5:dO4WQbO,59pO4WQbO,59pO4WQbO,59pO4WQbO,59pOOQ`'#EX'#EXO,PQbO,59qO7zQcO'#DdO8RQcO'#EjO8YQRO,59qO8dQQO,59qO8iQQO,59qO8qQQO,59qO8|QRO,59qO9fQRO,59qO9mQQO'#DQO9rQbO,5:gO9yQQO,5:fOOQa,5:g,5:gO:UQbO,5:gO:`QbO,5:pO:`QbO,5:oO;sQbO,5:hO;zQbO,59lOOQ`,5;R,5;RO:`QbO'#EWOOQ`-E8T-E8TOOQ`'#EY'#EYO<fQbO'#D^O<qQbO'#D_OOQO'#EZ'#EZO<iQQO'#D^O=VQQO,59wO=[QcO'#EiO>XQRO'#EwO?UQRO'#EwOOQO'#Ew'#EwO?]QQO,5:^O?bQRO,59nO?iQRO,59nO;sQbO,5:iO?wQcO,5:kOAVQcO,5:kOAsQcO,5:kOBhQbO,5:mOOQ`'#Ec'#EcO5ZQbO,5:mOOQa1G/_1G/_OOQ`,5:],5:]OOQ`-E8]-E8]OOOO'#Dd'#DdOOOO,59},59}OOOO,5:P,5:POOOO-E8Y-E8YOOQa1G/g1G/gOOQa1G0O1G0OODaQcO1G0OODkQcO1G0OOEyQcO1G0OOFTQcO1G0OOFbQcO1G0OOOQa1G/[1G/[OGsQcO1G/[OGzQcO1G/[OHRQcO1G/[OIQQcO1G/[OHYQcO1G/[OOQ`-E8V-E8VOIhQRO1G/]OIrQQO1G/]OIwQQO1G/]OJPQQO1G/]OJ[QRO1G/]OJcQRO1G/]OJjQbO,59rOJtQQO1G/]OOQa1G/]1G/]OJ|QQO1G0QOOQa1G0R1G0ROKXQbO1G0ROOQO'#Ea'#EaOJ|QQO1G0QOOQa1G0Q1G0QOOQ`'#Eb'#EbOKXQbO1G0ROKcQbO1G0[OK}QbO1G0ZOLiQbO'#DlOLzQbO'#DlOM_QbO1G0SOOQ`-E8U-E8UOOQ`,5:r,5:rOOQ`-E8W-E8WOMjQQO,59xOOQO,59y,59yOOQO-E8X-E8XOMrQbO1G/cO;sQbO1G/xO;sQbO1G/YOMyQbO1G0TONUQbO1G0XONsQbO1G0XOOQ`-E8a-E8aONzQQO7+$wOOQa7+$w7+$wO! SQQO1G/^O! [QQO7+%lOOQa7+%l7+%lO! gQbO7+%mOOQa7+%m7+%mOOQO-E8_-E8_OOQ`-E8`-E8`OOQ`'#E]'#E]O! qQQO'#E]O! yQbO'#EvOOQ`,5:W,5:WO!!^QbO'#DjO!!cQQO'#DmOOQ`7+%n7+%nO!!hQbO7+%nO!!mQbO7+%nO!!uQbO7+$}O!#TQbO7+$}O!#eQbO7+%dO!#mQbO7+$tOOQ`7+%o7+%oO!#rQbO7+%oO!#wQbO7+%oO!$PQbO7+%sOOQa<<Hc<<HcO!$nQbO7+$xO!${QQO7+$xOOQa<<IW<<IWOOQa<<IX<<IXOOQ`,5:w,5:wOOQ`-E8Z-E8ZO!%TQQO,5:UO;sQbO,5:XOOQ`<<IY<<IYO!%YQbO<<IYOOQ`<<Hi<<HiO!%_QbO<<HiO!%dQbO<<HiO!%lQbO<<HiOOQ`'#E`'#E`O!%wQbO<<IOO!&PQbO'#DwOOQ`<<IO<<IOO!&XQbO<<IOOOQ`<<H`<<H`OOQ`<<IZ<<IZO!&^QbO<<IZOOQO,5:x,5:xO!&cQbO<<HdOOQO-E8[-E8[O;sQbO1G/pOOQ`1G/s1G/sOOQ`AN>tAN>tOOQ`AN>TAN>TO!&pQbOAN>TO!&uQbOAN>TOOQ`-E8^-E8^OOQ`AN>jAN>jO!&}QbOAN>jO3YQbO,5:aO;sQbO,5:cOOQ`AN>uAN>uPJjQbO'#EXOOQ`7+%[7+%[OOQ`G23oG23oO!'SQbOG23oP!&SQbO'#DuOOQ`G24UG24UO!'XQQO1G/{OOQ`1G/}1G/}OOQ`LD)ZLD)ZO;sQbO7+%gOOQ`<<IR<<IRO!'^ObO,59sO!'oOpO'#DX", states: "?[QYQ!SOOOOQ!Q'#Ek'#EkO!sO!bO'#DXO%kQ!TO'#DdO&UOSO'#DaOOQ!R'#Da'#DaO)SQ!TO'#EnOOQ!Q'#E{'#E{O)pQRO'#DxO+xQ!TO'#EjO,fQ!SO'#DVOOQ!R'#Dz'#DzO/WQ!SO'#D{OOQ!R'#En'#EnO/_Q!TO'#EnO1cQ!TO'#EmO2qQ!TO'#EjO3OQRO'#ETOOQ!Q'#Ej'#EjO3gQ!SO'#EjO3nQrO'#EiOOQ!Q'#Ei'#EiOOQ!Q'#EV'#EVQYQ!SOOO4PQbO'#D]O4[QbO'#DrO5YQbO'#DSO6WQQO'#D}O5YQbO'#EPO6]QbO'#ERO6eObO,59sOOQ!Q'#D['#D[O6vQbO'#DqOOQ!Q'#Eq'#EqOOQ!Q'#E_'#E_O7QQ!SO,5:`OOQ!R'#Em'#EmO8QQbO'#DcO8`QWO'#DeOOOO'#Es'#EsOOOO'#E['#E[O8tOSO,59{OOQ!R,59{,59{O5YQbO,5:dO5YQbO,5:dO5YQbO,5:dO5YQbO,5:dO5YQbO,59pO5YQbO,59pO5YQbO,59pO5YQbO,59pOOQ!Q'#EX'#EXO,fQ!SO,59qO9SQ!TO'#DdO9^Q!TO'#EnO9hQsO,59qO9uQQO,59qO9zQrO,59qO:VQrO,59qO:eQsO,59qO;TQsO,59qO;[QrO'#DQO;dQ!SO,5:gO;kQrO,5:fOOQ!R,5:g,5:gO;yQ!SO,5:gO<WQbO,5:pO<WQbO,5:oOYQ!SO,5:hO=kQ!SO,59lOOQ!Q,5;T,5;TOYQ!SO'#EWO>]QQO'#EWOOQ!Q-E8T-E8TOOQ!Q'#EY'#EYO>bQbO'#D^O>mQbO'#D_OOQO'#EZ'#EZO>eQQO'#D^O?RQQO,59wO?WQcO'#EmO@TQRO'#EzOAQQRO'#EzOOQO'#Ez'#EzOAXQQO,5:^OA^QRO,59nOAeQRO,59nOYQ!SO,5:iOAsQ!TO,5:kOCXQ!TO,5:kOC{Q!TO,5:kODYQ!SO,5:mOOQ!Q'#Ec'#EcO6]QbO,5:mOOQ!R1G/_1G/_OOQ!Q,5:],5:]OOQ!Q-E8]-E8]OOOO'#Dd'#DdOOOO,59},59}OOOO,5:P,5:POOOO-E8Y-E8YOOQ!R1G/g1G/gOOQ!R1G0O1G0OOF_Q!TO1G0OOFiQ!TO1G0OOG}Q!TO1G0OOHXQ!TO1G0OOHfQ!TO1G0OOOQ!R1G/[1G/[OI}Q!TO1G/[OJUQ!TO1G/[OJ]Q!TO1G/[OKbQ!TO1G/[OJdQ!TO1G/[OOQ!Q-E8V-E8VOKxQsO1G/]OLVQQO1G/]OL[QrO1G/]OLgQrO1G/]OLuQsO1G/]OL|QsO1G/]OMTQ!SO,59rOM_QrO1G/]OOQ!R1G/]1G/]OMjQrO1G0QOOQ!R1G0R1G0ROMxQ!SO1G0ROOQp'#Ea'#EaOMjQrO1G0QOOQ!R1G0Q1G0QOOQ!Q'#Eb'#EbOMxQ!SO1G0RONVQ!SO1G0[ONwQ!SO1G0ZO! iQ!SO'#DlO! }Q!SO'#DlO!!_QbO1G0SOOQ!Q-E8U-E8UOYQ!SO,5:rOOQ!Q,5:r,5:rOYQ!SO,5:rOOQ!Q-E8W-E8WO!!jQQO,59xOOQO,59y,59yOOQO-E8X-E8XOYQ!SO1G/cOYQ!SO1G/xOYQ!SO1G/YO!!rQbO1G0TO!!}Q!SO1G0XO!#rQ!SO1G0XOOQ!Q-E8a-E8aO!#yQrO7+$wOOQ!R7+$w7+$wO!$UQrO1G/^O!$aQrO7+%lOOQ!R7+%l7+%lO!$oQ!SO7+%mOOQ!R7+%m7+%mOOQp-E8_-E8_OOQ!Q-E8`-E8`OOQ!Q'#E]'#E]O!$|QrO'#E]O!%[Q!SO'#EyOOQ`,5:W,5:WO!%lQbO'#DjO!%qQQO'#DmOOQ!Q7+%n7+%nO!%vQbO7+%nO!%{QbO7+%nOOQ!Q1G0^1G0^OYQ!SO1G0^O!&TQ!SO7+$}O!&fQ!SO7+$}O!&sQbO7+%dO!&{QbO7+$tOOQ!Q7+%o7+%oO!'QQbO7+%oO!'VQbO7+%oO!'_Q!SO7+%sOOQ!R<<Hc<<HcO!(SQ!SO7+$xO!(aQrO7+$xOOQ!R<<IW<<IWOOQ!R<<IX<<IXOOQ!Q,5:w,5:wOOQ!Q-E8Z-E8ZO!(lQQO,5:UOYQ!SO,5:XOOQ!Q<<IY<<IYO!(qQbO<<IYOOQ!Q7+%x7+%xOOQ!Q<<Hi<<HiO!(vQbO<<HiO!({QbO<<HiO!)TQbO<<HiOOQ`'#E`'#E`O!)`QbO<<IOO!)hQbO'#DwOOQ!Q<<IO<<IOO!)pQbO<<IOOOQ!Q<<H`<<H`OOQ!Q<<IZ<<IZO!)uQbO<<IZOOQp,5:x,5:xO!)zQ!SO<<HdOOQp-E8[-E8[OYQ!SO1G/pOOQ`1G/s1G/sOOQ!QAN>tAN>tOOQ!QAN>TAN>TO!*XQbOAN>TO!*^QbOAN>TOOQ`-E8^-E8^OOQ!QAN>jAN>jO!*fQbOAN>jO4[QbO,5:aOYQ!SO,5:cOOQ!QAN>uAN>uPMTQ!SO'#EXOOQ`7+%[7+%[OOQ!QG23oG23oO!*kQbOG23oP!)kQbO'#DuOOQ!QG24UG24UO!*pQQO1G/{OOQ`1G/}1G/}OOQ!QLD)ZLD)ZOYQ!SO7+%gOOQ`<<IR<<IRO!*uObO,59sO!+WO!bO'#DX",
stateData: "!'w~O#YOSrOS~OlQOm`On[OoPOpSOqgOwiO|[O}PO!YSO!Z[O![[O!ghO!m[O!rjO!tkO!vlO#_XO#`dO#cRO#nYO#oZO~O#amO~OlsOn[OoPOpSOqgO|[O}PO!SoO!YSO!Z[O![[O!dnO!m[O#_XO#cRO#nYO#oZOP#]XQ#]XR#]XS#]XT#]XU#]XW#]XX#]XY#]XZ#]X[#]X]#]X^#]Xd#]Xe#]Xf#]Xg#]Xh#]Xi#]Xj#]Xu!WX!]!WX#m!WX~O#`!WX#q!WX!_!WX!b!WX!c!WX!j!WX~P!uO!UvO#cyO#etO#fuO~OlsOn[OoPOpSOqgO|[O}PO!SoO!YSO!Z[O![[O!dnO!m[O#_XO#cRO#nYO#oZOP#^XQ#^XR#^XS#^XT#^XU#^XW#^XX#^XY#^XZ#^X[#^X]#^X^#^Xd#^Xe#^Xf#^Xg#^Xh#^Xi#^Xj#^Xu#^X#m#^X~O#`#^X#q#^X!]#^X!_#^X!b#^X!c#^X!j#^X~P&ZOP{OQ{OR|OS|OT!POU!QOW!OOX!OOY!OOZ!OO[!OO]!OO^zOd}Oe}Of}Og}Oh}Oi}Oj!RO~OP{OQ{OR|OS|Od}Oe}Of}Og}Oh}Oi}Ou#[X~O#`#[X#q#[X!_#[X!b#[X!c#[X#m#[X!j#[X~P*qOl!UOm`On[OoPOpSOqgOwiO|[O}PO!YSO!Z[O![[O!ghO!m[O!rjO!tkO!vlO#_XO#`!SO#cRO#nYO#oZO~OlsOn[OoPOpSO|[O}PO!SoO!YSO!Z[O![[O!m[O#_XO#`!SO#cRO#nYO#oZO~O#p!aO~P-gOV!cO#`#^X#q#^X!_#^X!b#^X!c#^X!j#^X~P'`OP#]XQ#]XR#]XS#]XT#]XU#]XW#]XX#]XY#]XZ#]X[#]X]#]X^#]Xd#]Xe#]Xf#]Xg#]Xh#]Xi#]Xj#]Xu#[X~O#`#[X#q#[X!_#[X!b#[X!c#[X#m#[X!j#[X~P/]Ou#[X#`#[X#q#[X!_#[X!b#[X!c#[X#m#[X!j#[X~OT!POU!QOj!RO~P1ZOV!cO_!dO`!dOa!dOb!dOc!dOk!dO~O!]!eO~P1ZOu!hO#`!gO#q!gO~Ol!jO!S!lO!]!QP~Ol!pOn[OoPOpSO|[O}PO!YSO!Z[O![[O!m[O#_XO#cRO#nYO#oZO~OlsOn[OoPOpSO|[O}PO!YSO!Z[O![[O!m[O#_XO#cRO#nYO#oZO~O!]!wO~Ol!jO!SoO~Ol#OOoPO|#OO}PO#_XO~OqgO!d#PO~P4WOqgO!SoO!dnOu!ha!]!ha#`!ha#q!ha#m!ha!_!ha!b!ha!c!ha!j!ha~P4WOl#ROo%xO}%xO#_XO~O#c#TO#e#TO#f#TO#g#TO#h#TO#i#TO~O!UvO#c#VO#etO#fuO~O#`!SO~P!uO#`!SO~P&ZO#`!SO#m#mO~P*qO#m#mO~O#m#mOu#[X~O!]!eO#m#mOu#[X~O#m#mO~P/]OT!POU!QOj!RO#`!SOu#[X~O#m#mO~P9TOu!hO~O#p#oO~P-gO!SoO#`#qO#p#sO~O#`#tO#p#oO~P4WOlQOm`On[OoPOpSOqgOwiO|[O}PO!YSO!Z[O![[O!ghO!m[O!rjO!tkO!vlO#_XO#cRO#nYO#oZO~O#`#yO~P:`Ou!hO#`ta#qta#mta!_ta!bta!cta!jta~Ol!jO!S!lO!]!QX~OpSO|$PO!YSO!Z$PO![$PO#cRO~O!]$RO~OqgO!SoO!dnOT#]XU#]XW#]XX#]XY#]XZ#]X[#]X]#]Xj#]X!]#]X~P4WOT!POU!QOj!RO!]#kX~OT!POU!QOW!OOX!OOY!OOZ!OO[!OO]!OOj!RO~O!]#kX~P>gO!]$SO~O!]$TO~P>gOT!POU!QOj!RO!]$TO~Ou!sa#`!sa#q!sa!_!sa!b!sa!c!sa#m!sa!j!sa~P)aOP{OQ{OR|OS|Od}Oe}Of}Og}Oh}Oi}O~Ou!sa#`!sa#q!sa!_!sa!b!sa!c!sa#m!sa!j!sa~P@eOT!POU!QOj!ROu!sa#`!sa#q!sa!_!sa!b!sa!c!sa#m!sa!j!sa~Ol!jO!SoOu!ua#`!ua#q!ua!_!ua!b!ua!c!ua#m!ua!j!ua~O^zOR!liS!lid!lie!lif!lig!lih!lii!liu!li#`!li#q!li#m!li!_!li!b!li!c!li!j!li~OP!liQ!li~PCYOP{OQ{O~PCYOP{OQ{Od!lie!lif!lig!lih!lii!liu!li#`!li#q!li#m!li!_!li!b!li!c!li!j!li~OR!liS!li~PDuOR|OS|O^zO~PDuOR|OS|O~PDuOW!OOX!OOY!OOZ!OO[!OO]!OOTxijxiuxi#`xi#qxi#mxi!]xi!_xi!bxi!cxi!jxi~OU!QO~PFlOU!QO~PGOOUxi~PFlOT!POU!QOjxiuxi#`xi#qxi#mxi!]xi!_xi!bxi!cxi!jxi~OW!OOX!OOY!OOZ!OO[!OO]!OO~PHYO#`!SO#m$ZO~P*qO#m$ZO~O#m$ZOu#[X~O!]!eO#m$ZOu#[X~O#m$ZO~P/]O#m$ZO~P9TOqgO!dnO~P-gO#`!SO#m$ZO~O!SoO#`#qO#p$^O~O#`#tO#p$`O~P4WOu!hO#`!xi#q!xi!_!xi!b!xi!c!xi#m!xi!j!xi~Ou!hO#`!wi#q!wi!_!wi!b!wi!c!wi#m!wi!j!wi~Ou!hO!_!`X!b!`X!c!`X!j!`X~O#`$cO!_#jP!b#jP!c#jP!j#jP~P:`O!_$gO!b$hO!c$iO~O!S!lO!]!Qa~O#`$mO~P:`O!_$gO!b$hO!c$pO~O!SoOu!ui#`!ui#q!ui!_!ui!b!ui!c!ui#m!ui!j!ui~Ol!jO~PNUO#`!SO#m$tO~O#`!SO#mzi~O!SoO#`#qO#p$wO~O#`#tO#p$xO~P4WOu!hO#`$yO~O#`$cO!_#jX!b#jX!c#jX!j#jX~P:`Ol${O~O!]$|O~O!c$}O~O!b$hO!c$}O~Ou!hO!_$gO!b$hO!c%PO~O#`$cO!_#jP!b#jP!c#jP~P:`O!c%WO!j%VO~O!c%YO~O!c%ZO~O!b$hO!c%ZO~O!SoOu!uq#`!uq#q!uq!_!uq!b!uq!c!uq#m!uq!j!uq~OqgO!dnO#mzq~P-gO#`!SO#mzq~O!]%`O~O!c%bO~O!c%cO~O!b$hO!c%cO~O!_$gO!b$hO!c%cO~O!c%gO!j%VO~O!]%jO!g%iO~O!c%gO~O!c%kO~OqgO!dnO#mzy~P-gO!c%nO~O!b$hO!c%nO~O!c%qO~O!c%tO~O!]%uO~Ol#OOo%xO|#OO}%xO#_XO~O#a%wO~O|!m~", stateData: "!+`~O#[OSrOS~OlROmaOn]OoQOpTOqhOwjO|]O}QO!YTO!Z]O![]O!giO!m]O!rkO!tlO!vmO#XPO#`PO#cYO#fSO#qZO#r[O~O#dnO~OltOn]OoQOpTOqhO|]O}QO!SpO!YTO!Z]O![]O!doO!m]O#cYO#fSO#qZO#r[OP#aXQ#aXR#aXS#aXT#aXU#aXW#aXX#aXY#aXZ#aX[#aX]#aX^#aXd#aXe#aXf#aXg#aXh#aXi#aXj#aXu!WX!]!WX#Y!WX#p!WX~O#X!WX#`!WX#t!WX!_!WX!b!WX!c!WX!j!WX~P!xO!UwO#fzO#huO#ivO~OltOn]OoQOpTOqhO|]O}QO!SpO!YTO!Z]O![]O!doO!m]O#cYO#fSO#qZO#r[OP#bXQ#bXR#bXS#bXT#bXU#bXW#bXX#bXY#bXZ#bX[#bX]#bX^#bXd#bXe#bXf#bXg#bXh#bXi#bXj#bXu#bX#Y#bX#p#bX~O#X#bX#`#bX#t#bX!]#bX!_#bX!b#bX!c#bX!j#bX~P&dOP|OQ|OR}OS}OT!QOU!ROW!POX!POY!POZ!PO[!PO]!PO^{Od!OOe!OOf!OOg!OOh!OOi!OOj!SO~OP|OQ|OR}OS}Od!OOe!OOf!OOg!OOh!OOi!OOu#^X#Y#^X~O#X#^X#`#^X#t#^X!_#^X!b#^X!c#^X#p#^X!j#^X~P+QOl!VOmaOn]OoQOpTOqhOwjO|]O}QO!YTO!Z]O![]O!giO!m]O!rkO!tlO!vmO#XPO#`PO#cYO#fSO#qZO#r[O~OltOn]OoQOpTO|]O}QO!SpO!YTO!Z]O![]O!m]O#XPO#`PO#cYO#fSO#qZO#r[O~O#s!bO~P.POV!dO#X#bX#`#bX#t#bX!_#bX!b#bX!c#bX!j#bX~P'iOP#aXQ#aXR#aXS#aXT#aXU#aXW#aXX#aXY#aXZ#aX[#aX]#aX^#aXd#aXe#aXf#aXg#aXh#aXi#aXj#aXu#^X#Y#^X~O#X#^X#`#^X#t#^X!_#^X!b#^X!c#^X#p#^X!j#^X~P/{Ou#^X#X#^X#Y#^X#`#^X#t#^X!_#^X!b#^X!c#^X#p#^X!j#^X~OT!QOU!ROj!SO~P2POV!dO_!eO`!eOa!eOb!eOc!eOk!eO~O!]!fO~P2POu!iO#XPO#Y!jO#`PO#t!hO~Ol!lO!S!nO!]!QP~Ol!rOn]OoQOpTO|]O}QO!YTO!Z]O![]O!m]O#cYO#fSO#qZO#r[O~OltOn]OoQOpTO|]O}QO!YTO!Z]O![]O!m]O#cYO#fSO#qZO#r[O~O!]!yO~Ol!lO!SpO~Ol#QOoQO|#QO}QO#cYO~OqhO!d#RO~P5YOqhO!SpO!doOu!ha!]!ha#X!ha#Y!ha#`!ha#t!ha#p!ha!_!ha!b!ha!c!ha!j!ha~P5YOl#TOo&PO}&PO#cYO~O#f#VO#h#VO#i#VO#j#VO#k#VO#l#VO~O!UwO#f#XO#huO#ivO~O#XPO#`PO~P!xO#XPO#`PO~P&dO#XPO#`PO#p#oO~P+QO#p#oO~O#p#oOu#^X#Y#^X~O!]!fO#p#oOu#^X#Y#^X~O#p#oO~P/{OT!QOU!ROj!SO#XPO#`POu#^X#Y#^X~O#p#oO~P:lOu!iO#Y!jO~O#s#qO~P.PO!SpO#XPO#`PO#s#uO~O#XPO#`PO#s#qO~P5YOlROmaOn]OoQOpTOqhOwjO|]O}QO!YTO!Z]O![]O!giO!m]O!rkO!tlO!vmO#cYO#fSO#qZO#r[O~Ou!iO#Y!jO#Xta#`ta#tta#pta!_ta!bta!cta!jta~Ou$QO~Ol!lO!S!nO!]!QX~OpTO|$TO!YTO!Z$TO![$TO#fSO~O!]$VO~OqhO!SpO!doOT#aXU#aXW#aXX#aXY#aXZ#aX[#aX]#aXj#aX!]#aX~P5YOT!QOU!ROj!SO!]#nX~OT!QOU!ROW!POX!POY!POZ!PO[!PO]!POj!SO~O!]#nX~P@cO!]$WO~O!]$XO~P@cOT!QOU!ROj!SO!]$XO~Ou!sa#X!sa#Y!sa#`!sa#t!sa!_!sa!b!sa!c!sa#p!sa!j!sa~P)pOu!sa#X!sa#Y!sa#`!sa#t!sa!_!sa!b!sa!c!sa#p!sa!j!sa~OP|OQ|OR}OS}Od!OOe!OOf!OOg!OOh!OOi!OO~PBgOT!QOU!ROj!SO~PBgOl!lO!SpOu!ua#X!ua#Y!ua#`!ua#t!ua!_!ua!b!ua!c!ua#p!ua!j!ua~O^{OR!liS!lid!lie!lif!lig!lih!lii!liu!li#X!li#Y!li#`!li#t!li#p!li!_!li!b!li!c!li!j!li~OP!liQ!li~PEQOP|OQ|O~PEQOP|OQ|Od!lie!lif!lig!lih!lii!liu!li#X!li#Y!li#`!li#t!li#p!li!_!li!b!li!c!li!j!li~OR!liS!li~PFsOR}OS}O^{O~PFsOR}OS}O~PFsOW!POX!POY!POZ!PO[!PO]!POTxijxiuxi#Xxi#Yxi#`xi#txi#pxi!]xi!_xi!bxi!cxi!jxi~OU!RO~PHpOU!RO~PISOUxi~PHpOT!QOU!ROjxiuxi#Xxi#Yxi#`xi#txi#pxi!]xi!_xi!bxi!cxi!jxi~OW!POX!POY!POZ!PO[!PO]!PO~PJdO#XPO#`PO#p$_O~P+QO#p$_O~O#p$_Ou#^X#Y#^X~O!]!fO#p$_Ou#^X#Y#^X~O#p$_O~P/{O#p$_O~P:lOqhO!doO~P.PO#XPO#`PO#p$_O~O!SpO#XPO#`PO#s$bO~O#XPO#`PO#s$dO~P5YOu!iO#Y!jO#X!xi#`!xi#t!xi!_!xi!b!xi!c!xi#p!xi!j!xi~Ou!iO#Y!jO#X!wi#`!wi#t!wi!_!wi!b!wi!c!wi#p!wi!j!wi~Ou!iO#Y!jO!_!`X!b!`X!c!`X!j!`X~O!_#mP!b#mP!c#mP!j#mP~PYO!_$kO!b$lO!c$mO~O!S!nO!]!Qa~O!_$kO!b$lO!c$vO~O!SpOu!ui#X!ui#Y!ui#`!ui#t!ui!_!ui!b!ui!c!ui#p!ui!j!ui~Ol!lO~P!!}O#XPO#`PO#p$zO~O#XPO#`PO#pzi~O!SpO#XPO#`PO#s$}O~O#XPO#`PO#s%OO~P5YOu!iO#XPO#Y!jO#`PO~O!_#mX!b#mX!c#mX!j#mX~PYOl%RO~O!]%SO~O!c%TO~O!b$lO!c%TO~Ou!iO!_$kO!b$lO!c%WO#Y!jO~O!_#mP!b#mP!c#mP~PYO!c%_O!j%^O~O!c%aO~O!c%bO~O!b$lO!c%bO~O!SpOu!uq#X!uq#Y!uq#`!uq#t!uq!_!uq!b!uq!c!uq#p!uq!j!uq~OqhO!doO#pzq~P.PO#XPO#`PO#pzq~O!]%gO~O!c%iO~O!c%jO~O!b$lO!c%jO~O!_$kO!b$lO!c%jO~O!c%nO!j%^O~O!]%qO!g%pO~O!c%nO~O!c%rO~OqhO!doO#pzy~P.PO!c%uO~O!b$lO!c%uO~O!c%xO~O!c%{O~O!]%|O~Ol#QOo&PO|#QO}&PO#cYO~O#d&OO~O|!m~",
goto: "9g#mPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP#nP$XP$n%l&{'RPP(d(p)j)mP)sP*z+O*zPPPP+hP+t,^PPP,t#nP-f.PP.T.ZP/Q0U$X$XP$XP$XP$X$X1[1b1n2b2p2z3Q3X3_3i3o3y4TPPP4c4g5[7QPPP8[P8lPPPPP8p8v8|raOf!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uQ!YXR#g!TwaOXf!T!c!d!e!h!w#y$R$S$T$e$m$|%`%j%ur_Of!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uQ!]XS!qh%iQ!viQ!zkQ#^!QQ#`!PQ#c!RR#j!TvTOfh!c!d!e!h!w#y$R$S$T$e$m$|%`%i%j%u!W[QTZikorz{|}!O!P!Q!R!U!V!_!b!p#k#p#u$_$u%^%lS!VX!TS#Om%wR#StQ!XXR#f!TrQOf!c!d!e!h!w#y$R$S$T$e$m$|%`%j%u!WsQTZikorz{|}!O!P!Q!R!U!V!_!b!p#k#p#u$_$u%^%lS!UX!TS!ph%iS#Om%wR#RtepQTr!U!V!p#k$u%^%lraOf!c!d!e!h!w#y$R$S$T$e$m$|%`%j%udnQTr!U!V!p#k$u%^%lQ!YXQ#PoR#g!TR!ogX!mg!k!n$O#S[OQTXZfhikorz{|}!O!P!Q!R!T!U!V!_!b!c!d!e!h!p!w#k#p#u#y$R$S$T$_$e$m$u$|%^%`%i%j%l%uR$P!lTvRxvUOXf!T!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uR#StQ$k#zQ$r$UQ%R$lR%e%SQ#z!eQ$U!wQ$n$SQ$o$TQ%a$|Q%m%`Q%s%jR%v%uQ$j#zQ$q$UQ%O$kQ%Q$lQ%[$rS%d%R%SR%o%edpQTr!U!V!p#k$u%^%lQ!`Z[!|l!{!}$V$W$sQ#n!_X#q!`#n#r$]vUOXf!T!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uT!sh%iT%T$n%UQ%X$nR%h%UrWOf!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uQ!WXQ!ykQ#W{Q#Z|Q#]}R#e!T#T[OQTXZfhikorz{|}!O!P!Q!R!T!U!V!_!b!c!d!e!h!p!w#k#p#u#y$R$S$T$_$e$m$u$|%^%`%i%j%l%u![[QTZhikorz{|}!O!P!Q!R!U!V!_!b!p#k#p#u$_$u%^%i%lw]OXf!T!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uQfOR!if^!fc!^#v#w#x$d$lR#{!fQ!TXQ!_Z`#d!T!_#k#l$Y$u%^%lS#k!U!VS#l!W!]S$Y#e#jQ$u$[R%^$vQ!kgQ!{lU#}!k!{$WR$W!}Q!ngQ$O!kT$Q!n$OQxRR#UxS$e#y$mR$z$eQ$v$[R%_$vYrQT!U!V!pR#QrQ%U$nR%f%UQ#r!`Q$]#nT$a#r$]Q#u!bQ$_#pT$b#u$_Q!}lQ$V!{U$X!}$V$sR$s$WTeOfScOfS!^X!TQ#v!cQ#w!d`#x!e!w$S$T$|%`%j%uQ#|!hU$d#y$e$mR$l$RvVOXf!T!c!d!e!h!w#y$R$S$T$e$m$|%`%j%udnQTr!U!V!p#k$u%^%lQ!bZS!rh%iQ!uiQ!xkQ#PoQ#WzQ#X{Q#Y|Q#[}Q#^!OQ#_!PQ#a!QQ#b!RQ#p!_X#t!b#p#u$_r^Of!c!d!e!h!w#y$R$S$T$e$m$|%`%j%u![sQTZhikorz{|}!O!P!Q!R!U!V!_!b!p#k#p#u$_$u%^%i%lQ![XR#i!T[qQTr!U!V!pQ$[#kV%]$u%^%lTwRxQ$f#yR%S$mQ!thR%r%irbOf!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uQ!ZXR#h!T", goto: "<[#pPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP#qP$_P$w%x'['bPP(v)S*P*SP*YP+d+h+dPPPP,TP,a,yPPP-a#qP.R.oP.s.yP/s0z$_$_P$_P$_P$_$_2T2Z2g3c3q3{4R4Y4`4j4p4z5UPPPPP5d5h6dP7v9oPP:|P;^PPPPP;b;h;nxbOg!d!e!f!i!y#{$O$Q$V$W$X$i$q$s%S%g%q%|Q!ZYR#i!U}bOYg!U!d!e!f!i!y#{$O$Q$V$W$X$i$q$s%S%g%q%|x`Og!d!e!f!i!y#{$O$Q$V$W$X$i$q$s%S%g%q%|Q!^YS!si%pQ!xjQ!|lQ#`!RQ#b!QQ#e!SR#l!U|UOgi!d!e!f!i!y#{$O$Q$V$W$X$i$q$s%S%g%p%q%|!W]RU[jlps{|}!O!P!Q!R!S!V!W!`!c!r#m#r#w$c${%e%sS!WY!US#Qn&OR#UuQ!YYR#h!UxROg!d!e!f!i!y#{$O$Q$V$W$X$i$q$s%S%g%q%|!WtRU[jlps{|}!O!P!Q!R!S!V!W!`!c!r#m#r#w$c${%e%sS!VY!US!ri%pS#Qn&OR#TueqRUs!V!W!r#m${%e%sxbOg!d!e!f!i!y#{$O$Q$V$W$X$i$q$s%S%g%q%|doRUs!V!W!r#m${%e%sQ!ZYQ#RpR#i!UR!qhX!oh!m!p$S#Y]ORUY[gijlps{|}!O!P!Q!R!S!U!V!W!`!c!d!e!f!i!r!y#m#r#w#{$O$Q$V$W$X$c$i$q$s${%S%e%g%p%q%s%|R$T!nTwSy|VOYg!U!d!e!f!i!y#{$O$Q$V$W$X$i$q$s%S%g%q%|R#UuQ$o#|Q$x$YQ%Y$rR%l%ZQ#|!fQ$Y!yQ$t$WQ$u$XQ%h%SQ%t%gQ%z%qR%}%|Q$n#|Q$w$YQ%U$oQ%X$rQ%c$xS%k%Y%ZR%v%ldqRUs!V!W!r#m${%e%sQ!a[[#Om!}#P$Z$[$yQ#p!`X#s!a#p#t$a|VOYg!U!d!e!f!i!y#{$O$Q$V$W$X$i$q$s%S%g%q%|T!ui%pT%[$t%]Q%`$tR%o%]xXOg!d!e!f!i!y#{$O$Q$V$W$X$i$q$s%S%g%q%|Q!XYQ!{lQ#Y|Q#]}Q#_!OR#g!U#Z]ORUY[gijlps{|}!O!P!Q!R!S!U!V!W!`!c!d!e!f!i!r!y#m#r#w#{$O$Q$V$W$X$c$i$q$s${%S%e%g%p%q%s%|![]RU[ijlps{|}!O!P!Q!R!S!V!W!`!c!r#m#r#w$c${%e%p%s}^OYg!U!d!e!f!i!y#{$O$Q$V$W$X$i$q$s%S%g%q%|QgOR!kg^!gd!_#x#y#z$h$rR#}!gQ!UYQ!`[d#f!U!`#m#n$O$^$q${%e%sS#m!V!WS#n!X!^Q$O!iS$^#g#lQ$q$QQ${$`R%e$|Q!mhQ!}mU$R!m!}$[R$[#PQ!phQ$S!mT$U!p$SQySR#WyS$i#{$sR%Q$iQ$|$`R%f$|YsRU!V!W!rR#SsQ%]$tR%m%]Q#t!aQ$a#pT$e#t$aQ#w!cQ$c#rT$f#w$cQ#PmQ$Z!}U$]#P$Z$yR$y$[TfOgSdOgS!_Y!UQ#x!dQ#y!e`#z!f!y$W$X%S%g%q%|Q$P!iU$h#{$i$sS$p$O$QQ$r$VR%V$qSeOg|!TY[!U!V!W!X!^!`!i#g#l#m#n$O$Q$^$`$q${$|%e%sQ!hdW#s!a#p#t$aW#v!c#r#w$c`#{!f!y$W$X%S%g%q%|U$g#{$i$sQ$s$VR%P$h|WOYg!U!d!e!f!i!y#{$O$Q$V$W$X$i$q$s%S%g%q%|doRUs!V!W!r#m${%e%sQ!c[S!ti%pQ!wjQ!zlQ#RpQ#Y{Q#Z|Q#[}Q#^!OQ#`!PQ#a!QQ#c!RQ#d!SQ#r!`X#v!c#r#w$cx_Og!d!e!f!i!y#{$O$Q$V$W$X$i$q$s%S%g%q%|![tRU[ijlps{|}!O!P!Q!R!S!V!W!`!c!r#m#r#w$c${%e%p%sQ!]YR#k!U[rRUs!V!W!rQ$`#mV%d${%e%sTxSyQ$j#{R%Z$sQ!viR%y%pxcOg!d!e!f!i!y#{$O$Q$V$W$X$i$q$s%S%g%q%|Q![YR#j!U",
nodeNames: "⚠ Star Slash Plus Minus And Or Eq EqEq Neq Lt Lte Gt Gte Modulo PlusEq MinusEq StarEq SlashEq ModuloEq Band Bor Bxor Shl Shr Ushr NullishCoalesce NullishEq Identifier AssignableIdentifier Word IdentifierBeforeDot CurlyString Do Comment Program PipeExpr operator WhileExpr keyword ConditionalOp ParenExpr FunctionCall DotGet Number Dollar PositionalArg FunctionDef Params NamedParam NamedArgPrefix String StringFragment Interpolation FunctionCallOrIdentifier EscapeSeq DoubleQuote Boolean Null colon CatchExpr keyword Block FinallyExpr keyword keyword Underscore NamedArg IfExpr keyword FunctionCall ElseIfExpr keyword ElseExpr BinOp Regex Dict Array FunctionCallWithBlock TryExpr keyword Throw keyword Import keyword CompoundAssign Assign", nodeNames: "⚠ Star Slash Plus Minus And Or Eq EqEq Neq Lt Lte Gt Gte Modulo PlusEq MinusEq StarEq SlashEq ModuloEq Band Bor Bxor Shl Shr Ushr NullishCoalesce NullishEq Identifier AssignableIdentifier Word IdentifierBeforeDot CurlyString Do Comment Program PipeExpr operator WhileExpr keyword ConditionalOp ParenExpr FunctionCall DotGet Number Dollar PositionalArg FunctionDef Params NamedParam NamedArgPrefix String StringFragment Interpolation FunctionCallOrIdentifier EscapeSeq DoubleQuote Boolean Null colon CatchExpr keyword Block FinallyExpr keyword keyword Underscore NamedArg IfExpr keyword FunctionCall ElseIfExpr keyword ElseExpr BinOp Regex Dict Array FunctionCallWithBlock TryExpr keyword Throw keyword Import keyword CompoundAssign Assign",
maxTerm: 125, maxTerm: 128,
context: trackScope, context: trackScope,
nodeProps: [ nodeProps: [
["closedBy", 59,"end"] ["closedBy", 59,"end"]
@ -19,9 +19,9 @@ export const parser = LRParser.deserialize({
propSources: [highlighting], propSources: [highlighting],
skippedNodes: [0,34], skippedNodes: [0,34],
repeatNodeCount: 13, repeatNodeCount: 13,
tokenData: "Ls~R!OOX$RXY$pYZ%ZZp$Rpq$pqr$Rrs%tst'ztu)cuw$Rwx)jxy)oyz*Yz{$R{|*s|}$R}!O*s!O!P$R!P!Q4`!Q!R+e!R![.Y![!]<{!]!^%Z!^!}$R!}#O=f#O#P?[#P#Q?a#Q#R$R#R#S?z#S#T$R#T#Y@e#Y#ZBP#Z#b@e#b#cGm#c#f@e#f#gHp#g#h@e#h#iIs#i#o@e#o#p$R#p#qLT#q;'S$R;'S;=`$j<%l~$R~O$R~~LnS$WU!USOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RS$mP;=`<%l$R^$wU!US#YYOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU%bU!US#`QOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU%yZ!USOr%trs&lst%ttu'Vuw%twx'Vx#O%t#O#P'V#P;'S%t;'S;=`'t<%lO%tU&sU!YQ!USOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RQ'YTOr'Vrs'is;'S'V;'S;=`'n<%lO'VQ'nO!YQQ'qP;=`<%l'VU'wP;=`<%l%t^(RZrY!USOY'zYZ$RZt'ztu(tuw'zwx(tx#O'z#O#P(t#P;'S'z;'S;=`)]<%lO'zY(ySrYOY(tZ;'S(t;'S;=`)V<%lO(tY)YP;=`<%l(t^)`P;=`<%l'z^)jO#e[}Q~)oO#c~U)vU!US#_QOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU*aU!US#mQOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU*xX!USOt$Ruw$Rx!Q$R!Q!R+e!R![.Y![#O$R#P;'S$R;'S;=`$j<%lO$RU+lb!US|QOt$Ruw$Rx!O$R!O!P,t!P!Q$R!Q![.Y![#O$R#P#R$R#R#S/V#S#U$R#U#V/t#V#c$R#c#d1Y#d#l$R#l#m2h#m;'S$R;'S;=`$j<%lO$RU,yW!USOt$Ruw$Rx!Q$R!Q![-c![#O$R#P;'S$R;'S;=`$j<%lO$RU-jY!US|QOt$Ruw$Rx!Q$R!Q![-c![#O$R#P#R$R#R#S,t#S;'S$R;'S;=`$j<%lO$RU.a[!US|QOt$Ruw$Rx!O$R!O!P,t!P!Q$R!Q![.Y![#O$R#P#R$R#R#S/V#S;'S$R;'S;=`$j<%lO$RU/[W!USOt$Ruw$Rx!Q$R!Q![.Y![#O$R#P;'S$R;'S;=`$j<%lO$RU/yX!USOt$Ruw$Rx!Q$R!Q!R0f!R!S0f!S#O$R#P;'S$R;'S;=`$j<%lO$RU0mX!US|QOt$Ruw$Rx!Q$R!Q!R0f!R!S0f!S#O$R#P;'S$R;'S;=`$j<%lO$RU1_W!USOt$Ruw$Rx!Q$R!Q!Y1w!Y#O$R#P;'S$R;'S;=`$j<%lO$RU2OW!US|QOt$Ruw$Rx!Q$R!Q!Y1w!Y#O$R#P;'S$R;'S;=`$j<%lO$RU2m[!USOt$Ruw$Rx!Q$R!Q![3c![!c$R!c!i3c!i#O$R#P#T$R#T#Z3c#Z;'S$R;'S;=`$j<%lO$RU3j[!US|QOt$Ruw$Rx!Q$R!Q![3c![!c$R!c!i3c!i#O$R#P#T$R#T#Z3c#Z;'S$R;'S;=`$j<%lO$RU4eW!USOt$Ruw$Rx!P$R!P!Q4}!Q#O$R#P;'S$R;'S;=`$j<%lO$RU5S^!USOY6OYZ$RZt6Otu7Ruw6Owx7Rx!P6O!P!Q$R!Q!}6O!}#O;t#O#P9a#P;'S6O;'S;=`<u<%lO6OU6V^!US!mQOY6OYZ$RZt6Otu7Ruw6Owx7Rx!P6O!P!Q9v!Q!}6O!}#O;t#O#P9a#P;'S6O;'S;=`<u<%lO6OQ7WX!mQOY7RZ!P7R!P!Q7s!Q!}7R!}#O8b#O#P9a#P;'S7R;'S;=`9p<%lO7RQ7vP!P!Q7yQ8OU!mQ#Z#[7y#]#^7y#a#b7y#g#h7y#i#j7y#m#n7yQ8eVOY8bZ#O8b#O#P8z#P#Q7R#Q;'S8b;'S;=`9Z<%lO8bQ8}SOY8bZ;'S8b;'S;=`9Z<%lO8bQ9^P;=`<%l8bQ9dSOY7RZ;'S7R;'S;=`9p<%lO7RQ9sP;=`<%l7RU9{W!USOt$Ruw$Rx!P$R!P!Q:e!Q#O$R#P;'S$R;'S;=`$j<%lO$RU:lb!US!mQOt$Ruw$Rx#O$R#P#Z$R#Z#[:e#[#]$R#]#^:e#^#a$R#a#b:e#b#g$R#g#h:e#h#i$R#i#j:e#j#m$R#m#n:e#n;'S$R;'S;=`$j<%lO$RU;y[!USOY;tYZ$RZt;ttu8buw;twx8bx#O;t#O#P8z#P#Q6O#Q;'S;t;'S;=`<o<%lO;tU<rP;=`<%l;tU<xP;=`<%l6OU=SU!US!]QOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU=mW#oQ!USOt$Ruw$Rx!_$R!_!`>V!`#O$R#P;'S$R;'S;=`$j<%lO$RU>[V!USOt$Ruw$Rx#O$R#P#Q>q#Q;'S$R;'S;=`$j<%lO$RU>xU#nQ!USOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$R~?aO#f~U?hU#pQ!USOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU@RU!US!dQOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU@j^!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#o@e#o;'S$R;'S;=`$j<%lO$RUAmU!SQ!USOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RUBU_!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#UCT#U#o@e#o;'S$R;'S;=`$j<%lO$RUCY`!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#`@e#`#aD[#a#o@e#o;'S$R;'S;=`$j<%lO$RUDa`!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#g@e#g#hEc#h#o@e#o;'S$R;'S;=`$j<%lO$RUEh`!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#X@e#X#YFj#Y#o@e#o;'S$R;'S;=`$j<%lO$RUFq^!ZQ!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#o@e#o;'S$R;'S;=`$j<%lO$R^Gt^#gW!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#o@e#o;'S$R;'S;=`$j<%lO$R^Hw^#iW!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#o@e#o;'S$R;'S;=`$j<%lO$R^Iz`#hW!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#f@e#f#gJ|#g#o@e#o;'S$R;'S;=`$j<%lO$RUKR`!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#i@e#i#jEc#j#o@e#o;'S$R;'S;=`$j<%lO$RUL[UuQ!USOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$R~LsO#q~", tokenData: "Lp~R}OX$OXY$mYp$Opq$mqr$Ors%Wst'^tu(uuw$Owx(|xy)Ryz)lz{$O{|*V|}$O}!O*V!O!P$O!P!Q3r!Q!R*w!R![-l![!]<_!]!^<x!^!}$O!}#O=c#O#P?X#P#Q?^#Q#R$O#R#S?w#S#T$O#T#Y@b#Y#ZA|#Z#b@b#b#cGj#c#f@b#f#gHm#g#h@b#h#iIp#i#o@b#o#p$O#p#qLQ#q;'S$O;'S;=`$g<%l~$O~O$O~~LkS$TU!USOt$Ouw$Ox#O$O#P;'S$O;'S;=`$g<%lO$OS$jP;=`<%l$O^$tU!US#[YOt$Ouw$Ox#O$O#P;'S$O;'S;=`$g<%lO$OU%]Z!USOr%Wrs&Ost%Wtu&iuw%Wwx&ix#O%W#O#P&i#P;'S%W;'S;=`'W<%lO%WU&VU!YQ!USOt$Ouw$Ox#O$O#P;'S$O;'S;=`$g<%lO$OQ&lTOr&irs&{s;'S&i;'S;=`'Q<%lO&iQ'QO!YQQ'TP;=`<%l&iU'ZP;=`<%l%W^'eZrY!USOY'^YZ$OZt'^tu(Wuw'^wx(Wx#O'^#O#P(W#P;'S'^;'S;=`(o<%lO'^Y(]SrYOY(WZ;'S(W;'S;=`(i<%lO(WY(lP;=`<%l(W^(rP;=`<%l'^^(|O#h[}Q~)RO#f~U)YU!US#cQOt$Ouw$Ox#O$O#P;'S$O;'S;=`$g<%lO$OU)sU!US#pQOt$Ouw$Ox#O$O#P;'S$O;'S;=`$g<%lO$OU*[X!USOt$Ouw$Ox!Q$O!Q!R*w!R![-l![#O$O#P;'S$O;'S;=`$g<%lO$OU+Ob!US|QOt$Ouw$Ox!O$O!O!P,W!P!Q$O!Q![-l![#O$O#P#R$O#R#S.i#S#U$O#U#V/W#V#c$O#c#d0l#d#l$O#l#m1z#m;'S$O;'S;=`$g<%lO$OU,]W!USOt$Ouw$Ox!Q$O!Q![,u![#O$O#P;'S$O;'S;=`$g<%lO$OU,|Y!US|QOt$Ouw$Ox!Q$O!Q![,u![#O$O#P#R$O#R#S,W#S;'S$O;'S;=`$g<%lO$OU-s[!US|QOt$Ouw$Ox!O$O!O!P,W!P!Q$O!Q![-l![#O$O#P#R$O#R#S.i#S;'S$O;'S;=`$g<%lO$OU.nW!USOt$Ouw$Ox!Q$O!Q![-l![#O$O#P;'S$O;'S;=`$g<%lO$OU/]X!USOt$Ouw$Ox!Q$O!Q!R/x!R!S/x!S#O$O#P;'S$O;'S;=`$g<%lO$OU0PX!US|QOt$Ouw$Ox!Q$O!Q!R/x!R!S/x!S#O$O#P;'S$O;'S;=`$g<%lO$OU0qW!USOt$Ouw$Ox!Q$O!Q!Y1Z!Y#O$O#P;'S$O;'S;=`$g<%lO$OU1bW!US|QOt$Ouw$Ox!Q$O!Q!Y1Z!Y#O$O#P;'S$O;'S;=`$g<%lO$OU2P[!USOt$Ouw$Ox!Q$O!Q![2u![!c$O!c!i2u!i#O$O#P#T$O#T#Z2u#Z;'S$O;'S;=`$g<%lO$OU2|[!US|QOt$Ouw$Ox!Q$O!Q![2u![!c$O!c!i2u!i#O$O#P#T$O#T#Z2u#Z;'S$O;'S;=`$g<%lO$OU3wW!USOt$Ouw$Ox!P$O!P!Q4a!Q#O$O#P;'S$O;'S;=`$g<%lO$OU4f^!USOY5bYZ$OZt5btu6euw5bwx6ex!P5b!P!Q$O!Q!}5b!}#O;W#O#P8s#P;'S5b;'S;=`<X<%lO5bU5i^!US!mQOY5bYZ$OZt5btu6euw5bwx6ex!P5b!P!Q9Y!Q!}5b!}#O;W#O#P8s#P;'S5b;'S;=`<X<%lO5bQ6jX!mQOY6eZ!P6e!P!Q7V!Q!}6e!}#O7t#O#P8s#P;'S6e;'S;=`9S<%lO6eQ7YP!P!Q7]Q7bU!mQ#Z#[7]#]#^7]#a#b7]#g#h7]#i#j7]#m#n7]Q7wVOY7tZ#O7t#O#P8^#P#Q6e#Q;'S7t;'S;=`8m<%lO7tQ8aSOY7tZ;'S7t;'S;=`8m<%lO7tQ8pP;=`<%l7tQ8vSOY6eZ;'S6e;'S;=`9S<%lO6eQ9VP;=`<%l6eU9_W!USOt$Ouw$Ox!P$O!P!Q9w!Q#O$O#P;'S$O;'S;=`$g<%lO$OU:Ob!US!mQOt$Ouw$Ox#O$O#P#Z$O#Z#[9w#[#]$O#]#^9w#^#a$O#a#b9w#b#g$O#g#h9w#h#i$O#i#j9w#j#m$O#m#n9w#n;'S$O;'S;=`$g<%lO$OU;][!USOY;WYZ$OZt;Wtu7tuw;Wwx7tx#O;W#O#P8^#P#Q5b#Q;'S;W;'S;=`<R<%lO;WU<UP;=`<%l;WU<[P;=`<%l5bU<fU!US!]QOt$Ouw$Ox#O$O#P;'S$O;'S;=`$g<%lO$OU=PU!US#`QOt$Ouw$Ox#O$O#P;'S$O;'S;=`$g<%lO$OU=jW#rQ!USOt$Ouw$Ox!_$O!_!`>S!`#O$O#P;'S$O;'S;=`$g<%lO$OU>XV!USOt$Ouw$Ox#O$O#P#Q>n#Q;'S$O;'S;=`$g<%lO$OU>uU#qQ!USOt$Ouw$Ox#O$O#P;'S$O;'S;=`$g<%lO$O~?^O#i~U?eU#sQ!USOt$Ouw$Ox#O$O#P;'S$O;'S;=`$g<%lO$OU@OU!US!dQOt$Ouw$Ox#O$O#P;'S$O;'S;=`$g<%lO$OU@g^!USOt$Ouw$Ox}$O}!O@b!O!Q$O!Q![@b![!_$O!_!`Ac!`#O$O#P#T$O#T#o@b#o;'S$O;'S;=`$g<%lO$OUAjU!SQ!USOt$Ouw$Ox#O$O#P;'S$O;'S;=`$g<%lO$OUBR_!USOt$Ouw$Ox}$O}!O@b!O!Q$O!Q![@b![!_$O!_!`Ac!`#O$O#P#T$O#T#UCQ#U#o@b#o;'S$O;'S;=`$g<%lO$OUCV`!USOt$Ouw$Ox}$O}!O@b!O!Q$O!Q![@b![!_$O!_!`Ac!`#O$O#P#T$O#T#`@b#`#aDX#a#o@b#o;'S$O;'S;=`$g<%lO$OUD^`!USOt$Ouw$Ox}$O}!O@b!O!Q$O!Q![@b![!_$O!_!`Ac!`#O$O#P#T$O#T#g@b#g#hE`#h#o@b#o;'S$O;'S;=`$g<%lO$OUEe`!USOt$Ouw$Ox}$O}!O@b!O!Q$O!Q![@b![!_$O!_!`Ac!`#O$O#P#T$O#T#X@b#X#YFg#Y#o@b#o;'S$O;'S;=`$g<%lO$OUFn^!ZQ!USOt$Ouw$Ox}$O}!O@b!O!Q$O!Q![@b![!_$O!_!`Ac!`#O$O#P#T$O#T#o@b#o;'S$O;'S;=`$g<%lO$O^Gq^#jW!USOt$Ouw$Ox}$O}!O@b!O!Q$O!Q![@b![!_$O!_!`Ac!`#O$O#P#T$O#T#o@b#o;'S$O;'S;=`$g<%lO$O^Ht^#lW!USOt$Ouw$Ox}$O}!O@b!O!Q$O!Q![@b![!_$O!_!`Ac!`#O$O#P#T$O#T#o@b#o;'S$O;'S;=`$g<%lO$O^Iw`#kW!USOt$Ouw$Ox}$O}!O@b!O!Q$O!Q![@b![!_$O!_!`Ac!`#O$O#P#T$O#T#f@b#f#gJy#g#o@b#o;'S$O;'S;=`$g<%lO$OUKO`!USOt$Ouw$Ox}$O}!O@b!O!Q$O!Q![@b![!_$O!_!`Ac!`#O$O#P#T$O#T#i@b#i#jE`#j#o@b#o;'S$O;'S;=`$g<%lO$OULXUuQ!USOt$Ouw$Ox#O$O#P;'S$O;'S;=`$g<%lO$O~LpO#t~",
tokenizers: [operatorTokenizer, 1, 2, 3, tokenizer, new LocalTokenGroup("[~RP!O!PU~ZO#a~~", 11)], tokenizers: [operatorTokenizer, 1, 2, 3, tokenizer, pipeStartsLineTokenizer, new LocalTokenGroup("[~RP!O!PU~ZO#d~~", 11)],
topRules: {"Program":[0,35]}, topRules: {"Program":[0,35]},
specialized: [{term: 28, get: (value: any, stack: any) => (specializeKeyword(value, stack) << 1), external: specializeKeyword},{term: 28, get: (value: keyof typeof spec_Identifier) => spec_Identifier[value] || -1}], specialized: [{term: 28, get: (value: any, stack: any) => (specializeKeyword(value, stack) << 1), external: specializeKeyword},{term: 28, get: (value: keyof typeof spec_Identifier) => spec_Identifier[value] || -1}],
tokenPrec: 2428 tokenPrec: 2589
}) })

View File

@ -1,4 +1,5 @@
import { expect, describe, test } from 'bun:test' import { expect, describe, test } from 'bun:test'
import { parser } from '../shrimp'
import '../shrimp.grammar' // Importing this so changes cause it to retest! import '../shrimp.grammar' // Importing this so changes cause it to retest!
@ -176,3 +177,159 @@ describe('pipe expressions', () => {
`) `)
}) })
}) })
describe('pipe continuation', () => {
test('pipe on next line', () => {
expect(`hello
| echo`).toMatchTree(`
PipeExpr
FunctionCallOrIdentifier
Identifier hello
operator |
FunctionCallOrIdentifier
Identifier echo
`)
expect(`echo hello
| grep h`).toMatchTree(`
PipeExpr
FunctionCall
Identifier echo
PositionalArg
Identifier hello
operator |
FunctionCall
Identifier grep
PositionalArg
Identifier h
`)
})
test('pipe on next non-empty line', () => {
expect(`hello
| echo`).toMatchTree(`
PipeExpr
FunctionCallOrIdentifier
Identifier hello
operator |
FunctionCallOrIdentifier
Identifier echo
`)
})
test('multi-line pipe chain', () => {
expect(`echo hello
| grep h
| sort`).toMatchTree(`
PipeExpr
FunctionCall
Identifier echo
PositionalArg
Identifier hello
operator |
FunctionCall
Identifier grep
PositionalArg
Identifier h
operator |
FunctionCallOrIdentifier
Identifier sort
`)
})
test('pipe with indentation', () => {
expect(`echo hello
| grep h
| sort`).toMatchTree(`
PipeExpr
FunctionCall
Identifier echo
PositionalArg
Identifier hello
operator |
FunctionCall
Identifier grep
PositionalArg
Identifier h
operator |
FunctionCallOrIdentifier
Identifier sort
`)
})
test('pipe after operand on next line (trailing pipe style)', () => {
expect(`echo hello |
grep h`).toMatchTree(`
PipeExpr
FunctionCall
Identifier echo
PositionalArg
Identifier hello
operator |
FunctionCall
Identifier grep
PositionalArg
Identifier h
`)
})
test('same-line pipes still work', () => {
expect('echo hello | grep h | sort').toMatchTree(`
PipeExpr
FunctionCall
Identifier echo
PositionalArg
Identifier hello
operator |
FunctionCall
Identifier grep
PositionalArg
Identifier h
operator |
FunctionCallOrIdentifier
Identifier sort
`)
})
test('lots of pipes', () => {
expect(`
'this should help readability in long chains'
| split ' '
| map (ref str.to-upper)
| join '-'
| echo
`).toMatchTree(`
PipeExpr
String
StringFragment this should help readability in long chains
operator |
FunctionCall
Identifier split
PositionalArg
String
StringFragment
operator |
FunctionCall
Identifier map
PositionalArg
ParenExpr
FunctionCall
Identifier ref
PositionalArg
DotGet
IdentifierBeforeDot str
Identifier to-upper
operator |
FunctionCall
Identifier join
PositionalArg
String
StringFragment -
operator |
FunctionCallOrIdentifier
Identifier echo
`)
})
})

View File

@ -1,5 +1,5 @@
import { ExternalTokenizer, InputStream, Stack } from '@lezer/lr' import { ExternalTokenizer, InputStream, Stack } from '@lezer/lr'
import { Identifier, AssignableIdentifier, Word, IdentifierBeforeDot, Do, CurlyString, DotGet } from './shrimp.terms' import { Identifier, AssignableIdentifier, Word, IdentifierBeforeDot, Do, CurlyString, DotGet, newline, pipeStartsLine } from './shrimp.terms'
// doobie doobie do (we need the `do` keyword to know when we're defining params) // doobie doobie do (we need the `do` keyword to know when we're defining params)
export function specializeKeyword(ident: string) { export function specializeKeyword(ident: string) {
@ -356,3 +356,34 @@ const isEmojiOrUnicode = (ch: number): boolean => {
} }
const getCharSize = (ch: number) => (ch > 0xffff ? 2 : 1) // emoji takes 2 UTF-16 code units const getCharSize = (ch: number) => (ch > 0xffff ? 2 : 1) // emoji takes 2 UTF-16 code units
export const pipeStartsLineTokenizer = new ExternalTokenizer((input: InputStream, stack: Stack) => {
const ch = input.peek(0)
if (ch !== 10 /* \n */) return
// ignore whitespace
let offset = 1
let lastNewlineOffset = 0
while (true) {
const ch = input.peek(offset)
if (ch === 10 /* \n */) {
lastNewlineOffset = offset
offset++
} else if (isWhiteSpace(ch)) {
offset++
} else {
break
}
}
// look for pipe after skipping empty lines
if (input.peek(offset) === 124 /* | */) {
input.advance(lastNewlineOffset + 1)
input.acceptToken(pipeStartsLine)
} else {
input.advance(1)
input.acceptToken(newline)
}
})