Compare commits
No commits in common. "d306d58b2f49b9da635be215123e4beb9a2f0e70" and "66671970e0ce869b484aaad77a1707fcd77a16d3" have entirely different histories.
d306d58b2f
...
66671970e0
|
|
@ -63,26 +63,26 @@ describe('compiler', () => {
|
|||
})
|
||||
|
||||
test('function', () => {
|
||||
expect(`do a b: a + b end`).toEvaluateTo(Function)
|
||||
expect(`fn a b: a + b end`).toEvaluateTo(Function)
|
||||
})
|
||||
|
||||
test('function call', () => {
|
||||
expect(`add = do a b: a + b end; add 2 9`).toEvaluateTo(11)
|
||||
expect(`add = fn a b: a + b end; add 2 9`).toEvaluateTo(11)
|
||||
})
|
||||
|
||||
test('function call with named args', () => {
|
||||
expect(`minus = do a b: a - b end; minus b=2 a=9`).toEvaluateTo(7)
|
||||
expect(`minus = fn a b: a - b end; minus b=2 a=9`).toEvaluateTo(7)
|
||||
})
|
||||
|
||||
test('function call with named and positional args', () => {
|
||||
expect(`minus = do a b: a - b end; minus b=2 9`).toEvaluateTo(7)
|
||||
expect(`minus = do a b: a - b end; minus 90 b=20`).toEvaluateTo(70)
|
||||
expect(`minus = do a b: a - b end; minus a=900 200`).toEvaluateTo(700)
|
||||
expect(`minus = do a b: a - b end; minus 2000 a=9000`).toEvaluateTo(7000)
|
||||
expect(`minus = fn a b: a - b end; minus b=2 9`).toEvaluateTo(7)
|
||||
expect(`minus = fn a b: a - b end; minus 90 b=20`).toEvaluateTo(70)
|
||||
expect(`minus = fn a b: a - b end; minus a=900 200`).toEvaluateTo(700)
|
||||
expect(`minus = fn a b: a - b end; minus 2000 a=9000`).toEvaluateTo(7000)
|
||||
})
|
||||
|
||||
test('function call with no args', () => {
|
||||
expect(`bloop = do: 'bloop' end; bloop`).toEvaluateTo('bloop')
|
||||
expect(`bloop = fn: 'bloop' end; bloop`).toEvaluateTo('bloop')
|
||||
})
|
||||
|
||||
test('simple conditionals', () => {
|
||||
|
|
@ -150,7 +150,7 @@ describe('errors', () => {
|
|||
describe('multiline tests', () => {
|
||||
test('multiline function', () => {
|
||||
expect(`
|
||||
add = do a b:
|
||||
add = fn a b:
|
||||
result = a + b
|
||||
result
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { describe, test, expect } from 'bun:test'
|
|||
describe('pipe expressions', () => {
|
||||
test('simple pipe passes result as first argument', () => {
|
||||
const code = `
|
||||
double = do x: x * 2 end
|
||||
double = fn x: x * 2 end
|
||||
double 2 | double`
|
||||
|
||||
expect(code).toEvaluateTo(8)
|
||||
|
|
@ -11,9 +11,9 @@ describe('pipe expressions', () => {
|
|||
|
||||
test('pipe chain with three stages', () => {
|
||||
const code = `
|
||||
add-one = do x: x + 1 end
|
||||
double = do x: x * 2 end
|
||||
minus-point-one = do x: x - 0.1 end
|
||||
add-one = fn x: x + 1 end
|
||||
double = fn x: x * 2 end
|
||||
minus-point-one = fn x: x - 0.1 end
|
||||
add-one 3 | double | minus-point-one`
|
||||
// 4 8 7.9
|
||||
expect(code).toEvaluateTo(7.9)
|
||||
|
|
@ -21,8 +21,8 @@ describe('pipe expressions', () => {
|
|||
|
||||
test('pipe with function that has additional arguments', () => {
|
||||
const code = `
|
||||
multiply = do a b: a * b end
|
||||
get-five = do: 5 end
|
||||
multiply = fn a b: a * b end
|
||||
get-five = fn: 5 end
|
||||
get-five | multiply 3`
|
||||
|
||||
expect(code).toEvaluateTo(15)
|
||||
|
|
@ -31,7 +31,7 @@ describe('pipe expressions', () => {
|
|||
test('pipe with bare identifier', () => {
|
||||
const code = `
|
||||
get-value = 42
|
||||
process = do x: x + 10 end
|
||||
process = fn x: x + 10 end
|
||||
get-value | process`
|
||||
|
||||
expect(code).toEvaluateTo(52)
|
||||
|
|
@ -39,7 +39,7 @@ describe('pipe expressions', () => {
|
|||
|
||||
test('pipe in assignment', () => {
|
||||
const code = `
|
||||
add-ten = do x: x + 10 end
|
||||
add-ten = fn x: x + 10 end
|
||||
result = add-ten 5 | add-ten
|
||||
result`
|
||||
|
||||
|
|
@ -49,23 +49,23 @@ describe('pipe expressions', () => {
|
|||
|
||||
test('pipe with named underscore arg', () => {
|
||||
expect(`
|
||||
divide = do a b: a / b end
|
||||
get-ten = do: 10 end
|
||||
divide = fn a b: a / b end
|
||||
get-ten = fn: 10 end
|
||||
get-ten | divide 2 b=_`).toEvaluateTo(0.2)
|
||||
|
||||
expect(`
|
||||
divide = do a b: a / b end
|
||||
get-ten = do: 10 end
|
||||
divide = fn a b: a / b end
|
||||
get-ten = fn: 10 end
|
||||
get-ten | divide b=_ 2`).toEvaluateTo(0.2)
|
||||
|
||||
expect(`
|
||||
divide = do a b: a / b end
|
||||
get-ten = do: 10 end
|
||||
divide = fn a b: a / b end
|
||||
get-ten = fn: 10 end
|
||||
get-ten | divide 2 a=_`).toEvaluateTo(5)
|
||||
|
||||
expect(`
|
||||
divide = do a b: a / b end
|
||||
get-ten = do: 10 end
|
||||
divide = fn a b: a / b end
|
||||
get-ten = fn: 10 end
|
||||
get-ten | divide a=_ 2`).toEvaluateTo(5)
|
||||
})
|
||||
|
||||
|
|
@ -74,8 +74,8 @@ describe('pipe expressions', () => {
|
|||
// handling logic works correctly when there are multiple pipe stages
|
||||
// in a single expression.
|
||||
expect(`
|
||||
sub = do a b: a - b end
|
||||
div = do a b: a / b end
|
||||
sub = fn a b: a - b end
|
||||
div = fn a b: a / b end
|
||||
sub 3 1 | div (sub 110 9 | sub 1) _ | div 5`).toEvaluateTo(10)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ const commandShapes: CommandShape[] = [
|
|||
] as const
|
||||
|
||||
let commandSource = () => commandShapes
|
||||
export const setCommandSource = (do: () => CommandShape[]) => {
|
||||
export const setCommandSource = (fn: () => CommandShape[]) => {
|
||||
commandSource = fn
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,9 +21,14 @@
|
|||
leftParen { "(" }
|
||||
rightParen { ")" }
|
||||
colon[closedBy="end", @name="colon"] { ":" }
|
||||
end[openedBy="colon", @name="end"] { "end" }
|
||||
Underscore { "_" }
|
||||
Null { "null" }
|
||||
Regex { "//" (![/\\\n[] | "\\" ![\n] | "[" (![\n\\\]] | "\\" ![\n])* "]")+ ("//" $[gimsuy]*)? } // Stolen from the lezer JavaScript grammar
|
||||
Fn[@name=keyword] { "fn" }
|
||||
"if" [@name=keyword]
|
||||
"elsif" [@name=keyword]
|
||||
"else" [@name=keyword]
|
||||
"|"[@name=operator]
|
||||
|
||||
}
|
||||
|
|
@ -93,11 +98,11 @@ FunctionDef {
|
|||
}
|
||||
|
||||
singleLineFunctionDef {
|
||||
@specialize[@name=keyword]<Identifier, "do"> Params colon consumeToTerminator @specialize[@name=keyword]<Identifier, "end">
|
||||
Fn Params colon consumeToTerminator end
|
||||
}
|
||||
|
||||
multilineFunctionDef {
|
||||
@specialize[@name=keyword]<Identifier, "do"> Params colon newlineOrSemicolon block @specialize[@name=keyword]<Identifier, "end">
|
||||
Fn Params colon newlineOrSemicolon block end
|
||||
}
|
||||
|
||||
IfExpr {
|
||||
|
|
@ -105,19 +110,19 @@ IfExpr {
|
|||
}
|
||||
|
||||
singleLineIf {
|
||||
@specialize[@name=keyword]<Identifier, "if"> (ConditionalOp | expression) colon ThenBlock { consumeToTerminator }
|
||||
"if" (ConditionalOp | expression) colon ThenBlock { consumeToTerminator }
|
||||
}
|
||||
|
||||
multilineIf {
|
||||
@specialize[@name=keyword]<Identifier, "if"> (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock ElsifExpr* ElseExpr? @specialize[@name=keyword]<Identifier, "end">
|
||||
"if" (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock ElsifExpr* ElseExpr? end
|
||||
}
|
||||
|
||||
ElsifExpr {
|
||||
@specialize[@name=keyword]<Identifier, "elsif"> (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock
|
||||
"elsif" (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock
|
||||
}
|
||||
|
||||
ElseExpr {
|
||||
@specialize[@name=keyword]<Identifier, "else"> colon newlineOrSemicolon ThenBlock
|
||||
"else" colon newlineOrSemicolon ThenBlock
|
||||
}
|
||||
|
||||
ThenBlock {
|
||||
|
|
@ -158,14 +163,9 @@ expression {
|
|||
expressionWithoutIdentifier | DotGet | Identifier
|
||||
}
|
||||
|
||||
|
||||
@local tokens {
|
||||
dot { "." }
|
||||
}
|
||||
|
||||
@skip {} {
|
||||
DotGet {
|
||||
IdentifierBeforeDot dot Identifier
|
||||
IdentifierBeforeDot "." Identifier
|
||||
}
|
||||
|
||||
String { "'" stringContent* "'" }
|
||||
|
|
|
|||
|
|
@ -34,9 +34,10 @@ export const
|
|||
Null = 32,
|
||||
DotGet = 33,
|
||||
FunctionDef = 34,
|
||||
keyword = 50,
|
||||
Fn = 35,
|
||||
Params = 36,
|
||||
colon = 37,
|
||||
end = 38,
|
||||
Underscore = 39,
|
||||
NamedArg = 40,
|
||||
NamedArgPrefix = 41,
|
||||
|
|
|
|||
|
|
@ -1,27 +1,26 @@
|
|||
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
||||
import {LRParser, LocalTokenGroup} from "@lezer/lr"
|
||||
import {LRParser} 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",
|
||||
states: ".jQVQrOOO#XQuO'#CrO$RQRO'#CsO$aQRO'#DmO$xQrO'#CqO%gOWO'#CuOOQq'#Dq'#DqO%uOQO'#C}O%zQRO'#DpO&cQrO'#D|OOQp'#DO'#DOOOQO'#Dn'#DnO&kQQO'#DmO&yQrO'#EQOOQO'#DX'#DXO'hQRO'#DaOOQO'#Dm'#DmO'mQQO'#DlOOQp'#Dl'#DlOOQp'#Db'#DbQVQrOOOOQq'#Dp'#DpOOQp'#Cp'#CpO'uQrO'#DUOOQp'#Do'#DoOOQp'#Dc'#DcO(PQtO,59ZO&yQrO,59_O&yQrO,59_O)XQRO'#CsO)iQRO,59]O)zQRO,59]O)uQQO,59]O*uQQO,59]O*}QrO'#CwO+VQ`O'#CxOOOO'#Du'#DuOOOO'#Dd'#DdO+kOWO,59aOOQq,59a,59aO+yOpO,59iOOQp'#De'#DeO,OQrO'#DQO,WQQO,5:hO,]QrO'#DgO,bQQO,59YO,sQRO,5:lO,zQQO,5:lO-PQrO,59{OOQp,5:W,5:WOOQp-E7`-E7`OOQp,59p,59pOOQp-E7a-E7aOOQP1G.y1G.yO-^QRO1G.yO&yQrO,59`O&yQrO,59`OOQq1G.w1G.wOOOO,59c,59cOOOO,59d,59dOOOO-E7b-E7bOOQq1G.{1G.{OOQq1G/T1G/TOOQp-E7c-E7cO-xQrO1G0SO!QQtO'#CrOOQO,5:R,5:ROOQO-E7e-E7eO.YQrO1G0WOOQO1G/g1G/gOOQO1G.z1G.zO.jQRO1G.zO.tQQO7+%nO.yQrO7+%oOOQO'#DZ'#DZOOQO7+%r7+%rO/ZQrO7+%sOOQp<<IY<<IYO/qQQO'#DfO/vQrO'#EPO0^QQO<<IZOOQO'#D['#D[O0cQQO<<I_OOQp,5:Q,5:QOOQp-E7d-E7dOOQpAN>uAN>uO&yQrO'#D]OOQO'#Dh'#DhO0nQQOAN>yO0yQQO'#D_OOQOAN>yAN>yO1OQQOAN>yO1TQRO,59wO1[QQO,59wOOQO-E7f-E7fOOQOG24eG24eO1aQQOG24eO1fQQO,59yO1kQQO1G/cOOQOLD*PLD*PO.yQrO1G/eO/ZQrO7+$}OOQO7+%P7+%POOQO<<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 ElsifExpr 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 end Underscore NamedArg NamedArgPrefix operator IfExpr keyword ThenBlock ThenBlock ElsifExpr keyword ElseExpr keyword Assign",
|
||||
maxTerm: 84,
|
||||
context: trackScope,
|
||||
nodeProps: [
|
||||
["closedBy", 37,"end"]
|
||||
["closedBy", 37,"end"],
|
||||
["openedBy", 38,"colon"]
|
||||
],
|
||||
propSources: [highlighting],
|
||||
skippedNodes: [0],
|
||||
repeatNodeCount: 7,
|
||||
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)],
|
||||
tokenData: "JX~R|OX#{XY$jYZ%TZp#{pq$jqt#{tu%nuw#{wx%sxy%xyz&cz{#{{|&||}#{}!O&|!O!P)p!P!Q*Z!Q!['k![!]2v!]!^%T!^#O#{#O#P3a#P#R#{#R#S3f#S#T#{#T#X4P#X#Y5_#Y#Z<e#Z#]4P#]#^Ap#^#b4P#b#cCb#c#f4P#f#gFz#g#h4P#h#iGq#i#o4P#o#p#{#p#qIi#q;'S#{;'S;=`$d<%l~#{~O#{~~JSS$QUjSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{S$gP;=`<%l#{_$qUjS!_ZOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{V%[UjS!rROt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{~%sO!j~~%xO!h~V&PUjS!fROt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{V&jUjS!gROt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{V'RWjSOt#{uw#{x!Q#{!Q!['k![#O#{#P;'S#{;'S;=`$d<%lO#{V'rYjSmROt#{uw#{x!O#{!O!P(b!P!Q#{!Q!['k![#O#{#P;'S#{;'S;=`$d<%lO#{V(gWjSOt#{uw#{x!Q#{!Q![)P![#O#{#P;'S#{;'S;=`$d<%lO#{V)WWjSmROt#{uw#{x!Q#{!Q![)P![#O#{#P;'S#{;'S;=`$d<%lO#{T)wU!oPjSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{V*`WjSOt#{uw#{x!P#{!P!Q*x!Q#O#{#P;'S#{;'S;=`$d<%lO#{V*}^jSOY+yYZ#{Zt+ytu,|uw+ywx,|x!P+y!P!Q#{!Q!}+y!}#O1o#O#P/[#P;'S+y;'S;=`2p<%lO+yV,Q^jSoROY+yYZ#{Zt+ytu,|uw+ywx,|x!P+y!P!Q/q!Q!}+y!}#O1o#O#P/[#P;'S+y;'S;=`2p<%lO+yR-RXoROY,|Z!P,|!P!Q-n!Q!},|!}#O.]#O#P/[#P;'S,|;'S;=`/k<%lO,|R-qP!P!Q-tR-yUoR#Z#[-t#]#^-t#a#b-t#g#h-t#i#j-t#m#n-tR.`VOY.]Z#O.]#O#P.u#P#Q,|#Q;'S.];'S;=`/U<%lO.]R.xSOY.]Z;'S.];'S;=`/U<%lO.]R/XP;=`<%l.]R/_SOY,|Z;'S,|;'S;=`/k<%lO,|R/nP;=`<%l,|V/vWjSOt#{uw#{x!P#{!P!Q0`!Q#O#{#P;'S#{;'S;=`$d<%lO#{V0gbjSoROt#{uw#{x#O#{#P#Z#{#Z#[0`#[#]#{#]#^0`#^#a#{#a#b0`#b#g#{#g#h0`#h#i#{#i#j0`#j#m#{#m#n0`#n;'S#{;'S;=`$d<%lO#{V1t[jSOY1oYZ#{Zt1otu.]uw1owx.]x#O1o#O#P.u#P#Q+y#Q;'S1o;'S;=`2j<%lO1oV2mP;=`<%l1oV2sP;=`<%l+yT2}UjSuPOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{~3fO!k~V3mUjSwROt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U4UYjSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#o4P#o;'S#{;'S;=`$d<%lO#{U4{UyQjSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{V5d^jSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#`4P#`#a6`#a#b4P#b#c:s#c#o4P#o;'S#{;'S;=`$d<%lO#{V6e[jSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#g4P#g#h7Z#h#o4P#o;'S#{;'S;=`$d<%lO#{V7`^jSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#X4P#X#Y8[#Y#]4P#]#^9R#^#o4P#o;'S#{;'S;=`$d<%lO#{V8cY!SPjSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#o4P#o;'S#{;'S;=`$d<%lO#{V9W[jSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#Y4P#Y#Z9|#Z#o4P#o;'S#{;'S;=`$d<%lO#{V:TY!QPjSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#o4P#o;'S#{;'S;=`$d<%lO#{V:x[jSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#W4P#W#X;n#X#o4P#o;'S#{;'S;=`$d<%lO#{V;uYjSvROt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#o4P#o;'S#{;'S;=`$d<%lO#{V<j]jSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#U=c#U#b4P#b#c@y#c#o4P#o;'S#{;'S;=`$d<%lO#{V=h[jSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#`4P#`#a>^#a#o4P#o;'S#{;'S;=`$d<%lO#{V>c[jSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#g4P#g#h?X#h#o4P#o;'S#{;'S;=`$d<%lO#{V?^[jSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#X4P#X#Y@S#Y#o4P#o;'S#{;'S;=`$d<%lO#{V@ZYnRjSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#o4P#o;'S#{;'S;=`$d<%lO#{VAQYsRjSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#o4P#o;'S#{;'S;=`$d<%lO#{VAu[jSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#Y4P#Y#ZBk#Z#o4P#o;'S#{;'S;=`$d<%lO#{VBrY|PjSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#o4P#o;'S#{;'S;=`$d<%lO#{_Ci[!lWjSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#i4P#i#jD_#j#o4P#o;'S#{;'S;=`$d<%lO#{VDd[jSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#`4P#`#aEY#a#o4P#o;'S#{;'S;=`$d<%lO#{VE_[jSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#`4P#`#aFT#a#o4P#o;'S#{;'S;=`$d<%lO#{VF[YpRjSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#o4P#o;'S#{;'S;=`$d<%lO#{^GRY!nWjSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#o4P#o;'S#{;'S;=`$d<%lO#{_Gx[!mWjSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#f4P#f#gHn#g#o4P#o;'S#{;'S;=`$d<%lO#{VHs[jSOt#{uw#{x!_#{!_!`4t!`#O#{#P#T#{#T#i4P#i#j?X#j#o4P#o;'S#{;'S;=`$d<%lO#{VIpUzRjSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{~JXO!v~",
|
||||
tokenizers: [operatorTokenizer, 0, 1, 2, 3, tokenizer],
|
||||
topRules: {"Program":[0,17]},
|
||||
specialized: [{term: 13, get: (value: keyof typeof spec_Identifier) => spec_Identifier[value] || -1}],
|
||||
tokenPrec: 768
|
||||
})
|
||||
|
|
|
|||
|
|
@ -286,12 +286,12 @@ describe('Assign', () => {
|
|||
})
|
||||
|
||||
test('parses assignment with functions', () => {
|
||||
expect('add = do a b: a + b end').toMatchTree(`
|
||||
expect('add = fn a b: a + b end').toMatchTree(`
|
||||
Assign
|
||||
AssignableIdentifier add
|
||||
Eq =
|
||||
FunctionDef
|
||||
keyword do
|
||||
keyword fn
|
||||
Params
|
||||
AssignableIdentifier a
|
||||
AssignableIdentifier b
|
||||
|
|
@ -300,7 +300,7 @@ describe('Assign', () => {
|
|||
Identifier a
|
||||
Plus +
|
||||
Identifier b
|
||||
keyword end`)
|
||||
end end`)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ describe('if/elsif/else', () => {
|
|||
ThenBlock
|
||||
FunctionCallOrIdentifier
|
||||
Identifier yes
|
||||
keyword end
|
||||
end end
|
||||
`)
|
||||
})
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ describe('if/elsif/else', () => {
|
|||
ThenBlock
|
||||
FunctionCallOrIdentifier
|
||||
Identifier y
|
||||
keyword end
|
||||
end end
|
||||
`)
|
||||
})
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ describe('if/elsif/else', () => {
|
|||
ThenBlock
|
||||
FunctionCallOrIdentifier
|
||||
Identifier y
|
||||
keyword end
|
||||
end end
|
||||
`)
|
||||
})
|
||||
|
||||
|
|
@ -133,21 +133,7 @@ describe('if/elsif/else', () => {
|
|||
ThenBlock
|
||||
FunctionCallOrIdentifier
|
||||
Identifier oh-no
|
||||
keyword end
|
||||
`)
|
||||
})
|
||||
|
||||
test('does not parse identifiers that start with if', () => {
|
||||
expect('iffy = if true: 2').toMatchTree(`
|
||||
Assign
|
||||
AssignableIdentifier iffy
|
||||
Eq =
|
||||
IfExpr
|
||||
keyword if
|
||||
Boolean true
|
||||
colon :
|
||||
ThenBlock
|
||||
Number 2
|
||||
end end
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -27,41 +27,41 @@ describe('DotGet', () => {
|
|||
})
|
||||
|
||||
test('function parameters are in scope within function body', () => {
|
||||
expect('do config: config.path end').toMatchTree(`
|
||||
expect('fn config: config.path end').toMatchTree(`
|
||||
FunctionDef
|
||||
keyword do
|
||||
keyword fn
|
||||
Params
|
||||
AssignableIdentifier config
|
||||
colon :
|
||||
DotGet
|
||||
IdentifierBeforeDot config
|
||||
Identifier path
|
||||
keyword end
|
||||
end end
|
||||
`)
|
||||
})
|
||||
|
||||
test('parameters out of scope outside function', () => {
|
||||
expect('do x: x.prop end; x.prop').toMatchTree(`
|
||||
expect('fn x: x.prop end; x.prop').toMatchTree(`
|
||||
FunctionDef
|
||||
keyword do
|
||||
keyword fn
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
colon :
|
||||
DotGet
|
||||
IdentifierBeforeDot x
|
||||
Identifier prop
|
||||
keyword end
|
||||
end end
|
||||
Word x.prop
|
||||
`)
|
||||
})
|
||||
|
||||
test('multiple parameters work correctly', () => {
|
||||
expect(`do x y:
|
||||
expect(`fn x y:
|
||||
x.foo
|
||||
y.bar
|
||||
end`).toMatchTree(`
|
||||
FunctionDef
|
||||
keyword do
|
||||
keyword fn
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
AssignableIdentifier y
|
||||
|
|
@ -72,17 +72,17 @@ end`).toMatchTree(`
|
|||
DotGet
|
||||
IdentifierBeforeDot y
|
||||
Identifier bar
|
||||
keyword end
|
||||
end end
|
||||
`)
|
||||
})
|
||||
|
||||
test('nested functions with scope isolation', () => {
|
||||
expect(`do x:
|
||||
expect(`fn x:
|
||||
x.outer
|
||||
do y: y.inner end
|
||||
fn y: y.inner end
|
||||
end`).toMatchTree(`
|
||||
FunctionDef
|
||||
keyword do
|
||||
keyword fn
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
colon :
|
||||
|
|
@ -90,15 +90,15 @@ end`).toMatchTree(`
|
|||
IdentifierBeforeDot x
|
||||
Identifier outer
|
||||
FunctionDef
|
||||
keyword do
|
||||
keyword fn
|
||||
Params
|
||||
AssignableIdentifier y
|
||||
colon :
|
||||
DotGet
|
||||
IdentifierBeforeDot y
|
||||
Identifier inner
|
||||
keyword end
|
||||
keyword end
|
||||
end end
|
||||
end end
|
||||
`)
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -56,21 +56,21 @@ describe('calling functions', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('Do', () => {
|
||||
describe('Fn', () => {
|
||||
test('parses function no parameters', () => {
|
||||
expect('do: 1 end').toMatchTree(`
|
||||
expect('fn: 1 end').toMatchTree(`
|
||||
FunctionDef
|
||||
keyword do
|
||||
keyword fn
|
||||
Params
|
||||
colon :
|
||||
Number 1
|
||||
keyword end`)
|
||||
end end`)
|
||||
})
|
||||
|
||||
test('parses function with single parameter', () => {
|
||||
expect('do x: x + 1 end').toMatchTree(`
|
||||
expect('fn x: x + 1 end').toMatchTree(`
|
||||
FunctionDef
|
||||
keyword do
|
||||
keyword fn
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
colon :
|
||||
|
|
@ -78,13 +78,13 @@ describe('Do', () => {
|
|||
Identifier x
|
||||
Plus +
|
||||
Number 1
|
||||
keyword end`)
|
||||
end end`)
|
||||
})
|
||||
|
||||
test('parses function with multiple parameters', () => {
|
||||
expect('do x y: x * y end').toMatchTree(`
|
||||
expect('fn x y: x * y end').toMatchTree(`
|
||||
FunctionDef
|
||||
keyword do
|
||||
keyword fn
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
AssignableIdentifier y
|
||||
|
|
@ -93,16 +93,16 @@ describe('Do', () => {
|
|||
Identifier x
|
||||
Star *
|
||||
Identifier y
|
||||
keyword end`)
|
||||
end end`)
|
||||
})
|
||||
|
||||
test('parses multiline function with multiple statements', () => {
|
||||
expect(`do x y:
|
||||
expect(`fn x y:
|
||||
x * y
|
||||
x + 9
|
||||
end`).toMatchTree(`
|
||||
FunctionDef
|
||||
keyword do
|
||||
keyword fn
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
AssignableIdentifier y
|
||||
|
|
@ -115,36 +115,6 @@ end`).toMatchTree(`
|
|||
Identifier x
|
||||
Plus +
|
||||
Number 9
|
||||
keyword end`)
|
||||
})
|
||||
|
||||
test('does not parse identifiers that start with fn', () => {
|
||||
expect('fnnn = do x: x end').toMatchTree(`
|
||||
Assign
|
||||
AssignableIdentifier fnnn
|
||||
Eq =
|
||||
FunctionDef
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
colon :
|
||||
FunctionCallOrIdentifier
|
||||
Identifier x
|
||||
keyword end`)
|
||||
})
|
||||
|
||||
test('does not parse identifiers that start with end', () => {
|
||||
expect('enddd = do x: x end').toMatchTree(`
|
||||
Assign
|
||||
AssignableIdentifier enddd
|
||||
Eq =
|
||||
FunctionDef
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
colon :
|
||||
FunctionCallOrIdentifier
|
||||
Identifier x
|
||||
keyword end`)
|
||||
end end`)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ describe('multiline', () => {
|
|||
|
||||
test('parses multiline functions', () => {
|
||||
expect(`
|
||||
add = do a b:
|
||||
add = fn a b:
|
||||
result = a + b
|
||||
result
|
||||
end
|
||||
|
|
@ -24,7 +24,7 @@ describe('multiline', () => {
|
|||
AssignableIdentifier add
|
||||
Eq =
|
||||
FunctionDef
|
||||
keyword do
|
||||
keyword fn
|
||||
Params
|
||||
AssignableIdentifier a
|
||||
AssignableIdentifier b
|
||||
|
|
@ -39,7 +39,7 @@ describe('multiline', () => {
|
|||
FunctionCallOrIdentifier
|
||||
Identifier result
|
||||
|
||||
keyword end
|
||||
end end
|
||||
FunctionCall
|
||||
Identifier add
|
||||
PositionalArg
|
||||
|
|
@ -53,7 +53,7 @@ describe('multiline', () => {
|
|||
3
|
||||
|
||||
|
||||
do x y:
|
||||
fn x y:
|
||||
x
|
||||
end
|
||||
|
||||
|
|
@ -61,14 +61,14 @@ end
|
|||
Number 3
|
||||
|
||||
FunctionDef
|
||||
keyword do
|
||||
keyword fn
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
AssignableIdentifier y
|
||||
colon :
|
||||
FunctionCallOrIdentifier
|
||||
Identifier x
|
||||
keyword end
|
||||
end end
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ describe('pipe expressions', () => {
|
|||
})
|
||||
|
||||
test('pipe with inline function', () => {
|
||||
expect('items | each do x: x end').toMatchTree(`
|
||||
expect('items | each fn x: x end').toMatchTree(`
|
||||
PipeExpr
|
||||
FunctionCallOrIdentifier
|
||||
Identifier items
|
||||
|
|
@ -75,13 +75,13 @@ describe('pipe expressions', () => {
|
|||
Identifier each
|
||||
PositionalArg
|
||||
FunctionDef
|
||||
keyword do
|
||||
keyword fn
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
colon :
|
||||
FunctionCallOrIdentifier
|
||||
Identifier x
|
||||
keyword end
|
||||
end end
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user