Compare commits

..

1 Commits

Author SHA1 Message Date
831966323a bun run repl 2025-10-25 10:20:52 -07:00
7 changed files with 49 additions and 67 deletions

View File

@ -112,18 +112,18 @@ describe('compiler', () => {
end`).toEvaluateTo('white')
})
test('if elseif', () => {
test('if elsif', () => {
expect(`if false:
boromir
elseif true:
elsif true:
frodo
end`).toEvaluateTo('frodo')
})
test('if elseif else', () => {
test('if elsif else', () => {
expect(`if false:
destroyed
elseif true:
elsif true:
fire
else:
darkness
@ -131,9 +131,9 @@ describe('compiler', () => {
expect(`if false:
king
elseif false:
elsif false:
elf
elseif true:
elsif true:
dwarf
else:
scattered

View File

@ -140,11 +140,11 @@ export const getIfExprParts = (node: SyntaxNode, input: string) => {
throw new CompilerError(message, child.from, child.to)
}
elseThenBlock = parts.at(-1)
} else if (child.type.id === terms.ElseIfExpr) {
} else if (child.type.id === terms.ElsifExpr) {
const [_keyword, conditional, _colon, thenBlock] = parts
if (!conditional || !thenBlock) {
const names = parts.map((p) => p.type.name).join(', ')
const message = `ElseIfExpr expected conditional and thenBlock, got ${names}`
const message = `ElsifExpr expected conditional and thenBlock, got ${names}`
throw new CompilerError(message, child.from, child.to)
}

View File

@ -22,6 +22,7 @@
rightParen { ")" }
colon[closedBy="end", @name="colon"] { ":" }
Underscore { "_" }
Null { "null" }
Regex { "//" (![/\\\n[] | "\\" ![\n] | "[" (![\n\\\]] | "\\" ![\n])* "]")+ ("//" $[gimsuy]*)? } // Stolen from the lezer JavaScript grammar
"|"[@name=operator]
@ -108,11 +109,11 @@ singleLineIf {
}
multilineIf {
@specialize[@name=keyword]<Identifier, "if"> (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock ElseIfExpr* ElseExpr? @specialize[@name=keyword]<Identifier, "end">
@specialize[@name=keyword]<Identifier, "if"> (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock ElsifExpr* ElseExpr? @specialize[@name=keyword]<Identifier, "end">
}
ElseIfExpr {
@specialize[@name=keyword]<Identifier, "elseif"> (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock
ElsifExpr {
@specialize[@name=keyword]<Identifier, "elsif"> (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock
}
ElseExpr {
@ -195,7 +196,7 @@ EscapeSeq {
// to go through ambiguousFunctionCall (which is what we want semantically).
// Yes, it is annoying and I gave up trying to use GLR to fix it.
expressionWithoutIdentifier {
ParenExpr | Word | String | Number | Boolean | Regex | @specialize[@name=Null]<Identifier, "null">
ParenExpr | Word | String | Number | Boolean | Regex | Null
}
block {

View File

@ -1,5 +1,6 @@
// This file was generated by lezer-generator. You probably shouldn't edit it.
export const Star = 1,
export const
Star = 1,
Slash = 2,
Plus = 3,
Minus = 4,
@ -41,6 +42,6 @@ export const Star = 1,
NamedArgPrefix = 41,
IfExpr = 43,
ThenBlock = 46,
ElseIfExpr = 47,
ElsifExpr = 47,
ElseExpr = 49,
Assign = 51

View File

@ -1,39 +1,27 @@
// This file was generated by lezer-generator. You probably shouldn't edit it.
import { LRParser, LocalTokenGroup } from '@lezer/lr'
import { operatorTokenizer } from './operatorTokenizer'
import { tokenizer } from './tokenizer'
import { trackScope } from './scopeTracker'
import { highlighting } from './highlight'
const spec_Identifier = {
__proto__: null,
null: 64,
do: 70,
end: 76,
if: 88,
elseif: 96,
else: 100,
}
import {LRParser, LocalTokenGroup} from "@lezer/lr"
import {operatorTokenizer} from "./operatorTokenizer"
import {tokenizer} from "./tokenizer"
import {trackScope} from "./scopeTracker"
import {highlighting} from "./highlight"
const spec_Identifier = {__proto__:null,do:70, end:76, if:88, elsif:96, else:100}
export const parser = LRParser.deserialize({
version: 14,
states:
".jQVQbOOO#XQcO'#CrO$RQRO'#CsO$aQcO'#DmO$xQbO'#CqO%gOSO'#CuOOQa'#Dq'#DqO%uOpO'#C}O%zQcO'#DpO&cQbO'#D|OOQ`'#DO'#DOOOQ`'#Dn'#DnO&kQbO'#DmO&yQbO'#EQOOQ`'#DX'#DXO'hQRO'#DaOOQ`'#Dm'#DmO'mQQO'#DlOOQ`'#Dl'#DlOOQ`'#Db'#DbQVQbOOOOQa'#Dp'#DpOOQ`'#Cp'#CpO'uQbO'#DUOOQ`'#Do'#DoOOQ`'#Dc'#DcO(PQbO,59ZO&yQbO,59_O&yQbO,59_O)XQRO'#CsO)iQRO,59]O)zQRO,59]O)uQQO,59]O*uQQO,59]O*}QbO'#CwO+VQWO'#CxOOOO'#Du'#DuOOOO'#Dd'#DdO+kOSO,59aOOQa,59a,59aO+yO`O,59iOOQ`'#De'#DeO,OQbO'#DQO,WQQO,5:hO,]QbO'#DgO,bQbO,59YO,sQRO,5:lO,zQQO,5:lO-PQbO,59{OOQ`,5:W,5:WOOQ`-E7`-E7`OOQ`,59p,59pOOQ`-E7a-E7aOOQa1G.y1G.yO-^QcO1G.yO&yQbO,59`O&yQbO,59`OOQa1G.w1G.wOOOO,59c,59cOOOO,59d,59dOOOO-E7b-E7bOOQa1G.{1G.{OOQa1G/T1G/TOOQ`-E7c-E7cO-xQbO1G0SO!QQbO'#CrOOQ`,5:R,5:ROOQ`-E7e-E7eO.YQbO1G0WOOQ`1G/g1G/gOOQO1G.z1G.zO.jQRO1G.zO.tQbO7+%nO.yQbO7+%oOOQ`'#DZ'#DZOOQ`7+%r7+%rO/ZQbO7+%sOOQ`<<IY<<IYO/qQQO'#DfO/vQbO'#EPO0^QbO<<IZOOQ`'#D['#D[O0cQbO<<I_OOQ`,5:Q,5:QOOQ`-E7d-E7dOOQ`AN>uAN>uO&yQbO'#D]OOQ`'#Dh'#DhO0nQbOAN>yO0yQQO'#D_OOQ`AN>yAN>yO1OQbOAN>yO1TQRO,59wO1[QQO,59wOOQ`-E7f-E7fOOQ`G24eG24eO1aQbOG24eO1fQQO,59yO1kQQO1G/cOOQ`LD*PLD*PO.yQbO1G/eO/ZQbO7+$}OOQ`7+%P7+%POOQ`<<Hi<<Hi",
stateData:
'1s~O!_OS~O]PO^_O_UO`VOmUOnUOoUOpUOsXO|]O!fSO!hTO!rbO~O]eO_UO`VOmUOnUOoUOpUOsXOwfOygO!fSO!hTOzfX!rfX!vfX!gfXvfX~OP!dXQ!dXR!dXS!dXT!dXU!dXV!dXW!dXX!dXY!dXZ!dX[!dX~P!QOPkOQkORlOSlO~OPkOQkORlOSlO!r!aX!v!aXv!aX~O]PO_UO`VOmUOnUOoUOpUO!fSO!hTO~OjtO!hwO!jrO!ksO~O!oxO~OP!dXQ!dXR!dXS!dX!r!aX!v!aXv!aX~O^yOutP~Oz|O!r!aX!v!aXv!aX~O]eO_UO`VOmUOnUOoUOpUO!fSO!hTO~OV!QO~O!r!RO!v!RO~OsXOw!TO~P&yOsXOwfOygOzca!rca!vca!gcavca~P&yOT!YOU!YOV!XOW!XOX!XOY!XOZ!XO[!XO~OPkOQkORlOSlO~P(mOPkOQkORlOSlO!g!ZO~O!g!ZOP!dXQ!dXR!dXS!dXT!dXU!dXV!dXW!dXX!dXY!dXZ!dX[!dX~Oz|O!g!ZO~O]![O!fSO~O!h!]O!j!]O!k!]O!l!]O!m!]O!n!]O~OjtO!h!_O!jrO!ksO~O]!`O~O^yOutX~Ou!bO~O]!cO~Oz|O!rba!vba!gbavba~Ou!fO~P(mOu!fO~O^_OsXO|]O~P$xOPkOQkORgiSgi!rgi!vgi!ggivgi~O^_OsXO|]O!r!kO~P$xO^_OsXO|]O!r!nO~P$xO!ghiuhi~P(mOv!oO~O^_OsXO|]Ov!sP~P$xO^_OsXO|]Ov!sP!Q!sP!S!sP~P$xO!r!uO~O^_OsXO|]Ov!sX!Q!sX!S!sX~P$xOv!wO~Ov!|O!Q!xO!S!{O~Ov#RO!Q!xO!S!{O~Ou#TO~Ov#RO~Ou#UO~P(mOu#UO~Ov#VO~O!r#WO~O!r#XO~Omo~',
states: ".jQVQbOOO#XQcO'#CrO$RQRO'#CsO$aQcO'#DmO$xQbO'#CqO%gOSO'#CuOOQa'#Dq'#DqO%uOpO'#C}O%zQcO'#DpO&cQbO'#D|OOQ`'#DO'#DOOOQ`'#Dn'#DnO&kQbO'#DmO&yQbO'#EQOOQ`'#DX'#DXO'hQRO'#DaOOQ`'#Dm'#DmO'mQQO'#DlOOQ`'#Dl'#DlOOQ`'#Db'#DbQVQbOOOOQa'#Dp'#DpOOQ`'#Cp'#CpO'uQbO'#DUOOQ`'#Do'#DoOOQ`'#Dc'#DcO(PQbO,59ZO&yQbO,59_O&yQbO,59_O)XQRO'#CsO)iQRO,59]O)zQRO,59]O)uQQO,59]O*uQQO,59]O*}QbO'#CwO+VQWO'#CxOOOO'#Du'#DuOOOO'#Dd'#DdO+kOSO,59aOOQa,59a,59aO+yO`O,59iOOQ`'#De'#DeO,OQbO'#DQO,WQQO,5:hO,]QbO'#DgO,bQbO,59YO,sQRO,5:lO,zQQO,5:lO-PQbO,59{OOQ`,5:W,5:WOOQ`-E7`-E7`OOQ`,59p,59pOOQ`-E7a-E7aOOQa1G.y1G.yO-^QcO1G.yO&yQbO,59`O&yQbO,59`OOQa1G.w1G.wOOOO,59c,59cOOOO,59d,59dOOOO-E7b-E7bOOQa1G.{1G.{OOQa1G/T1G/TOOQ`-E7c-E7cO-xQbO1G0SO!QQbO'#CrOOQ`,5:R,5:ROOQ`-E7e-E7eO.YQbO1G0WOOQ`1G/g1G/gOOQO1G.z1G.zO.jQRO1G.zO.tQbO7+%nO.yQbO7+%oOOQ`'#DZ'#DZOOQ`7+%r7+%rO/ZQbO7+%sOOQ`<<IY<<IYO/qQQO'#DfO/vQbO'#EPO0^QbO<<IZOOQ`'#D['#D[O0cQbO<<I_OOQ`,5:Q,5:QOOQ`-E7d-E7dOOQ`AN>uAN>uO&yQbO'#D]OOQ`'#Dh'#DhO0nQbOAN>yO0yQQO'#D_OOQ`AN>yAN>yO1OQbOAN>yO1TQRO,59wO1[QQO,59wOOQ`-E7f-E7fOOQ`G24eG24eO1aQbOG24eO1fQQO,59yO1kQQO1G/cOOQ`LD*PLD*PO.yQbO1G/eO/ZQbO7+$}OOQ`7+%P7+%POOQ`<<Hi<<Hi",
stateData: "1s~O!_OS~O]PO^_O_UO`VOmUOnUOoUOpUOsXO|]O!fSO!hTO!rbO~O]eO_UO`VOmUOnUOoUOpUOsXOwfOygO!fSO!hTOzfX!rfX!vfX!gfXvfX~OP!dXQ!dXR!dXS!dXT!dXU!dXV!dXW!dXX!dXY!dXZ!dX[!dX~P!QOPkOQkORlOSlO~OPkOQkORlOSlO!r!aX!v!aXv!aX~O]PO_UO`VOmUOnUOoUOpUO!fSO!hTO~OjtO!hwO!jrO!ksO~O!oxO~OP!dXQ!dXR!dXS!dX!r!aX!v!aXv!aX~O^yOutP~Oz|O!r!aX!v!aXv!aX~O]eO_UO`VOmUOnUOoUOpUO!fSO!hTO~OV!QO~O!r!RO!v!RO~OsXOw!TO~P&yOsXOwfOygOzca!rca!vca!gcavca~P&yOT!YOU!YOV!XOW!XOX!XOY!XOZ!XO[!XO~OPkOQkORlOSlO~P(mOPkOQkORlOSlO!g!ZO~O!g!ZOP!dXQ!dXR!dXS!dXT!dXU!dXV!dXW!dXX!dXY!dXZ!dX[!dX~Oz|O!g!ZO~O]![O!fSO~O!h!]O!j!]O!k!]O!l!]O!m!]O!n!]O~OjtO!h!_O!jrO!ksO~O]!`O~O^yOutX~Ou!bO~O]!cO~Oz|O!rba!vba!gbavba~Ou!fO~P(mOu!fO~O^_OsXO|]O~P$xOPkOQkORgiSgi!rgi!vgi!ggivgi~O^_OsXO|]O!r!kO~P$xO^_OsXO|]O!r!nO~P$xO!ghiuhi~P(mOv!oO~O^_OsXO|]Ov!sP~P$xO^_OsXO|]Ov!sP!Q!sP!S!sP~P$xO!r!uO~O^_OsXO|]Ov!sX!Q!sX!S!sX~P$xOv!wO~Ov!|O!Q!xO!S!{O~Ov#RO!Q!xO!S!{O~Ou#TO~Ov#RO~Ou#UO~P(mOu#UO~Ov#VO~O!r#WO~O!r#XO~Omo~",
goto: "+m!vPPPPPPPPPPPPPPPPPP!w#W#f#k#W$V$l$xP%a%aPPPP%e&OP&dPPP#fPP&gP&s&v'PP'TP&g'Z'a'h'n't'}(UPPP([(`(t)W)]*WPPP*sPPPPPP*w*wP+X+a+ad`Od!Q!b!f!k!n!q#W#XRpSiZOSd|!Q!b!f!k!n!q#W#XVhPj!czUOPS]dgjkl!Q!X!Y!b!c!f!k!n!q!x#W#XR![rdROd!Q!b!f!k!n!q#W#XQnSQ!VkR!WlQpSQ!P]Q!h!YR#P!x{UOPS]dgjkl!Q!X!Y!b!c!f!k!n!q!x#W#XTtTvdWOd!Q!b!f!k!n!q#W#XgePS]gjkl!X!Y!c!xd`Od!Q!b!f!k!n!q#W#XUfPj!cR!TgR{Xe`Od!Q!b!f!k!n!q#W#XR!m!fQ!t!nQ#Y#WR#Z#XT!y!t!zQ!}!tR#S!zQdOR!SdSjP!cR!UjQvTR!^vQzXR!azW!q!k!n#W#XR!v!qS}[qR!e}Q!z!tR#Q!zTcOdSaOdQ!g!QQ!j!bQ!l!fZ!p!k!n!q#W#Xd[Od!Q!b!f!k!n!q#W#XQqSR!d|ViPj!cdQOd!Q!b!f!k!n!q#W#XUfPj!cQmSQ!O]Q!TgQ!VkQ!WlQ!h!XQ!i!YR#O!xdWOd!Q!b!f!k!n!q#W#XdeP]gjkl!X!Y!c!xRoSTuTvmYOPdgj!Q!b!c!f!k!n!q#W#XQ!r!kV!s!n#W#Xe^Od!Q!b!f!k!n!q#W#X",
nodeNames:
'⚠ Star Slash Plus Minus And Or Eq Neq Lt Lte Gt Gte Identifier AssignableIdentifier Word IdentifierBeforeDot Program PipeExpr FunctionCall PositionalArg ParenExpr FunctionCallOrIdentifier BinOp ConditionalOp String StringFragment Interpolation EscapeSeq Number Boolean Regex Null DotGet FunctionDef keyword Params colon keyword Underscore NamedArg NamedArgPrefix operator IfExpr keyword ThenBlock ThenBlock ElseIfExpr keyword ElseExpr keyword Assign',
nodeNames: "⚠ Star Slash Plus Minus And Or Eq Neq Lt Lte Gt Gte Identifier AssignableIdentifier Word IdentifierBeforeDot Program PipeExpr FunctionCall PositionalArg ParenExpr FunctionCallOrIdentifier BinOp ConditionalOp String StringFragment Interpolation EscapeSeq Number Boolean Regex Null DotGet FunctionDef keyword Params colon keyword Underscore NamedArg NamedArgPrefix operator IfExpr keyword ThenBlock ThenBlock ElsifExpr keyword ElseExpr keyword Assign",
maxTerm: 84,
context: trackScope,
nodeProps: [['closedBy', 37, 'end']],
nodeProps: [
["closedBy", 37,"end"]
],
propSources: [highlighting],
skippedNodes: [0],
repeatNodeCount: 7,
tokenData:
"<}~RyOX#rXY$aYZ$zZp#rpq$aqt#rtu%euw#rwx%jxy%oyz&Yz{#r{|&s|}#r}!O&s!O!P#r!P!Q)g!Q!['b![!]2S!]!^$z!^#O#r#O#P2m#P#R#r#R#S2r#S#T#r#T#Y3]#Y#Z4k#Z#b3]#b#c8y#c#f3]#f#g9p#g#h3]#h#i:g#i#o3]#o#p#r#p#q<_#q;'S#r;'S;=`$Z<%l~#r~O#r~~<xS#wUjSOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#rS$^P;=`<%l#r^$hUjS!_YOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#rU%RUjS!rQOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#r~%jO!j~~%oO!h~U%vUjS!fQOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#rU&aUjS!gQOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#rU&xWjSOt#ruw#rx!Q#r!Q!['b![#O#r#P;'S#r;'S;=`$Z<%lO#rU'iYjSmQOt#ruw#rx!O#r!O!P(X!P!Q#r!Q!['b![#O#r#P;'S#r;'S;=`$Z<%lO#rU(^WjSOt#ruw#rx!Q#r!Q![(v![#O#r#P;'S#r;'S;=`$Z<%lO#rU(}WjSmQOt#ruw#rx!Q#r!Q![(v![#O#r#P;'S#r;'S;=`$Z<%lO#rU)lWjSOt#ruw#rx!P#r!P!Q*U!Q#O#r#P;'S#r;'S;=`$Z<%lO#rU*Z^jSOY+VYZ#rZt+Vtu,Yuw+Vwx,Yx!P+V!P!Q#r!Q!}+V!}#O0{#O#P.h#P;'S+V;'S;=`1|<%lO+VU+^^jSoQOY+VYZ#rZt+Vtu,Yuw+Vwx,Yx!P+V!P!Q.}!Q!}+V!}#O0{#O#P.h#P;'S+V;'S;=`1|<%lO+VQ,_XoQOY,YZ!P,Y!P!Q,z!Q!},Y!}#O-i#O#P.h#P;'S,Y;'S;=`.w<%lO,YQ,}P!P!Q-QQ-VUoQ#Z#[-Q#]#^-Q#a#b-Q#g#h-Q#i#j-Q#m#n-QQ-lVOY-iZ#O-i#O#P.R#P#Q,Y#Q;'S-i;'S;=`.b<%lO-iQ.USOY-iZ;'S-i;'S;=`.b<%lO-iQ.eP;=`<%l-iQ.kSOY,YZ;'S,Y;'S;=`.w<%lO,YQ.zP;=`<%l,YU/SWjSOt#ruw#rx!P#r!P!Q/l!Q#O#r#P;'S#r;'S;=`$Z<%lO#rU/sbjSoQOt#ruw#rx#O#r#P#Z#r#Z#[/l#[#]#r#]#^/l#^#a#r#a#b/l#b#g#r#g#h/l#h#i#r#i#j/l#j#m#r#m#n/l#n;'S#r;'S;=`$Z<%lO#rU1Q[jSOY0{YZ#rZt0{tu-iuw0{wx-ix#O0{#O#P.R#P#Q+V#Q;'S0{;'S;=`1v<%lO0{U1yP;=`<%l0{U2PP;=`<%l+VU2ZUjSuQOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#r~2rO!k~U2yUjSwQOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#rU3bYjSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#o3]#o;'S#r;'S;=`$Z<%lO#rU4XUyQjSOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#rU4pZjSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#U5c#U#o3]#o;'S#r;'S;=`$Z<%lO#rU5h[jSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#`3]#`#a6^#a#o3]#o;'S#r;'S;=`$Z<%lO#rU6c[jSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#g3]#g#h7X#h#o3]#o;'S#r;'S;=`$Z<%lO#rU7^[jSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#X3]#X#Y8S#Y#o3]#o;'S#r;'S;=`$Z<%lO#rU8ZYnQjSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#o3]#o;'S#r;'S;=`$Z<%lO#r^9QY!lWjSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#o3]#o;'S#r;'S;=`$Z<%lO#r^9wY!nWjSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#o3]#o;'S#r;'S;=`$Z<%lO#r^:n[!mWjSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#f3]#f#g;d#g#o3]#o;'S#r;'S;=`$Z<%lO#rU;i[jSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#i3]#i#j7X#j#o3]#o;'S#r;'S;=`$Z<%lO#rU<fUzQjSOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#r~<}O!v~",
tokenizers: [operatorTokenizer, 1, 2, 3, tokenizer, new LocalTokenGroup('[~RP!O!PU~ZO!o~~', 11)],
topRules: { Program: [0, 17] },
specialized: [
{ term: 13, get: (value: keyof typeof spec_Identifier) => spec_Identifier[value] || -1 },
],
tokenPrec: 768,
tokenData: "?p~RyOX#rXY$aYZ$zZp#rpq$aqt#rtu%euw#rwx%jxy%oyz&Yz{#r{|&s|}#r}!O&s!O!P#r!P!Q)g!Q!['b![!]2S!]!^$z!^#O#r#O#P2m#P#R#r#R#S2r#S#T#r#T#Y3]#Y#Z4k#Z#b3]#b#c8y#c#f3]#f#g<c#g#h3]#h#i=Y#i#o3]#o#p#r#p#q?Q#q;'S#r;'S;=`$Z<%l~#r~O#r~~?kS#wUjSOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#rS$^P;=`<%l#r^$hUjS!_YOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#rU%RUjS!rQOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#r~%jO!j~~%oO!h~U%vUjS!fQOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#rU&aUjS!gQOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#rU&xWjSOt#ruw#rx!Q#r!Q!['b![#O#r#P;'S#r;'S;=`$Z<%lO#rU'iYjSmQOt#ruw#rx!O#r!O!P(X!P!Q#r!Q!['b![#O#r#P;'S#r;'S;=`$Z<%lO#rU(^WjSOt#ruw#rx!Q#r!Q![(v![#O#r#P;'S#r;'S;=`$Z<%lO#rU(}WjSmQOt#ruw#rx!Q#r!Q![(v![#O#r#P;'S#r;'S;=`$Z<%lO#rU)lWjSOt#ruw#rx!P#r!P!Q*U!Q#O#r#P;'S#r;'S;=`$Z<%lO#rU*Z^jSOY+VYZ#rZt+Vtu,Yuw+Vwx,Yx!P+V!P!Q#r!Q!}+V!}#O0{#O#P.h#P;'S+V;'S;=`1|<%lO+VU+^^jSoQOY+VYZ#rZt+Vtu,Yuw+Vwx,Yx!P+V!P!Q.}!Q!}+V!}#O0{#O#P.h#P;'S+V;'S;=`1|<%lO+VQ,_XoQOY,YZ!P,Y!P!Q,z!Q!},Y!}#O-i#O#P.h#P;'S,Y;'S;=`.w<%lO,YQ,}P!P!Q-QQ-VUoQ#Z#[-Q#]#^-Q#a#b-Q#g#h-Q#i#j-Q#m#n-QQ-lVOY-iZ#O-i#O#P.R#P#Q,Y#Q;'S-i;'S;=`.b<%lO-iQ.USOY-iZ;'S-i;'S;=`.b<%lO-iQ.eP;=`<%l-iQ.kSOY,YZ;'S,Y;'S;=`.w<%lO,YQ.zP;=`<%l,YU/SWjSOt#ruw#rx!P#r!P!Q/l!Q#O#r#P;'S#r;'S;=`$Z<%lO#rU/sbjSoQOt#ruw#rx#O#r#P#Z#r#Z#[/l#[#]#r#]#^/l#^#a#r#a#b/l#b#g#r#g#h/l#h#i#r#i#j/l#j#m#r#m#n/l#n;'S#r;'S;=`$Z<%lO#rU1Q[jSOY0{YZ#rZt0{tu-iuw0{wx-ix#O0{#O#P.R#P#Q+V#Q;'S0{;'S;=`1v<%lO0{U1yP;=`<%l0{U2PP;=`<%l+VU2ZUjSuQOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#r~2rO!k~U2yUjSwQOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#rU3bYjSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#o3]#o;'S#r;'S;=`$Z<%lO#rU4XUyQjSOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#rU4pZjSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#U5c#U#o3]#o;'S#r;'S;=`$Z<%lO#rU5h[jSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#`3]#`#a6^#a#o3]#o;'S#r;'S;=`$Z<%lO#rU6c[jSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#g3]#g#h7X#h#o3]#o;'S#r;'S;=`$Z<%lO#rU7^[jSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#X3]#X#Y8S#Y#o3]#o;'S#r;'S;=`$Z<%lO#rU8ZYnQjSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#o3]#o;'S#r;'S;=`$Z<%lO#r^9Q[!lWjSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#i3]#i#j9v#j#o3]#o;'S#r;'S;=`$Z<%lO#rU9{[jSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#`3]#`#a:q#a#o3]#o;'S#r;'S;=`$Z<%lO#rU:v[jSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#`3]#`#a;l#a#o3]#o;'S#r;'S;=`$Z<%lO#rU;sYpQjSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#o3]#o;'S#r;'S;=`$Z<%lO#r^<jY!nWjSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#o3]#o;'S#r;'S;=`$Z<%lO#r^=a[!mWjSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#f3]#f#g>V#g#o3]#o;'S#r;'S;=`$Z<%lO#rU>[[jSOt#ruw#rx!_#r!_!`4Q!`#O#r#P#T#r#T#i3]#i#j7X#j#o3]#o;'S#r;'S;=`$Z<%lO#rU?XUzQjSOt#ruw#rx#O#r#P;'S#r;'S;=`$Z<%lO#r~?pO!v~",
tokenizers: [operatorTokenizer, 1, 2, 3, tokenizer, new LocalTokenGroup("[~RP!O!PU~ZO!o~~", 11)],
topRules: {"Program":[0,17]},
specialized: [{term: 13, get: (value: keyof typeof spec_Identifier) => spec_Identifier[value] || -1}],
tokenPrec: 768
})

View File

@ -14,14 +14,6 @@ describe('null', () => {
Eq =
Null null`)
})
test('does not parse null in identifier', () => {
expect('null-jk = 5').toMatchTree(`
Assign
AssignableIdentifier null-jk
Eq =
Number 5`)
})
})
describe('Identifier', () => {

View File

@ -2,7 +2,7 @@ import { expect, describe, test } from 'bun:test'
import '../shrimp.grammar' // Importing this so changes cause it to retest!
describe('if/elseif/else', () => {
describe('if/elsif/else', () => {
test('parses single line if', () => {
expect(`if y = 1: 'cool'`).toMatchTree(`
IfExpr
@ -72,21 +72,21 @@ describe('if/elseif/else', () => {
`)
})
test('parses multiline if with elseif', () => {
expect(`if with-elseif:
test('parses multiline if with elsif', () => {
expect(`if with-elsif:
x
elseif another-condition:
elsif another-condition:
y
end`).toMatchTree(`
IfExpr
keyword if
Identifier with-elseif
Identifier with-elsif
colon :
ThenBlock
FunctionCallOrIdentifier
Identifier x
ElseIfExpr
keyword elseif
ElsifExpr
keyword elsif
Identifier another-condition
colon :
ThenBlock
@ -96,32 +96,32 @@ describe('if/elseif/else', () => {
`)
})
test('parses multiline if with multiple elseif and else', () => {
expect(`if with-elseif-else:
test('parses multiline if with multiple elsif and else', () => {
expect(`if with-elsif-else:
x
elseif another-condition:
elsif another-condition:
y
elseif yet-another-condition:
elsif yet-another-condition:
z
else:
oh-no
end`).toMatchTree(`
IfExpr
keyword if
Identifier with-elseif-else
Identifier with-elsif-else
colon :
ThenBlock
FunctionCallOrIdentifier
Identifier x
ElseIfExpr
keyword elseif
ElsifExpr
keyword elsif
Identifier another-condition
colon :
ThenBlock
FunctionCallOrIdentifier
Identifier y
ElseIfExpr
keyword elseif
ElsifExpr
keyword elsif
Identifier yet-another-condition
colon :
ThenBlock