Merge pull request 'DotGet function calls' (#9) from dotget-function-calls into main
Reviewed-on: #9
This commit is contained in:
commit
71fdafa72d
|
|
@ -70,9 +70,9 @@ export const getFunctionDefParts = (node: SyntaxNode, input: string) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const paramNames = getAllChildren(paramsNode).map((param) => {
|
const paramNames = getAllChildren(paramsNode).map((param) => {
|
||||||
if (param.type.id !== terms.AssignableIdentifier) {
|
if (param.type.id !== terms.Identifier) {
|
||||||
throw new CompilerError(
|
throw new CompilerError(
|
||||||
`FunctionDef params must be AssignableIdentifiers, got ${param.type.name}`,
|
`FunctionDef params must be Identifier, got ${param.type.name}`,
|
||||||
param.from,
|
param.from,
|
||||||
param.to
|
param.to
|
||||||
)
|
)
|
||||||
|
|
@ -219,9 +219,9 @@ export const getDotGetParts = (node: SyntaxNode, input: string) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (property.type.id !== terms.Identifier) {
|
if (property.type.id !== terms.Identifier && property.type.id !== terms.Number) {
|
||||||
throw new CompilerError(
|
throw new CompilerError(
|
||||||
`DotGet property must be an Identifier, got ${property.type.name}`,
|
`DotGet property must be an Identifier or Number, got ${property.type.name}`,
|
||||||
property.from,
|
property.from,
|
||||||
property.to
|
property.to
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -57,26 +57,30 @@ const readIdentifierText = (input: InputStream, start: number, end: number): str
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inParams = false
|
||||||
|
|
||||||
export const trackScope = new ContextTracker<TrackerContext>({
|
export const trackScope = new ContextTracker<TrackerContext>({
|
||||||
start: new TrackerContext(new Scope(null, new Set())),
|
start: new TrackerContext(new Scope(null, new Set())),
|
||||||
|
|
||||||
shift(context, term, stack, input) {
|
shift(context, term, stack, input) {
|
||||||
if (term !== terms.AssignableIdentifier) return context
|
if (term == terms.Do) inParams = true
|
||||||
|
|
||||||
const text = readIdentifierText(input, input.pos, stack.pos)
|
if (term === terms.AssignableIdentifier) {
|
||||||
return new TrackerContext(context.scope, [...context.pendingIds, text])
|
const text = readIdentifierText(input, input.pos, stack.pos)
|
||||||
|
return new TrackerContext(Scope.add(context.scope, text), context.pendingIds)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inParams && term === terms.Identifier) {
|
||||||
|
const text = readIdentifierText(input, input.pos, stack.pos)
|
||||||
|
return new TrackerContext(context.scope, [...context.pendingIds, text])
|
||||||
|
}
|
||||||
|
|
||||||
|
return context
|
||||||
},
|
},
|
||||||
|
|
||||||
reduce(context, term) {
|
reduce(context, term) {
|
||||||
// Add assignment variable to scope
|
|
||||||
if (term === terms.Assign) {
|
|
||||||
const varName = context.pendingIds.at(-1)
|
|
||||||
if (!varName) return context
|
|
||||||
return new TrackerContext(Scope.add(context.scope, varName), context.pendingIds.slice(0, -1))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push new scope and add all parameters
|
|
||||||
if (term === terms.Params) {
|
if (term === terms.Params) {
|
||||||
|
inParams = false
|
||||||
let newScope = context.scope.push()
|
let newScope = context.scope.push()
|
||||||
if (context.pendingIds.length > 0) {
|
if (context.pendingIds.length > 0) {
|
||||||
newScope = Scope.add(newScope, ...context.pendingIds)
|
newScope = Scope.add(newScope, ...context.pendingIds)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@external tokens tokenizer from "./tokenizer" { Identifier, AssignableIdentifier, Word, IdentifierBeforeDot }
|
@external tokens tokenizer from "./tokenizer" { Identifier, AssignableIdentifier, Word, IdentifierBeforeDot }
|
||||||
|
@external specialize {Identifier} specializeKeyword from "./tokenizer" { Do }
|
||||||
|
|
||||||
@precedence {
|
@precedence {
|
||||||
pipe @left,
|
pipe @left,
|
||||||
|
|
@ -47,7 +48,6 @@ item {
|
||||||
consumeToTerminator {
|
consumeToTerminator {
|
||||||
PipeExpr |
|
PipeExpr |
|
||||||
ambiguousFunctionCall |
|
ambiguousFunctionCall |
|
||||||
DotGet |
|
|
||||||
IfExpr |
|
IfExpr |
|
||||||
FunctionDef |
|
FunctionDef |
|
||||||
Assign |
|
Assign |
|
||||||
|
|
@ -64,7 +64,7 @@ pipeOperand {
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionCallOrIdentifier {
|
FunctionCallOrIdentifier {
|
||||||
Identifier
|
DotGet | Identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
ambiguousFunctionCall {
|
ambiguousFunctionCall {
|
||||||
|
|
@ -72,7 +72,7 @@ ambiguousFunctionCall {
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionCall {
|
FunctionCall {
|
||||||
Identifier arg+
|
(DotGet | Identifier) arg+
|
||||||
}
|
}
|
||||||
|
|
||||||
arg {
|
arg {
|
||||||
|
|
@ -93,11 +93,11 @@ FunctionDef {
|
||||||
}
|
}
|
||||||
|
|
||||||
singleLineFunctionDef {
|
singleLineFunctionDef {
|
||||||
@specialize[@name=keyword]<Identifier, "do"> Params colon consumeToTerminator @specialize[@name=keyword]<Identifier, "end">
|
Do Params colon consumeToTerminator @specialize[@name=keyword]<Identifier, "end">
|
||||||
}
|
}
|
||||||
|
|
||||||
multilineFunctionDef {
|
multilineFunctionDef {
|
||||||
@specialize[@name=keyword]<Identifier, "do"> Params colon newlineOrSemicolon block @specialize[@name=keyword]<Identifier, "end">
|
Do Params colon newlineOrSemicolon block @specialize[@name=keyword]<Identifier, "end">
|
||||||
}
|
}
|
||||||
|
|
||||||
IfExpr {
|
IfExpr {
|
||||||
|
|
@ -140,7 +140,7 @@ ConditionalOp {
|
||||||
}
|
}
|
||||||
|
|
||||||
Params {
|
Params {
|
||||||
AssignableIdentifier*
|
Identifier*
|
||||||
}
|
}
|
||||||
|
|
||||||
Assign {
|
Assign {
|
||||||
|
|
@ -169,7 +169,7 @@ expression {
|
||||||
|
|
||||||
@skip {} {
|
@skip {} {
|
||||||
DotGet {
|
DotGet {
|
||||||
IdentifierBeforeDot dot Identifier
|
IdentifierBeforeDot dot (Number | Identifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
String { "'" stringContent* "'" }
|
String { "'" stringContent* "'" }
|
||||||
|
|
|
||||||
|
|
@ -16,27 +16,28 @@ export const
|
||||||
AssignableIdentifier = 14,
|
AssignableIdentifier = 14,
|
||||||
Word = 15,
|
Word = 15,
|
||||||
IdentifierBeforeDot = 16,
|
IdentifierBeforeDot = 16,
|
||||||
Program = 17,
|
Do = 17,
|
||||||
PipeExpr = 18,
|
Program = 18,
|
||||||
FunctionCall = 19,
|
PipeExpr = 19,
|
||||||
PositionalArg = 20,
|
FunctionCall = 20,
|
||||||
ParenExpr = 21,
|
DotGet = 21,
|
||||||
FunctionCallOrIdentifier = 22,
|
Number = 22,
|
||||||
BinOp = 23,
|
PositionalArg = 23,
|
||||||
ConditionalOp = 24,
|
ParenExpr = 24,
|
||||||
FunctionDef = 25,
|
FunctionCallOrIdentifier = 25,
|
||||||
|
BinOp = 26,
|
||||||
|
ConditionalOp = 27,
|
||||||
|
FunctionDef = 28,
|
||||||
|
Params = 29,
|
||||||
|
colon = 30,
|
||||||
keyword = 50,
|
keyword = 50,
|
||||||
Params = 27,
|
String = 32,
|
||||||
colon = 28,
|
StringFragment = 33,
|
||||||
String = 30,
|
Interpolation = 34,
|
||||||
StringFragment = 31,
|
EscapeSeq = 35,
|
||||||
Interpolation = 32,
|
Boolean = 36,
|
||||||
EscapeSeq = 33,
|
Regex = 37,
|
||||||
Number = 34,
|
Null = 38,
|
||||||
Boolean = 35,
|
|
||||||
Regex = 36,
|
|
||||||
Null = 37,
|
|
||||||
DotGet = 38,
|
|
||||||
Underscore = 39,
|
Underscore = 39,
|
||||||
NamedArg = 40,
|
NamedArg = 40,
|
||||||
NamedArgPrefix = 41,
|
NamedArgPrefix = 41,
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,27 @@
|
||||||
// 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} from "./tokenizer"
|
import {tokenizer, specializeKeyword} from "./tokenizer"
|
||||||
import {trackScope} from "./scopeTracker"
|
import {trackScope} from "./scopeTracker"
|
||||||
import {highlighting} from "./highlight"
|
import {highlighting} from "./highlight"
|
||||||
const spec_Identifier = {__proto__:null,do:52, end:58, null:74, if:88, elseif:96, else:100}
|
const spec_Identifier = {__proto__:null,end:62, null:76, if:88, elseif:96, else:100}
|
||||||
export const parser = LRParser.deserialize({
|
export const parser = LRParser.deserialize({
|
||||||
version: 14,
|
version: 14,
|
||||||
states: ".vQYQbOOO#[QcO'#CrO$UQRO'#CsO$dQcO'#DnO${QbO'#DtOOQ`'#Cu'#CuO%TQbO'#CqO%uOSO'#CzOOQa'#Dr'#DrO&TOpO'#DSO&YQcO'#DqOOQ`'#Do'#DoO&qQbO'#DnO'PQbO'#EROOQ`'#DX'#DXO'nQRO'#DaOOQ`'#Dn'#DnO'sQQO'#DmOOQ`'#Dm'#DmOOQ`'#Db'#DbQYQbOOOOQa'#Dq'#DqOOQ`'#Cp'#CpO'{QbO'#DUOOQ`'#Dp'#DpOOQ`'#Dc'#DcO(VQbO,59ZO'PQbO,59_O'PQbO,59_OOQ`'#Dd'#DdO(sQbO'#CwO({QQO,5:`O)lQRO'#CsO)|QRO,59]O*_QRO,59]O*YQQO,59]O+YQQO,59]O+bQbO'#C|O+jQWO'#C}OOOO'#Dz'#DzOOOO'#Df'#DfO,OOSO,59fOOQa,59f,59fO,^O`O,59nO,cQbO'#DgO,hQbO,59YO,yQRO,5:mO-QQQO,5:mO-VQbO,59{OOQ`,5:X,5:XOOQ`-E7`-E7`OOQ`,59p,59pOOQ`-E7a-E7aOOQa1G.y1G.yO-aQcO1G.yOOQ`-E7b-E7bO-{QbO1G/zO'PQbO,59`O'PQbO,59`OOQa1G.w1G.wOOOO,59h,59hOOOO,59i,59iOOOO-E7d-E7dOOQa1G/Q1G/QOOQa1G/Y1G/YO!TQbO'#CrOOQ`,5:R,5:ROOQ`-E7e-E7eO.YQbO1G0XOOQ`1G/g1G/gO.gQbO7+%fO.lQbO7+%gOOQO1G.z1G.zO.|QRO1G.zOOQ`'#DZ'#DZO/WQbO7+%sO/]QbO7+%tOOQ`<<IQ<<IQOOQ`'#De'#DeO/sQQO'#DeO/xQbO'#DwO0`QbO<<IROOQ`<<I_<<I_OOQ`'#D['#D[O0eQbO<<I`OOQ`,5:P,5:POOQ`-E7c-E7cOOQ`AN>mAN>mO'PQbO'#D]OOQ`'#Dh'#DhO0pQbOAN>zO0{QQO'#D_OOQ`AN>zAN>zO1QQbOAN>zO1VQRO,59wO1^QQO,59wOOQ`-E7f-E7fOOQ`G24fG24fO1cQbOG24fO1hQQO,59yO1mQQO1G/cOOQ`LD*QLD*QO.lQbO1G/eO/]QbO7+$}OOQ`7+%P7+%POOQ`<<Hi<<Hi",
|
states: ".vQYQbOOO!TOpO'#CqO#aQcO'#CuO$ZQRO'#CvO$iQcO'#DnO%QQbO'#DuOOQ`'#Cx'#CxO%YQbO'#CtO%zOSO'#C|OOQa'#Ds'#DsO&YQcO'#DrOOQ`'#Do'#DoO&qQbO'#DnO'PQbO'#EROOQ`'#DX'#DXO'nQRO'#DaOOQ`'#Dn'#DnO'sQQO'#DmOOQ`'#Dm'#DmOOQ`'#Db'#DbQYQbOOO'{ObO,59]OOQa'#Dr'#DrOOQ`'#Cs'#CsO(TQbO'#DUOOQ`'#Dq'#DqOOQ`'#Dc'#DcO(_QbO,59[O'PQbO,59bO'PQbO,59bOOQ`'#Dd'#DdO({QbO'#CyO)TQQO,5:aO)tQRO'#CvO*UQRO,59`O*gQRO,59`O*bQQO,59`O+bQQO,59`O+jQbO'#DOO+rQWO'#DPOOOO'#D{'#D{OOOO'#Df'#DfO,WOSO,59hOOQa,59h,59hO,fQbO'#DgO,nQbO,59ZO-PQRO,5:mO-WQQO,5:mO-]QbO,59{OOQ`,5:X,5:XOOQ`-E7`-E7`OOQa1G.w1G.wOOQ`,59p,59pOOQ`-E7a-E7aOOQa1G.|1G.|O-gQcO1G.|OOQ`-E7b-E7bO.RQbO1G/{O'PQbO,59cO'PQbO,59cOOQa1G.z1G.zOOOO,59j,59jOOOO,59k,59kOOOO-E7d-E7dOOQa1G/S1G/SO!YQbO'#CuOOQ`,5:R,5:ROOQ`-E7e-E7eO.`QbO1G0XOOQ`1G/g1G/gO.mQbO7+%gO.rQbO7+%hOOQO1G.}1G.}O/SQRO1G.}OOQ`'#DZ'#DZO/^QbO7+%sO/cQbO7+%tOOQ`<<IR<<IROOQ`'#De'#DeO/yQQO'#DeO0OQbO'#DxO0fQbO<<ISOOQ`<<I_<<I_OOQ`'#D['#D[O0kQbO<<I`OOQ`,5:P,5:POOQ`-E7c-E7cOOQ`AN>nAN>nO'PQbO'#D]OOQ`'#Dh'#DhO0vQbOAN>zO1RQQO'#D_OOQ`AN>zAN>zO1WQbOAN>zO1]QRO,59wO1dQQO,59wOOQ`-E7f-E7fOOQ`G24fG24fO1iQbOG24fO1nQQO,59yO1sQQO1G/cOOQ`LD*QLD*QO.rQbO1G/eO/cQbO7+$}OOQ`7+%P7+%POOQ`<<Hi<<Hi",
|
||||||
stateData: "1u~O!_OS!`OS~O]PO^_O_WO`XOjSOrWOsWOtWOuWO|]O!gUO!jbO!mVO~O]eO_WO`XOjSOrWOsWOtWOuWOwfOygO!gUO!mVOzfX!jfX!wfX!lfXmfX~OP!eXQ!eXR!eXS!eXT!eXU!eXV!eXW!eXX!eXY!eXZ!eX[!eX~P!TOPkOQkORlOSlO~OPkOQkORlOSlO!j!bX!w!bXm!bX~O^mOlkP~O]PO_WO`XOjSOrWOsWOtWOuWO!gUO!mVO~OowO!mzO!ouO!pvO~O!t{O~OP!eXQ!eXR!eXS!eX!j!bX!w!bXm!bX~Oz|O!j!bX!w!bXm!bX~O]eO_WO`XOrWOsWOtWOuWO!gUO!mVO~OV!QO~O!j!RO!w!RO~OjSOw!TO~P'POjSOwfOygOzca!jca!wca!lcamca~P'PO^mOlkX~Ol!YO~OT![OU![OV!ZOW!ZOX!ZOY!ZOZ!ZO[!ZO~OPkOQkORlOSlO~P)QOPkOQkORlOSlO!l!]O~O!l!]OP!eXQ!eXR!eXS!eXT!eXU!eXV!eXW!eXX!eXY!eXZ!eX[!eX~Oz|O!l!]O~O]!^O!gUO~O!m!_O!o!_O!p!_O!q!_O!r!_O!s!_O~OowO!m!aO!ouO!pvO~O]!bO~O]!cO~Oz|O!jba!wba!lbamba~Ol!fO~P)QOl!fO~O^_O|]O~P%TOPkOQkORgiSgi!jgi!wgi!lgimgi~O^_O|]O!j!iO~P%TO^_O|]O!j!nO~P%TOm!oO~O^_O|]O!j!pOm!kP~P%TO!lhilhi~P)QOm!tO~O^_O|]O!j!pOm!kP!Q!kP!S!kP~P%TO!j!wO~O^_O|]O!j!pOm!kX!Q!kX!S!kX~P%TOm!yO~Om#OO!Q!zO!S!}O~Om#TO!Q!zO!S!}O~Ol#VO~Om#TO~Ol#WO~P)QOl#WO~Om#XO~O!j#YO~O!j#ZO~Ort~",
|
stateData: "1{~O!_OS!`OS~O]QO^_O_XO`POaTOfXOtXOuXOvXO|]O!hVO!kbO!nWO~O!deO~O]fO_XO`POaTOfXOtXOuXOvXOwgOyhO!hVO!nWOziX!kiX!wiX!miXoiX~OP!fXQ!fXR!fXS!fXT!fXU!fXV!fXW!fXX!fXY!fXZ!fX[!fX~P!YOPlOQlORmOSmO~OPlOQlORmOSmO!k!bX!w!bXo!bX~O]nOnmP~O]QO_XO`POaTOfXOtXOuXOvXO!hVO!nWO~OqxO!n{O!pvO!qwO~OP!fXQ!fXR!fXS!fX!k!bX!w!bXo!bX~Oz|O!k!bX!w!bXo!bX~O]fO_XO`POfXOtXOuXOvXO!hVO!nWO~OV!QO~O!k!RO!w!RO~O]!TOf!TO~OaTOw!UO~P'POaTOwgOyhOzda!kda!wda!mdaoda~P'PO]nOnmX~On!ZO~OT!]OU!]OV![OW![OX![OY![OZ![O[![O~OPlOQlORmOSmO~P)YOPlOQlORmOSmO!m!^O~O!m!^OP!fXQ!fXR!fXS!fXT!fXU!fXV!fXW!fXX!fXY!fXZ!fX[!fX~Oz|O!m!^O~O]!_O!hVO~O!n!`O!p!`O!q!`O!r!`O!s!`O!t!`O~OqxO!n!bO!pvO!qwO~O]!cO`PO~Oz|O!kca!wca!mcaoca~On!fO~P)YOn!fO~O^_O|]O~P%YOPlOQlORjiSji!kji!wji!mjioji~O^_O|]O!k!iO~P%YO^_O|]O!k!nO~P%YOo!oO~O^_O|]O!k!pOo!lP~P%YO!mkinki~P)YOo!tO~O^_O|]O!k!pOo!lP!Q!lP!S!lP~P%YO!k!wO~O^_O|]O!k!pOo!lX!Q!lX!S!lX~P%YOo!yO~Oo#OO!Q!zO!S!}O~Oo#TO!Q!zO!S!}O~On#VO~Oo#TO~On#WO~P)YOn#WO~Oo#XO~O!k#YO~O!k#ZO~Ofu~",
|
||||||
goto: "+r!wPPPPPPPPPPPPPPPPPP!x#X#g#l#X$W$m$yP%bPP%eP%|%|PPPP&QP#gPP&kP&w&z'TP'XP&k'_'e'l'r'{(R(YPPPP(`(d(x)[)a*[P*w*wP+YPP+bPPPPPP+f+fd`Od!Q!Y!f!i!n!r#Y#ZRsUiZOUd|!Q!Y!f!i!n!r#Y#ZVhPj!czWOPU]dgjkl!Q!Y!Z![!c!f!i!n!r!z#Y#ZR!^udROd!Q!Y!f!i!n!r#Y#ZQqUQ!VkR!WlQsUQ!P]Q!j![R#R!zd`Od!Q!Y!f!i!n!r#Y#ZUfPj!cQsUR!TgRoS{WOPU]dgjkl!Q!Y!Z![!c!f!i!n!r!z#Y#ZTwVydYOd!Q!Y!f!i!n!r#Y#ZgePU]gjkl!Z![!c!ze`Od!Q!Y!f!i!n!r#Y#ZR!m!fQ!v!nQ#[#YR#]#ZT!{!v!|Q#P!vR#U!|QdOR!SdSjP!cR!UjQnSR!XnW!r!i!n#Y#ZR!x!rQyVR!`yS}[tR!e}Q!|!vR#S!|TcOdSaOdQ!g!QQ!h!YQ!l!fZ!q!i!n!r#Y#Zd[Od!Q!Y!f!i!n!r#Y#ZQtUR!d|ViPj!cdQOd!Q!Y!f!i!n!r#Y#ZUfPj!cQpUQ!O]Q!TgQ!VkQ!WlQ!j!ZQ!k![R#Q!zdYOd!Q!Y!f!i!n!r#Y#ZdeP]gjkl!Z![!c!zRrUoTOPUdgj!Q!Y!c!f!i!n!r#Y#ZQ!s!iV!u!n#Y#ZTxVye^Od!Q!Y!f!i!n!r#Y#Z",
|
goto: "+u!wPPPPPPPPPPPPPPPPPPP!x#X#gP$T$Y#X$t%Z%g&OPP&RP&j&jPPPP$TPP&nP&z&}'WP'[P&n'b'h'o'u(O(U(]PPPP(c(g({P)_)d*_P*z*zP+]PP+ePPPPP+i+id`Od!Q!Z!f!i!n!r#Y#ZRtViZOVd|!Q!Z!f!i!n!r#Y#ZfQOVd!Q!Z!f!i!n!r#Y#ZdfQ]hklm![!]!c!zR!c|ViQk!czXOQV]dhklm!Q!Z![!]!c!f!i!n!r!z#Y#ZR!_vdSOd!Q!Z!f!i!n!r#Y#ZQrVQ!WlR!XmQtVQ!P]Q!j!]R#R!zd`Od!Q!Z!f!i!n!r#Y#ZUgQk!cQtVR!UhRpT{XOQV]dhklm!Q!Z![!]!c!f!i!n!r!z#Y#ZTxWze`Od!Q!Z!f!i!n!r#Y#ZR!m!fQ!v!nQ#[#YR#]#ZT!{!v!|Q#P!vR#U!|QdOR!SdSkQ!cR!VkQoTR!YoW!r!i!n#Y#ZR!x!rQzWR!azS}[uR!e}Q!|!vR#S!|TcOdSaOdQ!g!QQ!h!ZQ!l!fZ!q!i!n!r#Y#Zd[Od!Q!Z!f!i!n!r#Y#ZQuVR!d|VjQk!cdROd!Q!Z!f!i!n!r#Y#ZUgQk!cQqVQ!O]Q!UhQ!WlQ!XmQ!j![Q!k!]R#Q!zdYOd!Q!Z!f!i!n!r#Y#ZdfQ]hklm![!]!c!zRsVoUOQVdhk!Q!Z!c!f!i!n!r#Y#ZQ!s!iV!u!n#Y#ZTyWze^Od!Q!Z!f!i!n!r#Y#Z",
|
||||||
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 FunctionDef keyword Params colon keyword String StringFragment Interpolation EscapeSeq Number Boolean Regex Null DotGet Underscore NamedArg NamedArgPrefix operator IfExpr keyword SingleLineThenBlock ThenBlock ElseIfExpr keyword ElseExpr keyword Assign",
|
nodeNames: "⚠ Star Slash Plus Minus And Or Eq Neq Lt Lte Gt Gte Identifier AssignableIdentifier Word IdentifierBeforeDot Do Program PipeExpr FunctionCall DotGet Number PositionalArg ParenExpr FunctionCallOrIdentifier BinOp ConditionalOp FunctionDef Params colon keyword String StringFragment Interpolation EscapeSeq Boolean Regex Null Underscore NamedArg NamedArgPrefix operator IfExpr keyword SingleLineThenBlock ThenBlock ElseIfExpr keyword ElseExpr keyword Assign",
|
||||||
maxTerm: 85,
|
maxTerm: 85,
|
||||||
context: trackScope,
|
context: trackScope,
|
||||||
nodeProps: [
|
nodeProps: [
|
||||||
["closedBy", 28,"end"]
|
["closedBy", 30,"end"]
|
||||||
],
|
],
|
||||||
propSources: [highlighting],
|
propSources: [highlighting],
|
||||||
skippedNodes: [0],
|
skippedNodes: [0],
|
||||||
repeatNodeCount: 7,
|
repeatNodeCount: 7,
|
||||||
tokenData: ">i~RzOX#uXY$dYZ$}Zp#upq$dqs#ust%htu'Puw#uwx'Uxy'Zyz'tz{#u{|(_|}#u}!O(_!O!P#u!P!Q+R!Q![(|![!]3n!]!^$}!^#O#u#O#P4X#P#R#u#R#S4^#S#T#u#T#Y4w#Y#Z6V#Z#b4w#b#c:e#c#f4w#f#g;[#g#h4w#h#i<R#i#o4w#o#p#u#p#q=y#q;'S#u;'S;=`$^<%l~#u~O#u~~>dS#zUoSOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#uS$aP;=`<%l#u^$kUoS!_YOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#uU%UUoS!jQOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#u^%oZoS!`YOY%hYZ#uZt%htu&buw%hwx&bx#O%h#O#P&b#P;'S%h;'S;=`&y<%lO%hY&gS!`YOY&bZ;'S&b;'S;=`&s<%lO&bY&vP;=`<%l&b^&|P;=`<%l%h~'UO!o~~'ZO!m~U'bUoS!gQOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#uU'{UoS!lQOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#uU(dWoSOt#uuw#ux!Q#u!Q![(|![#O#u#P;'S#u;'S;=`$^<%lO#uU)TYoSrQOt#uuw#ux!O#u!O!P)s!P!Q#u!Q![(|![#O#u#P;'S#u;'S;=`$^<%lO#uU)xWoSOt#uuw#ux!Q#u!Q![*b![#O#u#P;'S#u;'S;=`$^<%lO#uU*iWoSrQOt#uuw#ux!Q#u!Q![*b![#O#u#P;'S#u;'S;=`$^<%lO#uU+WWoSOt#uuw#ux!P#u!P!Q+p!Q#O#u#P;'S#u;'S;=`$^<%lO#uU+u^oSOY,qYZ#uZt,qtu-tuw,qwx-tx!P,q!P!Q#u!Q!},q!}#O2g#O#P0S#P;'S,q;'S;=`3h<%lO,qU,x^oStQOY,qYZ#uZt,qtu-tuw,qwx-tx!P,q!P!Q0i!Q!},q!}#O2g#O#P0S#P;'S,q;'S;=`3h<%lO,qQ-yXtQOY-tZ!P-t!P!Q.f!Q!}-t!}#O/T#O#P0S#P;'S-t;'S;=`0c<%lO-tQ.iP!P!Q.lQ.qUtQ#Z#[.l#]#^.l#a#b.l#g#h.l#i#j.l#m#n.lQ/WVOY/TZ#O/T#O#P/m#P#Q-t#Q;'S/T;'S;=`/|<%lO/TQ/pSOY/TZ;'S/T;'S;=`/|<%lO/TQ0PP;=`<%l/TQ0VSOY-tZ;'S-t;'S;=`0c<%lO-tQ0fP;=`<%l-tU0nWoSOt#uuw#ux!P#u!P!Q1W!Q#O#u#P;'S#u;'S;=`$^<%lO#uU1_boStQOt#uuw#ux#O#u#P#Z#u#Z#[1W#[#]#u#]#^1W#^#a#u#a#b1W#b#g#u#g#h1W#h#i#u#i#j1W#j#m#u#m#n1W#n;'S#u;'S;=`$^<%lO#uU2l[oSOY2gYZ#uZt2gtu/Tuw2gwx/Tx#O2g#O#P/m#P#Q,q#Q;'S2g;'S;=`3b<%lO2gU3eP;=`<%l2gU3kP;=`<%l,qU3uUoSlQOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#u~4^O!p~U4eUoSwQOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#uU4|YoSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#o4w#o;'S#u;'S;=`$^<%lO#uU5sUyQoSOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#uU6[ZoSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#U6}#U#o4w#o;'S#u;'S;=`$^<%lO#uU7S[oSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#`4w#`#a7x#a#o4w#o;'S#u;'S;=`$^<%lO#uU7}[oSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#g4w#g#h8s#h#o4w#o;'S#u;'S;=`$^<%lO#uU8x[oSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#X4w#X#Y9n#Y#o4w#o;'S#u;'S;=`$^<%lO#uU9uYsQoSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#o4w#o;'S#u;'S;=`$^<%lO#u^:lY!qWoSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#o4w#o;'S#u;'S;=`$^<%lO#u^;cY!sWoSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#o4w#o;'S#u;'S;=`$^<%lO#u^<Y[!rWoSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#f4w#f#g=O#g#o4w#o;'S#u;'S;=`$^<%lO#uU=T[oSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#i4w#i#j8s#j#o4w#o;'S#u;'S;=`$^<%lO#uU>QUzQoSOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#u~>iO!w~",
|
tokenData: ">i~RzOX#uXY$dYZ$}Zp#upq$dqs#ust%htu'Puw#uwx'Uxy'Zyz'tz{#u{|(_|}#u}!O(_!O!P#u!P!Q+R!Q![(|![!]3n!]!^$}!^#O#u#O#P4X#P#R#u#R#S4^#S#T#u#T#Y4w#Y#Z6V#Z#b4w#b#c:e#c#f4w#f#g;[#g#h4w#h#i<R#i#o4w#o#p#u#p#q=y#q;'S#u;'S;=`$^<%l~#u~O#u~~>dS#zUqSOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#uS$aP;=`<%l#u^$kUqS!_YOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#uU%UUqS!kQOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#u^%oZqS!`YOY%hYZ#uZt%htu&buw%hwx&bx#O%h#O#P&b#P;'S%h;'S;=`&y<%lO%hY&gS!`YOY&bZ;'S&b;'S;=`&s<%lO&bY&vP;=`<%l&b^&|P;=`<%l%h~'UO!p~~'ZO!n~U'bUqS!hQOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#uU'{UqS!mQOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#uU(dWqSOt#uuw#ux!Q#u!Q![(|![#O#u#P;'S#u;'S;=`$^<%lO#uU)TYqSfQOt#uuw#ux!O#u!O!P)s!P!Q#u!Q![(|![#O#u#P;'S#u;'S;=`$^<%lO#uU)xWqSOt#uuw#ux!Q#u!Q![*b![#O#u#P;'S#u;'S;=`$^<%lO#uU*iWqSfQOt#uuw#ux!Q#u!Q![*b![#O#u#P;'S#u;'S;=`$^<%lO#uU+WWqSOt#uuw#ux!P#u!P!Q+p!Q#O#u#P;'S#u;'S;=`$^<%lO#uU+u^qSOY,qYZ#uZt,qtu-tuw,qwx-tx!P,q!P!Q#u!Q!},q!}#O2g#O#P0S#P;'S,q;'S;=`3h<%lO,qU,x^qSuQOY,qYZ#uZt,qtu-tuw,qwx-tx!P,q!P!Q0i!Q!},q!}#O2g#O#P0S#P;'S,q;'S;=`3h<%lO,qQ-yXuQOY-tZ!P-t!P!Q.f!Q!}-t!}#O/T#O#P0S#P;'S-t;'S;=`0c<%lO-tQ.iP!P!Q.lQ.qUuQ#Z#[.l#]#^.l#a#b.l#g#h.l#i#j.l#m#n.lQ/WVOY/TZ#O/T#O#P/m#P#Q-t#Q;'S/T;'S;=`/|<%lO/TQ/pSOY/TZ;'S/T;'S;=`/|<%lO/TQ0PP;=`<%l/TQ0VSOY-tZ;'S-t;'S;=`0c<%lO-tQ0fP;=`<%l-tU0nWqSOt#uuw#ux!P#u!P!Q1W!Q#O#u#P;'S#u;'S;=`$^<%lO#uU1_bqSuQOt#uuw#ux#O#u#P#Z#u#Z#[1W#[#]#u#]#^1W#^#a#u#a#b1W#b#g#u#g#h1W#h#i#u#i#j1W#j#m#u#m#n1W#n;'S#u;'S;=`$^<%lO#uU2l[qSOY2gYZ#uZt2gtu/Tuw2gwx/Tx#O2g#O#P/m#P#Q,q#Q;'S2g;'S;=`3b<%lO2gU3eP;=`<%l2gU3kP;=`<%l,qU3uUqSnQOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#u~4^O!q~U4eUqSwQOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#uU4|YqSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#o4w#o;'S#u;'S;=`$^<%lO#uU5sUyQqSOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#uU6[ZqSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#U6}#U#o4w#o;'S#u;'S;=`$^<%lO#uU7S[qSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#`4w#`#a7x#a#o4w#o;'S#u;'S;=`$^<%lO#uU7}[qSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#g4w#g#h8s#h#o4w#o;'S#u;'S;=`$^<%lO#uU8x[qSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#X4w#X#Y9n#Y#o4w#o;'S#u;'S;=`$^<%lO#uU9uYtQqSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#o4w#o;'S#u;'S;=`$^<%lO#u^:lY!rWqSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#o4w#o;'S#u;'S;=`$^<%lO#u^;cY!tWqSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#o4w#o;'S#u;'S;=`$^<%lO#u^<Y[!sWqSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#f4w#f#g=O#g#o4w#o;'S#u;'S;=`$^<%lO#uU=T[qSOt#uuw#ux!_#u!_!`5l!`#O#u#P#T#u#T#i4w#i#j8s#j#o4w#o;'S#u;'S;=`$^<%lO#uU>QUzQqSOt#uuw#ux#O#u#P;'S#u;'S;=`$^<%lO#u~>iO!w~",
|
||||||
tokenizers: [operatorTokenizer, 1, 2, 3, tokenizer, new LocalTokenGroup("[~RP!O!PU~ZO!t~~", 11)],
|
tokenizers: [operatorTokenizer, 1, 2, 3, tokenizer, new LocalTokenGroup("[~RP!O!PU~ZO!d~~", 11)],
|
||||||
topRules: {"Program":[0,17]},
|
topRules: {"Program":[0,18]},
|
||||||
specialized: [{term: 13, get: (value: keyof typeof spec_Identifier) => spec_Identifier[value] || -1}],
|
specialized: [{term: 13, get: (value: any, stack: any) => (specializeKeyword(value, stack) << 1), external: specializeKeyword},{term: 13, get: (value: keyof typeof spec_Identifier) => spec_Identifier[value] || -1}],
|
||||||
tokenPrec: 770
|
tokenPrec: 776
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -497,10 +497,10 @@ describe('Assign', () => {
|
||||||
AssignableIdentifier add
|
AssignableIdentifier add
|
||||||
Eq =
|
Eq =
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
AssignableIdentifier a
|
Identifier a
|
||||||
AssignableIdentifier b
|
Identifier b
|
||||||
colon :
|
colon :
|
||||||
BinOp
|
BinOp
|
||||||
Identifier a
|
Identifier a
|
||||||
|
|
@ -517,9 +517,10 @@ describe('DotGet whitespace sensitivity', () => {
|
||||||
AssignableIdentifier basename
|
AssignableIdentifier basename
|
||||||
Eq =
|
Eq =
|
||||||
Number 5
|
Number 5
|
||||||
DotGet
|
FunctionCallOrIdentifier
|
||||||
IdentifierBeforeDot basename
|
DotGet
|
||||||
Identifier prop`)
|
IdentifierBeforeDot basename
|
||||||
|
Identifier prop`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('space before dot - NOT DotGet, parses as division', () => {
|
test('space before dot - NOT DotGet, parses as division', () => {
|
||||||
|
|
|
||||||
|
|
@ -20,22 +20,24 @@ describe('DotGet', () => {
|
||||||
AssignableIdentifier obj
|
AssignableIdentifier obj
|
||||||
Eq =
|
Eq =
|
||||||
Number 5
|
Number 5
|
||||||
DotGet
|
FunctionCallOrIdentifier
|
||||||
IdentifierBeforeDot obj
|
DotGet
|
||||||
Identifier prop
|
IdentifierBeforeDot obj
|
||||||
|
Identifier prop
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('function parameters are in scope within function body', () => {
|
test('function parameters are in scope within function body', () => {
|
||||||
expect('do config: config.path end').toMatchTree(`
|
expect('do config: config.path end').toMatchTree(`
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
AssignableIdentifier config
|
Identifier config
|
||||||
colon :
|
colon :
|
||||||
DotGet
|
FunctionCallOrIdentifier
|
||||||
IdentifierBeforeDot config
|
DotGet
|
||||||
Identifier path
|
IdentifierBeforeDot config
|
||||||
|
Identifier path
|
||||||
keyword end
|
keyword end
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
@ -43,13 +45,14 @@ describe('DotGet', () => {
|
||||||
test('parameters out of scope outside function', () => {
|
test('parameters out of scope outside function', () => {
|
||||||
expect('do x: x.prop end; x.prop').toMatchTree(`
|
expect('do x: x.prop end; x.prop').toMatchTree(`
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
AssignableIdentifier x
|
Identifier x
|
||||||
colon :
|
colon :
|
||||||
DotGet
|
FunctionCallOrIdentifier
|
||||||
IdentifierBeforeDot x
|
DotGet
|
||||||
Identifier prop
|
IdentifierBeforeDot x
|
||||||
|
Identifier prop
|
||||||
keyword end
|
keyword end
|
||||||
Word x.prop
|
Word x.prop
|
||||||
`)
|
`)
|
||||||
|
|
@ -61,17 +64,19 @@ describe('DotGet', () => {
|
||||||
y.bar
|
y.bar
|
||||||
end`).toMatchTree(`
|
end`).toMatchTree(`
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
AssignableIdentifier x
|
Identifier x
|
||||||
AssignableIdentifier y
|
Identifier y
|
||||||
colon :
|
colon :
|
||||||
DotGet
|
FunctionCallOrIdentifier
|
||||||
IdentifierBeforeDot x
|
DotGet
|
||||||
Identifier foo
|
IdentifierBeforeDot x
|
||||||
DotGet
|
Identifier foo
|
||||||
IdentifierBeforeDot y
|
FunctionCallOrIdentifier
|
||||||
Identifier bar
|
DotGet
|
||||||
|
IdentifierBeforeDot y
|
||||||
|
Identifier bar
|
||||||
keyword end
|
keyword end
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
@ -82,21 +87,23 @@ end`).toMatchTree(`
|
||||||
do y: y.inner end
|
do y: y.inner end
|
||||||
end`).toMatchTree(`
|
end`).toMatchTree(`
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
AssignableIdentifier x
|
Identifier x
|
||||||
colon :
|
colon :
|
||||||
DotGet
|
FunctionCallOrIdentifier
|
||||||
IdentifierBeforeDot x
|
|
||||||
Identifier outer
|
|
||||||
FunctionDef
|
|
||||||
keyword do
|
|
||||||
Params
|
|
||||||
AssignableIdentifier y
|
|
||||||
colon :
|
|
||||||
DotGet
|
DotGet
|
||||||
IdentifierBeforeDot y
|
IdentifierBeforeDot x
|
||||||
Identifier inner
|
Identifier outer
|
||||||
|
FunctionDef
|
||||||
|
Do do
|
||||||
|
Params
|
||||||
|
Identifier y
|
||||||
|
colon :
|
||||||
|
FunctionCallOrIdentifier
|
||||||
|
DotGet
|
||||||
|
IdentifierBeforeDot y
|
||||||
|
Identifier inner
|
||||||
keyword end
|
keyword end
|
||||||
keyword end
|
keyword end
|
||||||
`)
|
`)
|
||||||
|
|
@ -117,6 +124,62 @@ end`).toMatchTree(`
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('dot get works as bare function', () => {
|
||||||
|
expect('io = dict print=echo; io.print').toMatchTree(`
|
||||||
|
Assign
|
||||||
|
AssignableIdentifier io
|
||||||
|
Eq =
|
||||||
|
FunctionCall
|
||||||
|
Identifier dict
|
||||||
|
NamedArg
|
||||||
|
NamedArgPrefix print=
|
||||||
|
Identifier echo
|
||||||
|
FunctionCallOrIdentifier
|
||||||
|
DotGet
|
||||||
|
IdentifierBeforeDot io
|
||||||
|
Identifier print
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('dot get works as function w/ args', () => {
|
||||||
|
expect('io = dict print=echo; io.print heya').toMatchTree(`
|
||||||
|
Assign
|
||||||
|
AssignableIdentifier io
|
||||||
|
Eq =
|
||||||
|
FunctionCall
|
||||||
|
Identifier dict
|
||||||
|
NamedArg
|
||||||
|
NamedArgPrefix print=
|
||||||
|
Identifier echo
|
||||||
|
FunctionCall
|
||||||
|
DotGet
|
||||||
|
IdentifierBeforeDot io
|
||||||
|
Identifier print
|
||||||
|
PositionalArg
|
||||||
|
Identifier heya
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('dot get works as function in parens', () => {
|
||||||
|
expect('io = dict print=echo; (io.print heya)').toMatchTree(`
|
||||||
|
Assign
|
||||||
|
AssignableIdentifier io
|
||||||
|
Eq =
|
||||||
|
FunctionCall
|
||||||
|
Identifier dict
|
||||||
|
NamedArg
|
||||||
|
NamedArgPrefix print=
|
||||||
|
Identifier echo
|
||||||
|
ParenExpr
|
||||||
|
FunctionCall
|
||||||
|
DotGet
|
||||||
|
IdentifierBeforeDot io
|
||||||
|
Identifier print
|
||||||
|
PositionalArg
|
||||||
|
Identifier heya
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
test('mixed file paths and dot get', () => {
|
test('mixed file paths and dot get', () => {
|
||||||
expect('config = 42; cat readme.txt; echo config.path').toMatchTree(`
|
expect('config = 42; cat readme.txt; echo config.path').toMatchTree(`
|
||||||
Assign
|
Assign
|
||||||
|
|
@ -145,4 +208,70 @@ end`).toMatchTree(`
|
||||||
PositionalArg
|
PositionalArg
|
||||||
Identifier prop`)
|
Identifier prop`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('readme.1 is Word when readme not in scope', () => {
|
||||||
|
expect('readme.1').toMatchTree(`Word readme.1`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('readme.1 is Word when used in function', () => {
|
||||||
|
expect('echo readme.1').toMatchTree(`
|
||||||
|
FunctionCall
|
||||||
|
Identifier echo
|
||||||
|
PositionalArg
|
||||||
|
Word readme.1`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('obj.1 is DotGet when obj is assigned', () => {
|
||||||
|
expect('obj = 5; obj.1').toMatchTree(`
|
||||||
|
Assign
|
||||||
|
AssignableIdentifier obj
|
||||||
|
Eq =
|
||||||
|
Number 5
|
||||||
|
FunctionCallOrIdentifier
|
||||||
|
DotGet
|
||||||
|
IdentifierBeforeDot obj
|
||||||
|
Number 1
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('obj.1 arg is DotGet when obj is assigned', () => {
|
||||||
|
expect('obj = 5; obj.1').toMatchTree(`
|
||||||
|
Assign
|
||||||
|
AssignableIdentifier obj
|
||||||
|
Eq =
|
||||||
|
Number 5
|
||||||
|
FunctionCallOrIdentifier
|
||||||
|
DotGet
|
||||||
|
IdentifierBeforeDot obj
|
||||||
|
Number 1
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('dot get index works as function w/ args', () => {
|
||||||
|
expect(`io = list (do x: echo x end); io.0 heya`).toMatchTree(`
|
||||||
|
Assign
|
||||||
|
AssignableIdentifier io
|
||||||
|
Eq =
|
||||||
|
FunctionCall
|
||||||
|
Identifier list
|
||||||
|
PositionalArg
|
||||||
|
ParenExpr
|
||||||
|
FunctionDef
|
||||||
|
Do do
|
||||||
|
Params
|
||||||
|
Identifier x
|
||||||
|
colon :
|
||||||
|
FunctionCall
|
||||||
|
Identifier echo
|
||||||
|
PositionalArg
|
||||||
|
Identifier x
|
||||||
|
keyword end
|
||||||
|
FunctionCall
|
||||||
|
DotGet
|
||||||
|
IdentifierBeforeDot io
|
||||||
|
Number 0
|
||||||
|
PositionalArg
|
||||||
|
Identifier heya
|
||||||
|
`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ describe('Do', () => {
|
||||||
test('parses function no parameters', () => {
|
test('parses function no parameters', () => {
|
||||||
expect('do: 1 end').toMatchTree(`
|
expect('do: 1 end').toMatchTree(`
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
colon :
|
colon :
|
||||||
Number 1
|
Number 1
|
||||||
|
|
@ -70,9 +70,9 @@ describe('Do', () => {
|
||||||
test('parses function with single parameter', () => {
|
test('parses function with single parameter', () => {
|
||||||
expect('do x: x + 1 end').toMatchTree(`
|
expect('do x: x + 1 end').toMatchTree(`
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
AssignableIdentifier x
|
Identifier x
|
||||||
colon :
|
colon :
|
||||||
BinOp
|
BinOp
|
||||||
Identifier x
|
Identifier x
|
||||||
|
|
@ -84,10 +84,10 @@ describe('Do', () => {
|
||||||
test('parses function with multiple parameters', () => {
|
test('parses function with multiple parameters', () => {
|
||||||
expect('do x y: x * y end').toMatchTree(`
|
expect('do x y: x * y end').toMatchTree(`
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
AssignableIdentifier x
|
Identifier x
|
||||||
AssignableIdentifier y
|
Identifier y
|
||||||
colon :
|
colon :
|
||||||
BinOp
|
BinOp
|
||||||
Identifier x
|
Identifier x
|
||||||
|
|
@ -102,10 +102,10 @@ describe('Do', () => {
|
||||||
x + 9
|
x + 9
|
||||||
end`).toMatchTree(`
|
end`).toMatchTree(`
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
AssignableIdentifier x
|
Identifier x
|
||||||
AssignableIdentifier y
|
Identifier y
|
||||||
colon :
|
colon :
|
||||||
BinOp
|
BinOp
|
||||||
Identifier x
|
Identifier x
|
||||||
|
|
@ -124,9 +124,9 @@ end`).toMatchTree(`
|
||||||
AssignableIdentifier fnnn
|
AssignableIdentifier fnnn
|
||||||
Eq =
|
Eq =
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
AssignableIdentifier x
|
Identifier x
|
||||||
colon :
|
colon :
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier x
|
Identifier x
|
||||||
|
|
@ -139,9 +139,9 @@ end`).toMatchTree(`
|
||||||
AssignableIdentifier enddd
|
AssignableIdentifier enddd
|
||||||
Eq =
|
Eq =
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
AssignableIdentifier x
|
Identifier x
|
||||||
colon :
|
colon :
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier x
|
Identifier x
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,10 @@ describe('multiline', () => {
|
||||||
AssignableIdentifier add
|
AssignableIdentifier add
|
||||||
Eq =
|
Eq =
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
AssignableIdentifier a
|
Identifier a
|
||||||
AssignableIdentifier b
|
Identifier b
|
||||||
colon :
|
colon :
|
||||||
Assign
|
Assign
|
||||||
AssignableIdentifier result
|
AssignableIdentifier result
|
||||||
|
|
@ -61,10 +61,10 @@ end
|
||||||
Number 3
|
Number 3
|
||||||
|
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
AssignableIdentifier x
|
Identifier x
|
||||||
AssignableIdentifier y
|
Identifier y
|
||||||
colon :
|
colon :
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier x
|
Identifier x
|
||||||
|
|
|
||||||
|
|
@ -75,13 +75,27 @@ describe('pipe expressions', () => {
|
||||||
Identifier each
|
Identifier each
|
||||||
PositionalArg
|
PositionalArg
|
||||||
FunctionDef
|
FunctionDef
|
||||||
keyword do
|
Do do
|
||||||
Params
|
Params
|
||||||
AssignableIdentifier x
|
Identifier x
|
||||||
colon :
|
colon :
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier x
|
Identifier x
|
||||||
keyword end
|
keyword end
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test(`double trouble (do keyword isn't over eager)`, () => {
|
||||||
|
expect(`
|
||||||
|
double 2 | double`).toMatchTree(`
|
||||||
|
PipeExpr
|
||||||
|
FunctionCall
|
||||||
|
Identifier double
|
||||||
|
PositionalArg
|
||||||
|
Number 2
|
||||||
|
operator |
|
||||||
|
FunctionCallOrIdentifier
|
||||||
|
Identifier double
|
||||||
|
`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
import { ExternalTokenizer, InputStream, Stack } from '@lezer/lr'
|
import { ExternalTokenizer, InputStream, Stack } from '@lezer/lr'
|
||||||
import { Identifier, AssignableIdentifier, Word, IdentifierBeforeDot } from './shrimp.terms'
|
import { Identifier, AssignableIdentifier, Word, IdentifierBeforeDot, Do } from './shrimp.terms'
|
||||||
|
|
||||||
|
// doobie doobie do (we need the `do` keyword to know when we're defining params)
|
||||||
|
export function specializeKeyword(ident: string) {
|
||||||
|
return ident === 'do' ? Do : -1
|
||||||
|
}
|
||||||
|
|
||||||
// The only chars that can't be words are whitespace, apostrophes, closing parens, and EOF.
|
// The only chars that can't be words are whitespace, apostrophes, closing parens, and EOF.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user