Compare commits
2 Commits
66671970e0
...
d306d58b2f
| Author | SHA1 | Date | |
|---|---|---|---|
| d306d58b2f | |||
| 7077762738 |
|
|
@ -63,26 +63,26 @@ describe('compiler', () => {
|
|||
})
|
||||
|
||||
test('function', () => {
|
||||
expect(`fn a b: a + b end`).toEvaluateTo(Function)
|
||||
expect(`do a b: a + b end`).toEvaluateTo(Function)
|
||||
})
|
||||
|
||||
test('function call', () => {
|
||||
expect(`add = fn a b: a + b end; add 2 9`).toEvaluateTo(11)
|
||||
expect(`add = do a b: a + b end; add 2 9`).toEvaluateTo(11)
|
||||
})
|
||||
|
||||
test('function call with named args', () => {
|
||||
expect(`minus = fn a b: a - b end; minus b=2 a=9`).toEvaluateTo(7)
|
||||
expect(`minus = do a b: a - b end; minus b=2 a=9`).toEvaluateTo(7)
|
||||
})
|
||||
|
||||
test('function call with named and positional args', () => {
|
||||
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)
|
||||
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)
|
||||
})
|
||||
|
||||
test('function call with no args', () => {
|
||||
expect(`bloop = fn: 'bloop' end; bloop`).toEvaluateTo('bloop')
|
||||
expect(`bloop = do: 'bloop' end; bloop`).toEvaluateTo('bloop')
|
||||
})
|
||||
|
||||
test('simple conditionals', () => {
|
||||
|
|
@ -150,7 +150,7 @@ describe('errors', () => {
|
|||
describe('multiline tests', () => {
|
||||
test('multiline function', () => {
|
||||
expect(`
|
||||
add = fn a b:
|
||||
add = do 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 = fn x: x * 2 end
|
||||
double = do 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 = fn x: x + 1 end
|
||||
double = fn x: x * 2 end
|
||||
minus-point-one = fn x: x - 0.1 end
|
||||
add-one = do x: x + 1 end
|
||||
double = do x: x * 2 end
|
||||
minus-point-one = do 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 = fn a b: a * b end
|
||||
get-five = fn: 5 end
|
||||
multiply = do a b: a * b end
|
||||
get-five = do: 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 = fn x: x + 10 end
|
||||
process = do 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 = fn x: x + 10 end
|
||||
add-ten = do 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 = fn a b: a / b end
|
||||
get-ten = fn: 10 end
|
||||
divide = do a b: a / b end
|
||||
get-ten = do: 10 end
|
||||
get-ten | divide 2 b=_`).toEvaluateTo(0.2)
|
||||
|
||||
expect(`
|
||||
divide = fn a b: a / b end
|
||||
get-ten = fn: 10 end
|
||||
divide = do a b: a / b end
|
||||
get-ten = do: 10 end
|
||||
get-ten | divide b=_ 2`).toEvaluateTo(0.2)
|
||||
|
||||
expect(`
|
||||
divide = fn a b: a / b end
|
||||
get-ten = fn: 10 end
|
||||
divide = do a b: a / b end
|
||||
get-ten = do: 10 end
|
||||
get-ten | divide 2 a=_`).toEvaluateTo(5)
|
||||
|
||||
expect(`
|
||||
divide = fn a b: a / b end
|
||||
get-ten = fn: 10 end
|
||||
divide = do a b: a / b end
|
||||
get-ten = do: 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 = fn a b: a - b end
|
||||
div = fn a b: a / b end
|
||||
sub = do a b: a - b end
|
||||
div = do 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 = (fn: () => CommandShape[]) => {
|
||||
export const setCommandSource = (do: () => CommandShape[]) => {
|
||||
commandSource = fn
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,14 +21,9 @@
|
|||
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]
|
||||
|
||||
}
|
||||
|
|
@ -98,11 +93,11 @@ FunctionDef {
|
|||
}
|
||||
|
||||
singleLineFunctionDef {
|
||||
Fn Params colon consumeToTerminator end
|
||||
@specialize[@name=keyword]<Identifier, "do"> Params colon consumeToTerminator @specialize[@name=keyword]<Identifier, "end">
|
||||
}
|
||||
|
||||
multilineFunctionDef {
|
||||
Fn Params colon newlineOrSemicolon block end
|
||||
@specialize[@name=keyword]<Identifier, "do"> Params colon newlineOrSemicolon block @specialize[@name=keyword]<Identifier, "end">
|
||||
}
|
||||
|
||||
IfExpr {
|
||||
|
|
@ -110,19 +105,19 @@ IfExpr {
|
|||
}
|
||||
|
||||
singleLineIf {
|
||||
"if" (ConditionalOp | expression) colon ThenBlock { consumeToTerminator }
|
||||
@specialize[@name=keyword]<Identifier, "if"> (ConditionalOp | expression) colon ThenBlock { consumeToTerminator }
|
||||
}
|
||||
|
||||
multilineIf {
|
||||
"if" (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock ElsifExpr* ElseExpr? end
|
||||
@specialize[@name=keyword]<Identifier, "if"> (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock ElsifExpr* ElseExpr? @specialize[@name=keyword]<Identifier, "end">
|
||||
}
|
||||
|
||||
ElsifExpr {
|
||||
"elsif" (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock
|
||||
@specialize[@name=keyword]<Identifier, "elsif"> (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock
|
||||
}
|
||||
|
||||
ElseExpr {
|
||||
"else" colon newlineOrSemicolon ThenBlock
|
||||
@specialize[@name=keyword]<Identifier, "else"> colon newlineOrSemicolon ThenBlock
|
||||
}
|
||||
|
||||
ThenBlock {
|
||||
|
|
@ -163,9 +158,14 @@ expression {
|
|||
expressionWithoutIdentifier | DotGet | Identifier
|
||||
}
|
||||
|
||||
|
||||
@local tokens {
|
||||
dot { "." }
|
||||
}
|
||||
|
||||
@skip {} {
|
||||
DotGet {
|
||||
IdentifierBeforeDot "." Identifier
|
||||
IdentifierBeforeDot dot Identifier
|
||||
}
|
||||
|
||||
String { "'" stringContent* "'" }
|
||||
|
|
|
|||
|
|
@ -34,10 +34,9 @@ export const
|
|||
Null = 32,
|
||||
DotGet = 33,
|
||||
FunctionDef = 34,
|
||||
Fn = 35,
|
||||
keyword = 50,
|
||||
Params = 36,
|
||||
colon = 37,
|
||||
end = 38,
|
||||
Underscore = 39,
|
||||
NamedArg = 40,
|
||||
NamedArgPrefix = 41,
|
||||
|
|
|
|||
|
|
@ -1,26 +1,27 @@
|
|||
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
||||
import {LRParser} from "@lezer/lr"
|
||||
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: ".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",
|
||||
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 end 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 keyword Underscore NamedArg NamedArgPrefix operator IfExpr keyword ThenBlock ThenBlock ElsifExpr keyword ElseExpr keyword Assign",
|
||||
maxTerm: 84,
|
||||
context: trackScope,
|
||||
nodeProps: [
|
||||
["closedBy", 37,"end"],
|
||||
["openedBy", 38,"colon"]
|
||||
["closedBy", 37,"end"]
|
||||
],
|
||||
propSources: [highlighting],
|
||||
skippedNodes: [0],
|
||||
repeatNodeCount: 7,
|
||||
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],
|
||||
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
|
||||
})
|
||||
|
|
|
|||
|
|
@ -286,12 +286,12 @@ describe('Assign', () => {
|
|||
})
|
||||
|
||||
test('parses assignment with functions', () => {
|
||||
expect('add = fn a b: a + b end').toMatchTree(`
|
||||
expect('add = do a b: a + b end').toMatchTree(`
|
||||
Assign
|
||||
AssignableIdentifier add
|
||||
Eq =
|
||||
FunctionDef
|
||||
keyword fn
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier a
|
||||
AssignableIdentifier b
|
||||
|
|
@ -300,7 +300,7 @@ describe('Assign', () => {
|
|||
Identifier a
|
||||
Plus +
|
||||
Identifier b
|
||||
end end`)
|
||||
keyword end`)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ describe('if/elsif/else', () => {
|
|||
ThenBlock
|
||||
FunctionCallOrIdentifier
|
||||
Identifier yes
|
||||
end end
|
||||
keyword end
|
||||
`)
|
||||
})
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ describe('if/elsif/else', () => {
|
|||
ThenBlock
|
||||
FunctionCallOrIdentifier
|
||||
Identifier y
|
||||
end end
|
||||
keyword end
|
||||
`)
|
||||
})
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ describe('if/elsif/else', () => {
|
|||
ThenBlock
|
||||
FunctionCallOrIdentifier
|
||||
Identifier y
|
||||
end end
|
||||
keyword end
|
||||
`)
|
||||
})
|
||||
|
||||
|
|
@ -133,7 +133,21 @@ describe('if/elsif/else', () => {
|
|||
ThenBlock
|
||||
FunctionCallOrIdentifier
|
||||
Identifier oh-no
|
||||
end end
|
||||
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
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -27,41 +27,41 @@ describe('DotGet', () => {
|
|||
})
|
||||
|
||||
test('function parameters are in scope within function body', () => {
|
||||
expect('fn config: config.path end').toMatchTree(`
|
||||
expect('do config: config.path end').toMatchTree(`
|
||||
FunctionDef
|
||||
keyword fn
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier config
|
||||
colon :
|
||||
DotGet
|
||||
IdentifierBeforeDot config
|
||||
Identifier path
|
||||
end end
|
||||
keyword end
|
||||
`)
|
||||
})
|
||||
|
||||
test('parameters out of scope outside function', () => {
|
||||
expect('fn x: x.prop end; x.prop').toMatchTree(`
|
||||
expect('do x: x.prop end; x.prop').toMatchTree(`
|
||||
FunctionDef
|
||||
keyword fn
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
colon :
|
||||
DotGet
|
||||
IdentifierBeforeDot x
|
||||
Identifier prop
|
||||
end end
|
||||
keyword end
|
||||
Word x.prop
|
||||
`)
|
||||
})
|
||||
|
||||
test('multiple parameters work correctly', () => {
|
||||
expect(`fn x y:
|
||||
expect(`do x y:
|
||||
x.foo
|
||||
y.bar
|
||||
end`).toMatchTree(`
|
||||
FunctionDef
|
||||
keyword fn
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
AssignableIdentifier y
|
||||
|
|
@ -72,17 +72,17 @@ end`).toMatchTree(`
|
|||
DotGet
|
||||
IdentifierBeforeDot y
|
||||
Identifier bar
|
||||
end end
|
||||
keyword end
|
||||
`)
|
||||
})
|
||||
|
||||
test('nested functions with scope isolation', () => {
|
||||
expect(`fn x:
|
||||
expect(`do x:
|
||||
x.outer
|
||||
fn y: y.inner end
|
||||
do y: y.inner end
|
||||
end`).toMatchTree(`
|
||||
FunctionDef
|
||||
keyword fn
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
colon :
|
||||
|
|
@ -90,15 +90,15 @@ end`).toMatchTree(`
|
|||
IdentifierBeforeDot x
|
||||
Identifier outer
|
||||
FunctionDef
|
||||
keyword fn
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier y
|
||||
colon :
|
||||
DotGet
|
||||
IdentifierBeforeDot y
|
||||
Identifier inner
|
||||
end end
|
||||
end end
|
||||
keyword end
|
||||
keyword end
|
||||
`)
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -56,21 +56,21 @@ describe('calling functions', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('Fn', () => {
|
||||
describe('Do', () => {
|
||||
test('parses function no parameters', () => {
|
||||
expect('fn: 1 end').toMatchTree(`
|
||||
expect('do: 1 end').toMatchTree(`
|
||||
FunctionDef
|
||||
keyword fn
|
||||
keyword do
|
||||
Params
|
||||
colon :
|
||||
Number 1
|
||||
end end`)
|
||||
keyword end`)
|
||||
})
|
||||
|
||||
test('parses function with single parameter', () => {
|
||||
expect('fn x: x + 1 end').toMatchTree(`
|
||||
expect('do x: x + 1 end').toMatchTree(`
|
||||
FunctionDef
|
||||
keyword fn
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
colon :
|
||||
|
|
@ -78,13 +78,13 @@ describe('Fn', () => {
|
|||
Identifier x
|
||||
Plus +
|
||||
Number 1
|
||||
end end`)
|
||||
keyword end`)
|
||||
})
|
||||
|
||||
test('parses function with multiple parameters', () => {
|
||||
expect('fn x y: x * y end').toMatchTree(`
|
||||
expect('do x y: x * y end').toMatchTree(`
|
||||
FunctionDef
|
||||
keyword fn
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
AssignableIdentifier y
|
||||
|
|
@ -93,16 +93,16 @@ describe('Fn', () => {
|
|||
Identifier x
|
||||
Star *
|
||||
Identifier y
|
||||
end end`)
|
||||
keyword end`)
|
||||
})
|
||||
|
||||
test('parses multiline function with multiple statements', () => {
|
||||
expect(`fn x y:
|
||||
expect(`do x y:
|
||||
x * y
|
||||
x + 9
|
||||
end`).toMatchTree(`
|
||||
FunctionDef
|
||||
keyword fn
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
AssignableIdentifier y
|
||||
|
|
@ -115,6 +115,36 @@ end`).toMatchTree(`
|
|||
Identifier x
|
||||
Plus +
|
||||
Number 9
|
||||
end end`)
|
||||
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`)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ describe('multiline', () => {
|
|||
|
||||
test('parses multiline functions', () => {
|
||||
expect(`
|
||||
add = fn a b:
|
||||
add = do a b:
|
||||
result = a + b
|
||||
result
|
||||
end
|
||||
|
|
@ -24,7 +24,7 @@ describe('multiline', () => {
|
|||
AssignableIdentifier add
|
||||
Eq =
|
||||
FunctionDef
|
||||
keyword fn
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier a
|
||||
AssignableIdentifier b
|
||||
|
|
@ -39,7 +39,7 @@ describe('multiline', () => {
|
|||
FunctionCallOrIdentifier
|
||||
Identifier result
|
||||
|
||||
end end
|
||||
keyword end
|
||||
FunctionCall
|
||||
Identifier add
|
||||
PositionalArg
|
||||
|
|
@ -53,7 +53,7 @@ describe('multiline', () => {
|
|||
3
|
||||
|
||||
|
||||
fn x y:
|
||||
do x y:
|
||||
x
|
||||
end
|
||||
|
||||
|
|
@ -61,14 +61,14 @@ end
|
|||
Number 3
|
||||
|
||||
FunctionDef
|
||||
keyword fn
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
AssignableIdentifier y
|
||||
colon :
|
||||
FunctionCallOrIdentifier
|
||||
Identifier x
|
||||
end end
|
||||
keyword end
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ describe('pipe expressions', () => {
|
|||
})
|
||||
|
||||
test('pipe with inline function', () => {
|
||||
expect('items | each fn x: x end').toMatchTree(`
|
||||
expect('items | each do x: x end').toMatchTree(`
|
||||
PipeExpr
|
||||
FunctionCallOrIdentifier
|
||||
Identifier items
|
||||
|
|
@ -75,13 +75,13 @@ describe('pipe expressions', () => {
|
|||
Identifier each
|
||||
PositionalArg
|
||||
FunctionDef
|
||||
keyword fn
|
||||
keyword do
|
||||
Params
|
||||
AssignableIdentifier x
|
||||
colon :
|
||||
FunctionCallOrIdentifier
|
||||
Identifier x
|
||||
end end
|
||||
keyword end
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user