Dollar Dot #49

Merged
defunkt merged 3 commits from dollar-dot into main 2025-11-10 15:13:31 +00:00
11 changed files with 135 additions and 62 deletions
Showing only changes of commit c244435ae2 - Show all commits

View File

@ -7,6 +7,9 @@ import * as readline from 'readline'
import { readFileSync, writeFileSync } from 'fs'
import { basename } from 'path'
globals.$.script.name = '(repl)'
globals.$.script.path = '(repl)'
async function repl() {
const commands = ['/clear', '/reset', '/vars', '/funcs', '/history', '/bytecode', '/exit', '/save', '/quit']

View File

@ -1,13 +1,17 @@
#!/usr/bin/env bun
import { colors } from '../src/prelude'
import { colors, globals as prelude } from '../src/prelude'
import { treeToString } from '../src/utils/tree'
import { runCode, runFile, compileFile, parseCode } from '../src'
import { resolve } from 'path'
import { bytecodeToString } from 'reefvm'
import { readFileSync } from 'fs'
import { spawn } from 'child_process'
import { join } from 'path'
const idx = Bun.argv.indexOf('--')
prelude.$.args = idx >= 0 ? Bun.argv.slice(idx + 1) : []
function showHelp() {
console.log(`${colors.bright}${colors.magenta}🦐 Shrimp${colors.reset} is a scripting language in a shell.
@ -149,10 +153,12 @@ async function main() {
console.log(`${colors.bright}usage: shrimp run <file>${colors.reset}`)
process.exit(1)
}
prelude.$.script.path = resolve(file)
await runFile(file)
return
}
prelude.$.script.path = resolve(command)
await runFile(command)
}

View File

@ -293,7 +293,7 @@ export const getDotGetParts = (node: SyntaxNode, input: string) => {
)
}
if (object.type.id !== terms.IdentifierBeforeDot) {
if (object.type.id !== terms.IdentifierBeforeDot && object.type.id !== terms.Dollar) {
throw new CompilerError(
`DotGet object must be an IdentifierBeforeDot, got ${object.type.name}`,
object.from,

View File

@ -4,7 +4,7 @@ import { type Tree } from '@lezer/common'
import { Compiler } from '#compiler/compiler'
import { parser } from '#parser/shrimp'
import { globals as parserGlobals, setGlobals as setParserGlobals } from '#parser/tokenizer'
import { globals as shrimpGlobals } from '#prelude'
import { globals as prelude } from '#prelude'
export { Compiler } from '#compiler/compiler'
export { parser } from '#parser/shrimp'
@ -19,7 +19,7 @@ export class Shrimp {
constructor(globals?: Record<string, any>) {
const emptyBytecode = { instructions: [], constants: [], labels: new Map() }
this.vm = new VM(emptyBytecode, Object.assign({}, shrimpGlobals, globals ?? {}))
this.vm = new VM(emptyBytecode, Object.assign({}, prelude, globals ?? {}))
this.globals = globals
}
@ -53,7 +53,7 @@ export class Shrimp {
let bytecode
if (typeof code === 'string') {
const compiler = new Compiler(code, Object.keys(Object.assign({}, shrimpGlobals, this.globals ?? {}, locals ?? {})))
const compiler = new Compiler(code, Object.keys(Object.assign({}, prelude, this.globals ?? {}, locals ?? {})))
bytecode = compiler.bytecode
} else {
bytecode = code
@ -79,7 +79,7 @@ export async function runCode(code: string, globals?: Record<string, any>): Prom
}
export async function runBytecode(bytecode: Bytecode, globals?: Record<string, any>): Promise<any> {
const vm = new VM(bytecode, Object.assign({}, shrimpGlobals, globals))
const vm = new VM(bytecode, Object.assign({}, prelude, globals))
await vm.run()
return vm.stack.length ? fromValue(vm.stack[vm.stack.length - 1]!, vm) : null
}
@ -90,7 +90,7 @@ export function compileFile(path: string, globals?: Record<string, any>): Byteco
}
export function compileCode(code: string, globals?: Record<string, any>): Bytecode {
const globalNames = [...Object.keys(shrimpGlobals), ...(globals ? Object.keys(globals) : [])]
const globalNames = [...Object.keys(prelude), ...(globals ? Object.keys(globals) : [])]
const compiler = new Compiler(code, globalNames)
return compiler.bytecode
}
@ -102,7 +102,7 @@ export function parseFile(path: string, globals?: Record<string, any>): Tree {
export function parseCode(code: string, globals?: Record<string, any>): Tree {
const oldGlobals = [...parserGlobals]
const globalNames = [...Object.keys(shrimpGlobals), ...(globals ? Object.keys(globals) : [])]
const globalNames = [...Object.keys(prelude), ...(globals ? Object.keys(globals) : [])]
setParserGlobals(globalNames)
const result = parser.parse(code)

View File

@ -29,6 +29,7 @@
rightParen { ")" }
colon[closedBy="end", @name="colon"] { ":" }
Underscore { "_" }
Dollar { "$" }
Regex { "//" (![/\\\n[] | "\\" ![\n] | "[" (![\n\\\]] | "\\" ![\n])* "]")+ ("//" $[gimsuy]*)? } // Stolen from the lezer JavaScript grammar
"|"[@name=operator]
}
@ -239,7 +240,8 @@ expression {
@skip {} {
DotGet {
IdentifierBeforeDot dot (DotGet | Number | Identifier | ParenExpr)
IdentifierBeforeDot dot (DotGet | Number | Identifier | ParenExpr) |
Dollar dot (DotGet | Number | Identifier | ParenExpr)
}
String {
@ -254,7 +256,7 @@ stringContent {
}
Interpolation {
"$" Identifier |
"$" FunctionCallOrIdentifier |
"$" ParenExpr
}

View File

@ -37,42 +37,43 @@ export const
Program = 35,
PipeExpr = 36,
WhileExpr = 38,
keyword = 83,
keyword = 84,
ConditionalOp = 40,
ParenExpr = 41,
FunctionCallWithNewlines = 42,
DotGet = 43,
Number = 44,
PositionalArg = 45,
FunctionDef = 46,
Params = 47,
NamedParam = 48,
NamedArgPrefix = 49,
String = 50,
StringFragment = 51,
Interpolation = 52,
EscapeSeq = 53,
DoubleQuote = 54,
Boolean = 55,
Null = 56,
colon = 57,
CatchExpr = 58,
Block = 60,
FinallyExpr = 61,
Underscore = 64,
NamedArg = 65,
IfExpr = 66,
FunctionCall = 68,
ElseIfExpr = 69,
ElseExpr = 71,
FunctionCallOrIdentifier = 72,
BinOp = 73,
Regex = 74,
Dict = 75,
Array = 76,
FunctionCallWithBlock = 77,
TryExpr = 78,
Throw = 80,
Import = 82,
CompoundAssign = 84,
Assign = 85
Dollar = 45,
PositionalArg = 46,
FunctionDef = 47,
Params = 48,
NamedParam = 49,
NamedArgPrefix = 50,
String = 51,
StringFragment = 52,
Interpolation = 53,
FunctionCallOrIdentifier = 54,
EscapeSeq = 55,
DoubleQuote = 56,
Boolean = 57,
Null = 58,
colon = 59,
CatchExpr = 60,
Block = 62,
FinallyExpr = 63,
Underscore = 66,
NamedArg = 67,
IfExpr = 68,
FunctionCall = 70,
ElseIfExpr = 71,
ElseExpr = 73,
BinOp = 74,
Regex = 75,
Dict = 76,
Array = 77,
FunctionCallWithBlock = 78,
TryExpr = 79,
Throw = 81,
Import = 83,
CompoundAssign = 85,
Assign = 86

View File

@ -4,24 +4,24 @@ import {operatorTokenizer} from "./operatorTokenizer"
import {tokenizer, specializeKeyword} from "./tokenizer"
import {trackScope} from "./parserScopeContext"
import {highlighting} from "./highlight"
const spec_Identifier = {__proto__:null,while:78, null:112, catch:118, finally:124, end:126, if:134, else:140, try:158, throw:162, import:166}
const spec_Identifier = {__proto__:null,while:78, null:116, catch:122, finally:128, end:130, if:138, else:144, try:160, throw:164, import:168}
export const parser = LRParser.deserialize({
version: 14,
states: "=|QYQbOOO!mOpO'#DXO!rOSO'#D`OOQa'#D`'#D`O%mQcO'#DvO(mQcO'#EiOOQ`'#Ew'#EwO)WQRO'#DwO+]QcO'#EgO+vQbO'#DVOOQa'#Dy'#DyO.[QbO'#DzOOQa'#Ei'#EiO.cQcO'#EiO0aQcO'#EhO1fQcO'#EgO1sQRO'#ESOOQ`'#Eg'#EgO2[QbO'#EgO2cQQO'#EfOOQ`'#Ef'#EfOOQ`'#EU'#EUQYQbOOO2nQbO'#D[O2yQbO'#DpO3tQbO'#DSO4oQQO'#D|O3tQbO'#EOO4tQbO'#EQO4|ObO,59sO5[QbO'#DbO5dQWO'#DcOOOO'#Eo'#EoOOOO'#EZ'#EZO5xOSO,59zOOQa,59z,59zOOQ`'#DZ'#DZO6WQbO'#DoOOQ`'#Em'#EmOOQ`'#E^'#E^O6bQbO,5:^OOQa'#Eh'#EhO3tQbO,5:cO3tQbO,5:cO3tQbO,5:cO3tQbO,5:cO3tQbO,59pO3tQbO,59pO3tQbO,59pO3tQbO,59pOOQ`'#EW'#EWO+vQbO,59qO7[QcO'#DvO7cQcO'#EiO7jQRO,59qO7tQQO,59qO7yQQO,59qO8RQQO,59qO8^QRO,59qO8vQRO,59qO8}QQO'#DQO9SQbO,5:fO9ZQQO,5:eOOQa,5:f,5:fO9fQbO,5:fO9pQbO,5:oO9pQbO,5:nO;QQbO,5:gO;XQbO,59lOOQ`,5;Q,5;QO9pQbO'#EVOOQ`-E8S-E8SOOQ`'#EX'#EXO;sQbO'#D]O<OQbO'#D^OOQO'#EY'#EYO;vQQO'#D]O<dQQO,59vO<iQcO'#EhO=fQRO'#EvO>cQRO'#EvOOQO'#Ev'#EvO>jQQO,5:[O>oQRO,59nO>vQRO,59nO;QQbO,5:hO?UQcO,5:jO@dQcO,5:jOAQQcO,5:jOAuQbO,5:lOOQ`'#Eb'#EbO4tQbO,5:lOOQa1G/_1G/_OOOO,59|,59|OOOO,59},59}OOOO-E8X-E8XOOQa1G/f1G/fOOQ`,5:Z,5:ZOOQ`-E8[-E8[OOQa1G/}1G/}OCnQcO1G/}OCxQcO1G/}OEWQcO1G/}OEbQcO1G/}OEoQcO1G/}OOQa1G/[1G/[OGQQcO1G/[OGXQcO1G/[OG`QcO1G/[OH_QcO1G/[OGgQcO1G/[OOQ`-E8U-E8UOHuQRO1G/]OIPQQO1G/]OIUQQO1G/]OI^QQO1G/]OIiQRO1G/]OIpQRO1G/]OIwQbO,59rOJRQQO1G/]OOQa1G/]1G/]OJZQQO1G0POOQa1G0Q1G0QOJfQbO1G0QOOQO'#E`'#E`OJZQQO1G0POOQa1G0P1G0POOQ`'#Ea'#EaOJfQbO1G0QOJpQbO1G0ZOK[QbO1G0YOKvQbO'#DjOLXQbO'#DjOLlQbO1G0ROOQ`-E8T-E8TOOQ`,5:q,5:qOOQ`-E8V-E8VOLwQQO,59wOOQO,59x,59xOOQO-E8W-E8WOMPQbO1G/bO;QQbO1G/vO;QQbO1G/YOMWQbO1G0SOMcQbO1G0WONQQbO1G0WOOQ`-E8`-E8`ONXQQO7+$wOOQa7+$w7+$wONaQQO1G/^ONiQQO7+%kOOQa7+%k7+%kONtQbO7+%lOOQa7+%l7+%lOOQO-E8^-E8^OOQ`-E8_-E8_OOQ`'#E['#E[O! OQQO'#E[O! WQbO'#EuOOQ`,5:U,5:UO! kQbO'#DhO! pQQO'#DkOOQ`7+%m7+%mO! uQbO7+%mO! zQbO7+%mO!!SQbO7+$|O!!bQbO7+$|O!!rQbO7+%bO!!zQbO7+$tOOQ`7+%n7+%nO!#PQbO7+%nO!#UQbO7+%nO!#^QbO7+%rOOQa<<Hc<<HcO!#{QbO7+$xO!$YQQO7+$xOOQa<<IV<<IVOOQa<<IW<<IWOOQ`,5:v,5:vOOQ`-E8Y-E8YO!$bQQO,5:SO;QQbO,5:VOOQ`<<IX<<IXO!$gQbO<<IXOOQ`<<Hh<<HhO!$lQbO<<HhO!$qQbO<<HhO!$yQbO<<HhOOQ`'#E_'#E_O!%UQbO<<H|O!%^QbO'#DuOOQ`<<H|<<H|O!%fQbO<<H|OOQ`<<H`<<H`OOQ`<<IY<<IYO!%kQbO<<IYOOQO,5:w,5:wO!%pQbO<<HdOOQO-E8Z-E8ZO;QQbO1G/nOOQ`1G/q1G/qOOQ`AN>sAN>sOOQ`AN>SAN>SO!%}QbOAN>SO!&SQbOAN>SOOQ`-E8]-E8]OOQ`AN>hAN>hO!&[QbOAN>hO2yQbO,5:_O;QQbO,5:aOOQ`AN>tAN>tPIwQbO'#EWOOQ`7+%Y7+%YOOQ`G23nG23nO!&aQbOG23nP!%aQbO'#DsOOQ`G24SG24SO!&fQQO1G/yOOQ`1G/{1G/{OOQ`LD)YLD)YO;QQbO7+%eOOQ`<<IP<<IP",
stateData: "!&n~O#XOSrOS~OlSOm`On[OoPOpROqgOwiO|[O!WRO!X[O!Y[O!ehO!l[O!qjO!skO!ulO#^XO#_dO#bQO#mYO#nZO~O#`mO~O!TpO#bsO#dnO#eoO~OlyOn[OoPOpROqgO|[O!RuO!WRO!X[O!Y[O!btO!l[O#^XO#bQO#mYO#nZOP#[XQ#[XR#[XS#[XT#[XU#[XW#[XX#[XY#[XZ#[X[#[X]#[X^#[Xd#[Xe#[Xf#[Xg#[Xh#[Xi#[Xj#[Xu!jX!Z!jX#l!jX~O#_!jX#p!jX!]!jX!`!jX!a!jX!h!jX~P#QOlyOn[OoPOpROqgO|[O!RuO!WRO!X[O!Y[O!btO!l[O#^XO#bQO#mYO#nZOP#]XQ#]XR#]XS#]XT#]XU#]XW#]XX#]XY#]XZ#]X[#]X]#]X^#]Xd#]Xe#]Xf#]Xg#]Xh#]Xi#]Xj#]Xu#]X#l#]X~O#_#]X#p#]X!Z#]X!]#]X!`#]X!a#]X!h#]X~P&TOP{OQ{OR|OS|OT!POU!QOW!OOX!OOY!OOZ!OO[!OO]!OO^zOd}Oe}Of}Og}Oh}Oi}Oj!RO~OP{OQ{OR|OS|Od}Oe}Of}Og}Oh}Oi}Ou#ZX~O#_#ZX#p#ZX!]#ZX!`#ZX!a#ZX#l#ZX!h#ZX~P*hOl!UOm`On[OoPOpROqgOwiO|[O!WRO!X[O!Y[O!ehO!l[O!qjO!skO!ulO#^XO#_!SO#bQO#mYO#nZO~OlyOn[OoPOpRO|[O!RuO!WRO!X[O!Y[O!l[O#^XO#_!SO#bQO#mYO#nZO~O#o!aO~P-ZOV!cO#_#]X#p#]X!]#]X!`#]X!a#]X!h#]X~P'VOP#[XQ#[XR#[XS#[XT#[XU#[XW#[XX#[XY#[XZ#[X[#[X]#[X^#[Xd#[Xe#[Xf#[Xg#[Xh#[Xi#[Xj#[Xu#ZX~O#_#ZX#p#ZX!]#ZX!`#ZX!a#ZX#l#ZX!h#ZX~P.|Ou#ZX#_#ZX#p#ZX!]#ZX!`#ZX!a#ZX#l#ZX!h#ZX~OT!POU!QOj!RO~P0zOV!cO_!dO`!dOa!dOb!dOc!dOk!dO~O!Z!eO~P0zOu!hO#_!gO#p!gO~Ol!jO!R!lO!Z!PP~Ol!pOn[OoPOpRO|[O!WRO!X[O!Y[O!l[O#^XO#bQO#mYO#nZO~OlyOn[OoPOpRO|[O!WRO!X[O!Y[O!l[O#^XO#bQO#mYO#nZO~O!Z!wO~Ol!jO!RuO~Ol#OOoPO|#OO#^XO~Ol#PO#^XO~O#b#QO#d#QO#e#QO#f#QO#g#QO#h#QO~O!TpO#b#SO#dnO#eoO~OqgO!b#TO~P3tOqgO!RuO!btOu!fa!Z!fa#_!fa#p!fa#l!fa!]!fa!`!fa!a!fa!h!fa~P3tO#_!SO~P#QO#_!SO~P&TO#_!SO#l#lO~P*hO#l#lO~O#l#lOu#ZX~O!Z!eO#l#lOu#ZX~O#l#lO~P.|OT!POU!QOj!RO#_!SOu#ZX~O#l#lO~P8eOu!hO~O#o#nO~P-ZO!RuO#_#pO#o#rO~O#_#sO#o#nO~P3tOlSOm`On[OoPOpROqgOwiO|[O!WRO!X[O!Y[O!ehO!l[O!qjO!skO!ulO#^XO#bQO#mYO#nZO~O#_#xO~P9pOu!hO#_ta#pta#lta!]ta!`ta!ata!hta~Ol!jO!R!lO!Z!PX~OpRO|$OO!WRO!X$OO!Y$OO#bQO~O!Z$QO~OqgO!RuO!btOT#[XU#[XW#[XX#[XY#[XZ#[X[#[X]#[Xj#[X!Z#[X~P3tOT!POU!QOj!RO!Z#jX~OT!POU!QOW!OOX!OOY!OOZ!OO[!OO]!OOj!RO~O!Z#jX~P=tO!Z$RO~O!Z$SO~P=tOT!POU!QOj!RO!Z$SO~Ou!ra#_!ra#p!ra!]!ra!`!ra!a!ra#l!ra!h!ra~P)WOP{OQ{OR|OS|Od}Oe}Of}Og}Oh}Oi}O~Ou!ra#_!ra#p!ra!]!ra!`!ra!a!ra#l!ra!h!ra~P?rOT!POU!QOj!ROu!ra#_!ra#p!ra!]!ra!`!ra!a!ra#l!ra!h!ra~Ol!jO!RuOu!ta#_!ta#p!ta!]!ta!`!ta!a!ta#l!ta!h!ta~O^zOR!kiS!kid!kie!kif!kig!kih!kii!kiu!ki#_!ki#p!ki#l!ki!]!ki!`!ki!a!ki!h!ki~OP!kiQ!ki~PBgOP{OQ{O~PBgOP{OQ{Od!kie!kif!kig!kih!kii!kiu!ki#_!ki#p!ki#l!ki!]!ki!`!ki!a!ki!h!ki~OR!kiS!ki~PDSOR|OS|O^zO~PDSOR|OS|O~PDSOW!OOX!OOY!OOZ!OO[!OO]!OOTxijxiuxi#_xi#pxi#lxi!Zxi!]xi!`xi!axi!hxi~OU!QO~PEyOU!QO~PF]OUxi~PEyOT!POU!QOjxiuxi#_xi#pxi#lxi!Zxi!]xi!`xi!axi!hxi~OW!OOX!OOY!OOZ!OO[!OO]!OO~PGgO#_!SO#l$YO~P*hO#l$YO~O#l$YOu#ZX~O!Z!eO#l$YOu#ZX~O#l$YO~P.|O#l$YO~P8eOqgO!btO~P-ZO#_!SO#l$YO~O!RuO#_#pO#o$]O~O#_#sO#o$_O~P3tOu!hO#_!wi#p!wi!]!wi!`!wi!a!wi#l!wi!h!wi~Ou!hO#_!vi#p!vi!]!vi!`!vi!a!vi#l!vi!h!vi~Ou!hO!]!^X!`!^X!a!^X!h!^X~O#_$bO!]#iP!`#iP!a#iP!h#iP~P9pO!]$fO!`$gO!a$hO~O!R!lO!Z!Pa~O#_$lO~P9pO!]$fO!`$gO!a$oO~O!RuOu!ti#_!ti#p!ti!]!ti!`!ti!a!ti#l!ti!h!ti~Ol!jO~PMcO#_!SO#l$sO~O#_!SO#lzi~O!RuO#_#pO#o$vO~O#_#sO#o$wO~P3tOu!hO#_$xO~O#_$bO!]#iX!`#iX!a#iX!h#iX~P9pOl$zO~O!Z${O~O!a$|O~O!`$gO!a$|O~Ou!hO!]$fO!`$gO!a%OO~O#_$bO!]#iP!`#iP!a#iP~P9pO!a%VO!h%UO~O!a%XO~O!a%YO~O!`$gO!a%YO~O!RuOu!tq#_!tq#p!tq!]!tq!`!tq!a!tq#l!tq!h!tq~OqgO!btO#lzq~P-ZO#_!SO#lzq~O!Z%_O~O!a%aO~O!a%bO~O!`$gO!a%bO~O!]$fO!`$gO!a%bO~O!a%fO!h%UO~O!Z%iO!e%hO~O!a%fO~O!a%jO~OqgO!btO#lzy~P-ZO!a%mO~O!`$gO!a%mO~O!a%pO~O!a%sO~O!Z%tO~O|!l~",
goto: "9^#lPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP#mP$WP$m%k&y'PP(^(j)d)gP)mP*t*tPPPP*xP+U+nPPP,U#mP,v-aP-e-k.QP.w/{$W$WP$WP$WP$W$W1R1X1e2X2g2q2w3O3U3`3f3p3zPPP4Y4^5R6wPPP8RP8cPPPPP8g8m8sraOf!c!d!e!h!w#x$Q$R$S$d$l${%_%i%tQ!YXR#f!TwaOXf!T!c!d!e!h!w#x$Q$R$S$d$l${%_%i%tr_Of!c!d!e!h!w#x$Q$R$S$d$l${%_%i%tQ!]XS!qh%hQ!viQ!zkQ#]!QQ#_!PQ#b!RR#i!TvTOfh!c!d!e!h!w#x$Q$R$S$d$l${%_%h%i%t!W[STZikuxz{|}!O!P!Q!R!U!V!_!b!p#j#o#t$^$t%]%kS!VX!TQ#OmR#PnQ!XXR#e!TrSOf!c!d!e!h!w#x$Q$R$S$d$l${%_%i%t!WySTZikuxz{|}!O!P!Q!R!U!V!_!b!p#j#o#t$^$t%]%kS!UX!TS!ph%hR#OmevSTx!U!V!p#j$t%]%kraOf!c!d!e!h!w#x$Q$R$S$d$l${%_%i%tdtSTx!U!V!p#j$t%]%kQ!YXQ#TuR#f!TR!ogX!mg!k!n#}#S[OSTXZfhikuxz{|}!O!P!Q!R!T!U!V!_!b!c!d!e!h!p!w#j#o#t#x$Q$R$S$^$d$l$t${%]%_%h%i%k%tR$O!lTpQrQ$j#yQ$q$TQ%Q$kR%d%RQ#y!eQ$T!wQ$m$RQ$n$SQ%`${Q%l%_Q%r%iR%u%tQ$i#yQ$p$TQ$}$jQ%P$kQ%Z$qS%c%Q%RR%n%ddvSTx!U!V!p#j$t%]%kQ!`Z[!|l!{!}$U$V$rQ#m!_X#p!`#m#q$[vUOXf!T!c!d!e!h!w#x$Q$R$S$d$l${%_%i%tT!sh%hT%S$m%TQ%W$mR%g%TwUOXf!T!c!d!e!h!w#x$Q$R$S$d$l${%_%i%trWOf!c!d!e!h!w#x$Q$R$S$d$l${%_%i%tQ!WXQ!ykQ#V{Q#Y|Q#[}R#d!T#T[OSTXZfhikuxz{|}!O!P!Q!R!T!U!V!_!b!c!d!e!h!p!w#j#o#t#x$Q$R$S$^$d$l$t${%]%_%h%i%k%t![[STZhikuxz{|}!O!P!Q!R!U!V!_!b!p#j#o#t$^$t%]%h%kw]OXf!T!c!d!e!h!w#x$Q$R$S$d$l${%_%i%tQfOR!if^!fc!^#u#v#w$c$kR#z!fQ!TXQ!_Z`#c!T!_#j#k$X$t%]%kS#j!U!VS#k!W!]S$X#d#iQ$t$ZR%]$uQ!kgQ!{lU#|!k!{$VR$V!}Q!ngQ#}!kT$P!n#}QrQR#RrS$d#x$lR$y$dQ$u$ZR%^$uYxST!U!V!pR#UxQ%T$mR%e%TQ#q!`Q$[#mT$`#q$[Q#t!bQ$^#oT$a#t$^Q!}lQ$U!{U$W!}$U$rR$r$VTeOfScOfS!^X!TQ#u!cQ#v!d`#w!e!w$R$S${%_%i%tQ#{!hU$c#x$d$lR$k$QvVOXf!T!c!d!e!h!w#x$Q$R$S$d$l${%_%i%tdtSTx!U!V!p#j$t%]%kQ!bZS!rh%hQ!uiQ!xkQ#TuQ#VzQ#W{Q#X|Q#Z}Q#]!OQ#^!PQ#`!QQ#a!RQ#o!_X#s!b#o#t$^r^Of!c!d!e!h!w#x$Q$R$S$d$l${%_%i%t![ySTZhikuxz{|}!O!P!Q!R!U!V!_!b!p#j#o#t$^$t%]%h%kQ![XR#h!T[wSTx!U!V!pQ$Z#jV%[$t%]%kTqQrQ$e#xR%R$lQ!thR%q%hrbOf!c!d!e!h!w#x$Q$R$S$d$l${%_%i%tQ!ZXR#g!T",
nodeNames: "⚠ Star Slash Plus Minus And Or Eq EqEq Neq Lt Lte Gt Gte Modulo PlusEq MinusEq StarEq SlashEq ModuloEq Band Bor Bxor Shl Shr Ushr NullishCoalesce NullishEq Identifier AssignableIdentifier Word IdentifierBeforeDot CurlyString Do Comment Program PipeExpr operator WhileExpr keyword ConditionalOp ParenExpr FunctionCall DotGet Number PositionalArg FunctionDef Params NamedParam NamedArgPrefix String StringFragment Interpolation EscapeSeq DoubleQuote Boolean Null colon CatchExpr keyword Block FinallyExpr keyword keyword Underscore NamedArg IfExpr keyword FunctionCall ElseIfExpr keyword ElseExpr FunctionCallOrIdentifier BinOp Regex Dict Array FunctionCallWithBlock TryExpr keyword Throw keyword Import keyword CompoundAssign Assign",
maxTerm: 124,
states: ">`QYQbOOO!pOpO'#DXO%eQcO'#DdO%{OSO'#DaOOQa'#Da'#DaO(vQcO'#EjOOQ`'#Ex'#ExO)aQRO'#DxO+fQcO'#EhO,PQbO'#DVOOQa'#Dz'#DzO.kQbO'#D{OOQa'#Ej'#EjO.rQcO'#EjO0pQcO'#EiO1uQcO'#EhO2SQRO'#ETOOQ`'#Eh'#EhO2kQbO'#EhO2rQQO'#EgOOQ`'#Eg'#EgOOQ`'#EV'#EVQYQbOOO2}QbO'#D]O3YQbO'#DrO4WQbO'#DSO5UQQO'#D}O4WQbO'#EPO5ZQbO'#ERO5cObO,59sOOQ`'#D['#D[O5tQbO'#DqOOQ`'#En'#EnOOQ`'#E_'#E_O6OQbO,5:`OOQa'#Ei'#EiO6xQbO'#DcO7WQWO'#DeOOOO'#Ep'#EpOOOO'#E['#E[O7lOSO,59{OOQa,59{,59{O4WQbO,5:dO4WQbO,5:dO4WQbO,5:dO4WQbO,5:dO4WQbO,59pO4WQbO,59pO4WQbO,59pO4WQbO,59pOOQ`'#EX'#EXO,PQbO,59qO7zQcO'#DdO8RQcO'#EjO8YQRO,59qO8dQQO,59qO8iQQO,59qO8qQQO,59qO8|QRO,59qO9fQRO,59qO9mQQO'#DQO9rQbO,5:gO9yQQO,5:fOOQa,5:g,5:gO:UQbO,5:gO:`QbO,5:pO:`QbO,5:oO;sQbO,5:hO;zQbO,59lOOQ`,5;R,5;RO:`QbO'#EWOOQ`-E8T-E8TOOQ`'#EY'#EYO<fQbO'#D^O<qQbO'#D_OOQO'#EZ'#EZO<iQQO'#D^O=VQQO,59wO=[QcO'#EiO>XQRO'#EwO?UQRO'#EwOOQO'#Ew'#EwO?]QQO,5:^O?bQRO,59nO?iQRO,59nO;sQbO,5:iO?wQcO,5:kOAVQcO,5:kOAsQcO,5:kOBhQbO,5:mOOQ`'#Ec'#EcO5ZQbO,5:mOOQa1G/_1G/_OOQ`,5:],5:]OOQ`-E8]-E8]OOOO'#Dd'#DdOOOO,59},59}OOOO,5:P,5:POOOO-E8Y-E8YOOQa1G/g1G/gOOQa1G0O1G0OODaQcO1G0OODkQcO1G0OOEyQcO1G0OOFTQcO1G0OOFbQcO1G0OOOQa1G/[1G/[OGsQcO1G/[OGzQcO1G/[OHRQcO1G/[OIQQcO1G/[OHYQcO1G/[OOQ`-E8V-E8VOIhQRO1G/]OIrQQO1G/]OIwQQO1G/]OJPQQO1G/]OJ[QRO1G/]OJcQRO1G/]OJjQbO,59rOJtQQO1G/]OOQa1G/]1G/]OJ|QQO1G0QOOQa1G0R1G0ROKXQbO1G0ROOQO'#Ea'#EaOJ|QQO1G0QOOQa1G0Q1G0QOOQ`'#Eb'#EbOKXQbO1G0ROKcQbO1G0[OK}QbO1G0ZOLiQbO'#DlOLzQbO'#DlOM_QbO1G0SOOQ`-E8U-E8UOOQ`,5:r,5:rOOQ`-E8W-E8WOMjQQO,59xOOQO,59y,59yOOQO-E8X-E8XOMrQbO1G/cO;sQbO1G/xO;sQbO1G/YOMyQbO1G0TONUQbO1G0XONsQbO1G0XOOQ`-E8a-E8aONzQQO7+$wOOQa7+$w7+$wO! SQQO1G/^O! [QQO7+%lOOQa7+%l7+%lO! gQbO7+%mOOQa7+%m7+%mOOQO-E8_-E8_OOQ`-E8`-E8`OOQ`'#E]'#E]O! qQQO'#E]O! yQbO'#EvOOQ`,5:W,5:WO!!^QbO'#DjO!!cQQO'#DmOOQ`7+%n7+%nO!!hQbO7+%nO!!mQbO7+%nO!!uQbO7+$}O!#TQbO7+$}O!#eQbO7+%dO!#mQbO7+$tOOQ`7+%o7+%oO!#rQbO7+%oO!#wQbO7+%oO!$PQbO7+%sOOQa<<Hc<<HcO!$nQbO7+$xO!${QQO7+$xOOQa<<IW<<IWOOQa<<IX<<IXOOQ`,5:w,5:wOOQ`-E8Z-E8ZO!%TQQO,5:UO;sQbO,5:XOOQ`<<IY<<IYO!%YQbO<<IYOOQ`<<Hi<<HiO!%_QbO<<HiO!%dQbO<<HiO!%lQbO<<HiOOQ`'#E`'#E`O!%wQbO<<IOO!&PQbO'#DwOOQ`<<IO<<IOO!&XQbO<<IOOOQ`<<H`<<H`OOQ`<<IZ<<IZO!&^QbO<<IZOOQO,5:x,5:xO!&cQbO<<HdOOQO-E8[-E8[O;sQbO1G/pOOQ`1G/s1G/sOOQ`AN>tAN>tOOQ`AN>TAN>TO!&pQbOAN>TO!&uQbOAN>TOOQ`-E8^-E8^OOQ`AN>jAN>jO!&}QbOAN>jO3YQbO,5:aO;sQbO,5:cOOQ`AN>uAN>uPJjQbO'#EXOOQ`7+%[7+%[OOQ`G23oG23oO!'SQbOG23oP!&SQbO'#DuOOQ`G24UG24UO!'XQQO1G/{OOQ`1G/}1G/}OOQ`LD)ZLD)ZO;sQbO7+%gOOQ`<<IR<<IRO!'^ObO,59sO!'oOpO'#DX",
stateData: "!'w~O#YOSrOS~OlQOm`On[OoPOpSOqgOwiO|[O}PO!YSO!Z[O![[O!ghO!m[O!rjO!tkO!vlO#_XO#`dO#cRO#nYO#oZO~O#amO~OlsOn[OoPOpSOqgO|[O}PO!SoO!YSO!Z[O![[O!dnO!m[O#_XO#cRO#nYO#oZOP#]XQ#]XR#]XS#]XT#]XU#]XW#]XX#]XY#]XZ#]X[#]X]#]X^#]Xd#]Xe#]Xf#]Xg#]Xh#]Xi#]Xj#]Xu!WX!]!WX#m!WX~O#`!WX#q!WX!_!WX!b!WX!c!WX!j!WX~P!uO!UvO#cyO#etO#fuO~OlsOn[OoPOpSOqgO|[O}PO!SoO!YSO!Z[O![[O!dnO!m[O#_XO#cRO#nYO#oZOP#^XQ#^XR#^XS#^XT#^XU#^XW#^XX#^XY#^XZ#^X[#^X]#^X^#^Xd#^Xe#^Xf#^Xg#^Xh#^Xi#^Xj#^Xu#^X#m#^X~O#`#^X#q#^X!]#^X!_#^X!b#^X!c#^X!j#^X~P&ZOP{OQ{OR|OS|OT!POU!QOW!OOX!OOY!OOZ!OO[!OO]!OO^zOd}Oe}Of}Og}Oh}Oi}Oj!RO~OP{OQ{OR|OS|Od}Oe}Of}Og}Oh}Oi}Ou#[X~O#`#[X#q#[X!_#[X!b#[X!c#[X#m#[X!j#[X~P*qOl!UOm`On[OoPOpSOqgOwiO|[O}PO!YSO!Z[O![[O!ghO!m[O!rjO!tkO!vlO#_XO#`!SO#cRO#nYO#oZO~OlsOn[OoPOpSO|[O}PO!SoO!YSO!Z[O![[O!m[O#_XO#`!SO#cRO#nYO#oZO~O#p!aO~P-gOV!cO#`#^X#q#^X!_#^X!b#^X!c#^X!j#^X~P'`OP#]XQ#]XR#]XS#]XT#]XU#]XW#]XX#]XY#]XZ#]X[#]X]#]X^#]Xd#]Xe#]Xf#]Xg#]Xh#]Xi#]Xj#]Xu#[X~O#`#[X#q#[X!_#[X!b#[X!c#[X#m#[X!j#[X~P/]Ou#[X#`#[X#q#[X!_#[X!b#[X!c#[X#m#[X!j#[X~OT!POU!QOj!RO~P1ZOV!cO_!dO`!dOa!dOb!dOc!dOk!dO~O!]!eO~P1ZOu!hO#`!gO#q!gO~Ol!jO!S!lO!]!QP~Ol!pOn[OoPOpSO|[O}PO!YSO!Z[O![[O!m[O#_XO#cRO#nYO#oZO~OlsOn[OoPOpSO|[O}PO!YSO!Z[O![[O!m[O#_XO#cRO#nYO#oZO~O!]!wO~Ol!jO!SoO~Ol#OOoPO|#OO}PO#_XO~OqgO!d#PO~P4WOqgO!SoO!dnOu!ha!]!ha#`!ha#q!ha#m!ha!_!ha!b!ha!c!ha!j!ha~P4WOl#ROo%xO}%xO#_XO~O#c#TO#e#TO#f#TO#g#TO#h#TO#i#TO~O!UvO#c#VO#etO#fuO~O#`!SO~P!uO#`!SO~P&ZO#`!SO#m#mO~P*qO#m#mO~O#m#mOu#[X~O!]!eO#m#mOu#[X~O#m#mO~P/]OT!POU!QOj!RO#`!SOu#[X~O#m#mO~P9TOu!hO~O#p#oO~P-gO!SoO#`#qO#p#sO~O#`#tO#p#oO~P4WOlQOm`On[OoPOpSOqgOwiO|[O}PO!YSO!Z[O![[O!ghO!m[O!rjO!tkO!vlO#_XO#cRO#nYO#oZO~O#`#yO~P:`Ou!hO#`ta#qta#mta!_ta!bta!cta!jta~Ol!jO!S!lO!]!QX~OpSO|$PO!YSO!Z$PO![$PO#cRO~O!]$RO~OqgO!SoO!dnOT#]XU#]XW#]XX#]XY#]XZ#]X[#]X]#]Xj#]X!]#]X~P4WOT!POU!QOj!RO!]#kX~OT!POU!QOW!OOX!OOY!OOZ!OO[!OO]!OOj!RO~O!]#kX~P>gO!]$SO~O!]$TO~P>gOT!POU!QOj!RO!]$TO~Ou!sa#`!sa#q!sa!_!sa!b!sa!c!sa#m!sa!j!sa~P)aOP{OQ{OR|OS|Od}Oe}Of}Og}Oh}Oi}O~Ou!sa#`!sa#q!sa!_!sa!b!sa!c!sa#m!sa!j!sa~P@eOT!POU!QOj!ROu!sa#`!sa#q!sa!_!sa!b!sa!c!sa#m!sa!j!sa~Ol!jO!SoOu!ua#`!ua#q!ua!_!ua!b!ua!c!ua#m!ua!j!ua~O^zOR!liS!lid!lie!lif!lig!lih!lii!liu!li#`!li#q!li#m!li!_!li!b!li!c!li!j!li~OP!liQ!li~PCYOP{OQ{O~PCYOP{OQ{Od!lie!lif!lig!lih!lii!liu!li#`!li#q!li#m!li!_!li!b!li!c!li!j!li~OR!liS!li~PDuOR|OS|O^zO~PDuOR|OS|O~PDuOW!OOX!OOY!OOZ!OO[!OO]!OOTxijxiuxi#`xi#qxi#mxi!]xi!_xi!bxi!cxi!jxi~OU!QO~PFlOU!QO~PGOOUxi~PFlOT!POU!QOjxiuxi#`xi#qxi#mxi!]xi!_xi!bxi!cxi!jxi~OW!OOX!OOY!OOZ!OO[!OO]!OO~PHYO#`!SO#m$ZO~P*qO#m$ZO~O#m$ZOu#[X~O!]!eO#m$ZOu#[X~O#m$ZO~P/]O#m$ZO~P9TOqgO!dnO~P-gO#`!SO#m$ZO~O!SoO#`#qO#p$^O~O#`#tO#p$`O~P4WOu!hO#`!xi#q!xi!_!xi!b!xi!c!xi#m!xi!j!xi~Ou!hO#`!wi#q!wi!_!wi!b!wi!c!wi#m!wi!j!wi~Ou!hO!_!`X!b!`X!c!`X!j!`X~O#`$cO!_#jP!b#jP!c#jP!j#jP~P:`O!_$gO!b$hO!c$iO~O!S!lO!]!Qa~O#`$mO~P:`O!_$gO!b$hO!c$pO~O!SoOu!ui#`!ui#q!ui!_!ui!b!ui!c!ui#m!ui!j!ui~Ol!jO~PNUO#`!SO#m$tO~O#`!SO#mzi~O!SoO#`#qO#p$wO~O#`#tO#p$xO~P4WOu!hO#`$yO~O#`$cO!_#jX!b#jX!c#jX!j#jX~P:`Ol${O~O!]$|O~O!c$}O~O!b$hO!c$}O~Ou!hO!_$gO!b$hO!c%PO~O#`$cO!_#jP!b#jP!c#jP~P:`O!c%WO!j%VO~O!c%YO~O!c%ZO~O!b$hO!c%ZO~O!SoOu!uq#`!uq#q!uq!_!uq!b!uq!c!uq#m!uq!j!uq~OqgO!dnO#mzq~P-gO#`!SO#mzq~O!]%`O~O!c%bO~O!c%cO~O!b$hO!c%cO~O!_$gO!b$hO!c%cO~O!c%gO!j%VO~O!]%jO!g%iO~O!c%gO~O!c%kO~OqgO!dnO#mzy~P-gO!c%nO~O!b$hO!c%nO~O!c%qO~O!c%tO~O!]%uO~Ol#OOo%xO|#OO}%xO#_XO~O#a%wO~O|!m~",
goto: "9g#mPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP#nP$XP$n%l&{'RPP(d(p)j)mP)sP*z+O*zPPPP+hP+t,^PPP,t#nP-f.PP.T.ZP/Q0U$X$XP$XP$XP$X$X1[1b1n2b2p2z3Q3X3_3i3o3y4TPPP4c4g5[7QPPP8[P8lPPPPP8p8v8|raOf!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uQ!YXR#g!TwaOXf!T!c!d!e!h!w#y$R$S$T$e$m$|%`%j%ur_Of!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uQ!]XS!qh%iQ!viQ!zkQ#^!QQ#`!PQ#c!RR#j!TvTOfh!c!d!e!h!w#y$R$S$T$e$m$|%`%i%j%u!W[QTZikorz{|}!O!P!Q!R!U!V!_!b!p#k#p#u$_$u%^%lS!VX!TS#Om%wR#StQ!XXR#f!TrQOf!c!d!e!h!w#y$R$S$T$e$m$|%`%j%u!WsQTZikorz{|}!O!P!Q!R!U!V!_!b!p#k#p#u$_$u%^%lS!UX!TS!ph%iS#Om%wR#RtepQTr!U!V!p#k$u%^%lraOf!c!d!e!h!w#y$R$S$T$e$m$|%`%j%udnQTr!U!V!p#k$u%^%lQ!YXQ#PoR#g!TR!ogX!mg!k!n$O#S[OQTXZfhikorz{|}!O!P!Q!R!T!U!V!_!b!c!d!e!h!p!w#k#p#u#y$R$S$T$_$e$m$u$|%^%`%i%j%l%uR$P!lTvRxvUOXf!T!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uR#StQ$k#zQ$r$UQ%R$lR%e%SQ#z!eQ$U!wQ$n$SQ$o$TQ%a$|Q%m%`Q%s%jR%v%uQ$j#zQ$q$UQ%O$kQ%Q$lQ%[$rS%d%R%SR%o%edpQTr!U!V!p#k$u%^%lQ!`Z[!|l!{!}$V$W$sQ#n!_X#q!`#n#r$]vUOXf!T!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uT!sh%iT%T$n%UQ%X$nR%h%UrWOf!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uQ!WXQ!ykQ#W{Q#Z|Q#]}R#e!T#T[OQTXZfhikorz{|}!O!P!Q!R!T!U!V!_!b!c!d!e!h!p!w#k#p#u#y$R$S$T$_$e$m$u$|%^%`%i%j%l%u![[QTZhikorz{|}!O!P!Q!R!U!V!_!b!p#k#p#u$_$u%^%i%lw]OXf!T!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uQfOR!if^!fc!^#v#w#x$d$lR#{!fQ!TXQ!_Z`#d!T!_#k#l$Y$u%^%lS#k!U!VS#l!W!]S$Y#e#jQ$u$[R%^$vQ!kgQ!{lU#}!k!{$WR$W!}Q!ngQ$O!kT$Q!n$OQxRR#UxS$e#y$mR$z$eQ$v$[R%_$vYrQT!U!V!pR#QrQ%U$nR%f%UQ#r!`Q$]#nT$a#r$]Q#u!bQ$_#pT$b#u$_Q!}lQ$V!{U$X!}$V$sR$s$WTeOfScOfS!^X!TQ#v!cQ#w!d`#x!e!w$S$T$|%`%j%uQ#|!hU$d#y$e$mR$l$RvVOXf!T!c!d!e!h!w#y$R$S$T$e$m$|%`%j%udnQTr!U!V!p#k$u%^%lQ!bZS!rh%iQ!uiQ!xkQ#PoQ#WzQ#X{Q#Y|Q#[}Q#^!OQ#_!PQ#a!QQ#b!RQ#p!_X#t!b#p#u$_r^Of!c!d!e!h!w#y$R$S$T$e$m$|%`%j%u![sQTZhikorz{|}!O!P!Q!R!U!V!_!b!p#k#p#u$_$u%^%i%lQ![XR#i!T[qQTr!U!V!pQ$[#kV%]$u%^%lTwRxQ$f#yR%S$mQ!thR%r%irbOf!c!d!e!h!w#y$R$S$T$e$m$|%`%j%uQ!ZXR#h!T",
nodeNames: "⚠ Star Slash Plus Minus And Or Eq EqEq Neq Lt Lte Gt Gte Modulo PlusEq MinusEq StarEq SlashEq ModuloEq Band Bor Bxor Shl Shr Ushr NullishCoalesce NullishEq Identifier AssignableIdentifier Word IdentifierBeforeDot CurlyString Do Comment Program PipeExpr operator WhileExpr keyword ConditionalOp ParenExpr FunctionCall DotGet Number Dollar PositionalArg FunctionDef Params NamedParam NamedArgPrefix String StringFragment Interpolation FunctionCallOrIdentifier EscapeSeq DoubleQuote Boolean Null colon CatchExpr keyword Block FinallyExpr keyword keyword Underscore NamedArg IfExpr keyword FunctionCall ElseIfExpr keyword ElseExpr BinOp Regex Dict Array FunctionCallWithBlock TryExpr keyword Throw keyword Import keyword CompoundAssign Assign",
maxTerm: 125,
context: trackScope,
nodeProps: [
["closedBy", 57,"end"]
["closedBy", 59,"end"]
],
propSources: [highlighting],
skippedNodes: [0,34],
repeatNodeCount: 13,
tokenData: "Lq~R!OOX$RXY$pYZ%ZZp$Rpq$pqr$Rrs%tst'ztu)cuw$Rwx)hxy)myz*Wz{$R{|*q|}$R}!O*q!O!P$R!P!Q4^!Q!R+c!R![.W![!]<y!]!^%Z!^!}$R!}#O=d#O#P?Y#P#Q?_#Q#R$R#R#S?x#S#T$R#T#Y@c#Y#ZA}#Z#b@c#b#cGk#c#f@c#f#gHn#g#h@c#h#iIq#i#o@c#o#p$R#p#qLR#q;'S$R;'S;=`$j<%l~$R~O$R~~LlS$WU!TSOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RS$mP;=`<%l$R^$wU!TS#XYOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU%bU!TS#_QOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU%yZ!TSOr%trs&lst%ttu'Vuw%twx'Vx#O%t#O#P'V#P;'S%t;'S;=`'t<%lO%tU&sU!WQ!TSOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RQ'YTOr'Vrs'is;'S'V;'S;=`'n<%lO'VQ'nO!WQQ'qP;=`<%l'VU'wP;=`<%l%t^(RZrY!TSOY'zYZ$RZt'ztu(tuw'zwx(tx#O'z#O#P(t#P;'S'z;'S;=`)]<%lO'zY(ySrYOY(tZ;'S(t;'S;=`)V<%lO(tY)YP;=`<%l(t^)`P;=`<%l'z~)hO#d~~)mO#b~U)tU!TS#^QOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU*_U!TS#lQOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU*vX!TSOt$Ruw$Rx!Q$R!Q!R+c!R![.W![#O$R#P;'S$R;'S;=`$j<%lO$RU+jb!TS|QOt$Ruw$Rx!O$R!O!P,r!P!Q$R!Q![.W![#O$R#P#R$R#R#S/T#S#U$R#U#V/r#V#c$R#c#d1W#d#l$R#l#m2f#m;'S$R;'S;=`$j<%lO$RU,wW!TSOt$Ruw$Rx!Q$R!Q![-a![#O$R#P;'S$R;'S;=`$j<%lO$RU-hY!TS|QOt$Ruw$Rx!Q$R!Q![-a![#O$R#P#R$R#R#S,r#S;'S$R;'S;=`$j<%lO$RU._[!TS|QOt$Ruw$Rx!O$R!O!P,r!P!Q$R!Q![.W![#O$R#P#R$R#R#S/T#S;'S$R;'S;=`$j<%lO$RU/YW!TSOt$Ruw$Rx!Q$R!Q![.W![#O$R#P;'S$R;'S;=`$j<%lO$RU/wX!TSOt$Ruw$Rx!Q$R!Q!R0d!R!S0d!S#O$R#P;'S$R;'S;=`$j<%lO$RU0kX!TS|QOt$Ruw$Rx!Q$R!Q!R0d!R!S0d!S#O$R#P;'S$R;'S;=`$j<%lO$RU1]W!TSOt$Ruw$Rx!Q$R!Q!Y1u!Y#O$R#P;'S$R;'S;=`$j<%lO$RU1|W!TS|QOt$Ruw$Rx!Q$R!Q!Y1u!Y#O$R#P;'S$R;'S;=`$j<%lO$RU2k[!TSOt$Ruw$Rx!Q$R!Q![3a![!c$R!c!i3a!i#O$R#P#T$R#T#Z3a#Z;'S$R;'S;=`$j<%lO$RU3h[!TS|QOt$Ruw$Rx!Q$R!Q![3a![!c$R!c!i3a!i#O$R#P#T$R#T#Z3a#Z;'S$R;'S;=`$j<%lO$RU4cW!TSOt$Ruw$Rx!P$R!P!Q4{!Q#O$R#P;'S$R;'S;=`$j<%lO$RU5Q^!TSOY5|YZ$RZt5|tu7Puw5|wx7Px!P5|!P!Q$R!Q!}5|!}#O;r#O#P9_#P;'S5|;'S;=`<s<%lO5|U6T^!TS!lQOY5|YZ$RZt5|tu7Puw5|wx7Px!P5|!P!Q9t!Q!}5|!}#O;r#O#P9_#P;'S5|;'S;=`<s<%lO5|Q7UX!lQOY7PZ!P7P!P!Q7q!Q!}7P!}#O8`#O#P9_#P;'S7P;'S;=`9n<%lO7PQ7tP!P!Q7wQ7|U!lQ#Z#[7w#]#^7w#a#b7w#g#h7w#i#j7w#m#n7wQ8cVOY8`Z#O8`#O#P8x#P#Q7P#Q;'S8`;'S;=`9X<%lO8`Q8{SOY8`Z;'S8`;'S;=`9X<%lO8`Q9[P;=`<%l8`Q9bSOY7PZ;'S7P;'S;=`9n<%lO7PQ9qP;=`<%l7PU9yW!TSOt$Ruw$Rx!P$R!P!Q:c!Q#O$R#P;'S$R;'S;=`$j<%lO$RU:jb!TS!lQOt$Ruw$Rx#O$R#P#Z$R#Z#[:c#[#]$R#]#^:c#^#a$R#a#b:c#b#g$R#g#h:c#h#i$R#i#j:c#j#m$R#m#n:c#n;'S$R;'S;=`$j<%lO$RU;w[!TSOY;rYZ$RZt;rtu8`uw;rwx8`x#O;r#O#P8x#P#Q5|#Q;'S;r;'S;=`<m<%lO;rU<pP;=`<%l;rU<vP;=`<%l5|U=QU!TS!ZQOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU=kW#nQ!TSOt$Ruw$Rx!_$R!_!`>T!`#O$R#P;'S$R;'S;=`$j<%lO$RU>YV!TSOt$Ruw$Rx#O$R#P#Q>o#Q;'S$R;'S;=`$j<%lO$RU>vU#mQ!TSOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$R~?_O#e~U?fU#oQ!TSOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU@PU!TS!bQOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU@h^!TSOt$Ruw$Rx}$R}!O@c!O!Q$R!Q![@c![!_$R!_!`Ad!`#O$R#P#T$R#T#o@c#o;'S$R;'S;=`$j<%lO$RUAkU!RQ!TSOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RUBS_!TSOt$Ruw$Rx}$R}!O@c!O!Q$R!Q![@c![!_$R!_!`Ad!`#O$R#P#T$R#T#UCR#U#o@c#o;'S$R;'S;=`$j<%lO$RUCW`!TSOt$Ruw$Rx}$R}!O@c!O!Q$R!Q![@c![!_$R!_!`Ad!`#O$R#P#T$R#T#`@c#`#aDY#a#o@c#o;'S$R;'S;=`$j<%lO$RUD_`!TSOt$Ruw$Rx}$R}!O@c!O!Q$R!Q![@c![!_$R!_!`Ad!`#O$R#P#T$R#T#g@c#g#hEa#h#o@c#o;'S$R;'S;=`$j<%lO$RUEf`!TSOt$Ruw$Rx}$R}!O@c!O!Q$R!Q![@c![!_$R!_!`Ad!`#O$R#P#T$R#T#X@c#X#YFh#Y#o@c#o;'S$R;'S;=`$j<%lO$RUFo^!XQ!TSOt$Ruw$Rx}$R}!O@c!O!Q$R!Q![@c![!_$R!_!`Ad!`#O$R#P#T$R#T#o@c#o;'S$R;'S;=`$j<%lO$R^Gr^#fW!TSOt$Ruw$Rx}$R}!O@c!O!Q$R!Q![@c![!_$R!_!`Ad!`#O$R#P#T$R#T#o@c#o;'S$R;'S;=`$j<%lO$R^Hu^#hW!TSOt$Ruw$Rx}$R}!O@c!O!Q$R!Q![@c![!_$R!_!`Ad!`#O$R#P#T$R#T#o@c#o;'S$R;'S;=`$j<%lO$R^Ix`#gW!TSOt$Ruw$Rx}$R}!O@c!O!Q$R!Q![@c![!_$R!_!`Ad!`#O$R#P#T$R#T#f@c#f#gJz#g#o@c#o;'S$R;'S;=`$j<%lO$RUKP`!TSOt$Ruw$Rx}$R}!O@c!O!Q$R!Q![@c![!_$R!_!`Ad!`#O$R#P#T$R#T#i@c#i#jEa#j#o@c#o;'S$R;'S;=`$j<%lO$RULYUuQ!TSOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$R~LqO#p~",
tokenizers: [operatorTokenizer, 1, 2, 3, tokenizer, new LocalTokenGroup("[~RP!O!PU~ZO#`~~", 11)],
tokenData: "Ls~R!OOX$RXY$pYZ%ZZp$Rpq$pqr$Rrs%tst'ztu)cuw$Rwx)jxy)oyz*Yz{$R{|*s|}$R}!O*s!O!P$R!P!Q4`!Q!R+e!R![.Y![!]<{!]!^%Z!^!}$R!}#O=f#O#P?[#P#Q?a#Q#R$R#R#S?z#S#T$R#T#Y@e#Y#ZBP#Z#b@e#b#cGm#c#f@e#f#gHp#g#h@e#h#iIs#i#o@e#o#p$R#p#qLT#q;'S$R;'S;=`$j<%l~$R~O$R~~LnS$WU!USOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RS$mP;=`<%l$R^$wU!US#YYOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU%bU!US#`QOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU%yZ!USOr%trs&lst%ttu'Vuw%twx'Vx#O%t#O#P'V#P;'S%t;'S;=`'t<%lO%tU&sU!YQ!USOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RQ'YTOr'Vrs'is;'S'V;'S;=`'n<%lO'VQ'nO!YQQ'qP;=`<%l'VU'wP;=`<%l%t^(RZrY!USOY'zYZ$RZt'ztu(tuw'zwx(tx#O'z#O#P(t#P;'S'z;'S;=`)]<%lO'zY(ySrYOY(tZ;'S(t;'S;=`)V<%lO(tY)YP;=`<%l(t^)`P;=`<%l'z^)jO#e[}Q~)oO#c~U)vU!US#_QOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU*aU!US#mQOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU*xX!USOt$Ruw$Rx!Q$R!Q!R+e!R![.Y![#O$R#P;'S$R;'S;=`$j<%lO$RU+lb!US|QOt$Ruw$Rx!O$R!O!P,t!P!Q$R!Q![.Y![#O$R#P#R$R#R#S/V#S#U$R#U#V/t#V#c$R#c#d1Y#d#l$R#l#m2h#m;'S$R;'S;=`$j<%lO$RU,yW!USOt$Ruw$Rx!Q$R!Q![-c![#O$R#P;'S$R;'S;=`$j<%lO$RU-jY!US|QOt$Ruw$Rx!Q$R!Q![-c![#O$R#P#R$R#R#S,t#S;'S$R;'S;=`$j<%lO$RU.a[!US|QOt$Ruw$Rx!O$R!O!P,t!P!Q$R!Q![.Y![#O$R#P#R$R#R#S/V#S;'S$R;'S;=`$j<%lO$RU/[W!USOt$Ruw$Rx!Q$R!Q![.Y![#O$R#P;'S$R;'S;=`$j<%lO$RU/yX!USOt$Ruw$Rx!Q$R!Q!R0f!R!S0f!S#O$R#P;'S$R;'S;=`$j<%lO$RU0mX!US|QOt$Ruw$Rx!Q$R!Q!R0f!R!S0f!S#O$R#P;'S$R;'S;=`$j<%lO$RU1_W!USOt$Ruw$Rx!Q$R!Q!Y1w!Y#O$R#P;'S$R;'S;=`$j<%lO$RU2OW!US|QOt$Ruw$Rx!Q$R!Q!Y1w!Y#O$R#P;'S$R;'S;=`$j<%lO$RU2m[!USOt$Ruw$Rx!Q$R!Q![3c![!c$R!c!i3c!i#O$R#P#T$R#T#Z3c#Z;'S$R;'S;=`$j<%lO$RU3j[!US|QOt$Ruw$Rx!Q$R!Q![3c![!c$R!c!i3c!i#O$R#P#T$R#T#Z3c#Z;'S$R;'S;=`$j<%lO$RU4eW!USOt$Ruw$Rx!P$R!P!Q4}!Q#O$R#P;'S$R;'S;=`$j<%lO$RU5S^!USOY6OYZ$RZt6Otu7Ruw6Owx7Rx!P6O!P!Q$R!Q!}6O!}#O;t#O#P9a#P;'S6O;'S;=`<u<%lO6OU6V^!US!mQOY6OYZ$RZt6Otu7Ruw6Owx7Rx!P6O!P!Q9v!Q!}6O!}#O;t#O#P9a#P;'S6O;'S;=`<u<%lO6OQ7WX!mQOY7RZ!P7R!P!Q7s!Q!}7R!}#O8b#O#P9a#P;'S7R;'S;=`9p<%lO7RQ7vP!P!Q7yQ8OU!mQ#Z#[7y#]#^7y#a#b7y#g#h7y#i#j7y#m#n7yQ8eVOY8bZ#O8b#O#P8z#P#Q7R#Q;'S8b;'S;=`9Z<%lO8bQ8}SOY8bZ;'S8b;'S;=`9Z<%lO8bQ9^P;=`<%l8bQ9dSOY7RZ;'S7R;'S;=`9p<%lO7RQ9sP;=`<%l7RU9{W!USOt$Ruw$Rx!P$R!P!Q:e!Q#O$R#P;'S$R;'S;=`$j<%lO$RU:lb!US!mQOt$Ruw$Rx#O$R#P#Z$R#Z#[:e#[#]$R#]#^:e#^#a$R#a#b:e#b#g$R#g#h:e#h#i$R#i#j:e#j#m$R#m#n:e#n;'S$R;'S;=`$j<%lO$RU;y[!USOY;tYZ$RZt;ttu8buw;twx8bx#O;t#O#P8z#P#Q6O#Q;'S;t;'S;=`<o<%lO;tU<rP;=`<%l;tU<xP;=`<%l6OU=SU!US!]QOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU=mW#oQ!USOt$Ruw$Rx!_$R!_!`>V!`#O$R#P;'S$R;'S;=`$j<%lO$RU>[V!USOt$Ruw$Rx#O$R#P#Q>q#Q;'S$R;'S;=`$j<%lO$RU>xU#nQ!USOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$R~?aO#f~U?hU#pQ!USOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU@RU!US!dQOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RU@j^!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#o@e#o;'S$R;'S;=`$j<%lO$RUAmU!SQ!USOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$RUBU_!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#UCT#U#o@e#o;'S$R;'S;=`$j<%lO$RUCY`!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#`@e#`#aD[#a#o@e#o;'S$R;'S;=`$j<%lO$RUDa`!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#g@e#g#hEc#h#o@e#o;'S$R;'S;=`$j<%lO$RUEh`!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#X@e#X#YFj#Y#o@e#o;'S$R;'S;=`$j<%lO$RUFq^!ZQ!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#o@e#o;'S$R;'S;=`$j<%lO$R^Gt^#gW!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#o@e#o;'S$R;'S;=`$j<%lO$R^Hw^#iW!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#o@e#o;'S$R;'S;=`$j<%lO$R^Iz`#hW!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#f@e#f#gJ|#g#o@e#o;'S$R;'S;=`$j<%lO$RUKR`!USOt$Ruw$Rx}$R}!O@e!O!Q$R!Q![@e![!_$R!_!`Af!`#O$R#P#T$R#T#i@e#i#jEc#j#o@e#o;'S$R;'S;=`$j<%lO$RUL[UuQ!USOt$Ruw$Rx#O$R#P;'S$R;'S;=`$j<%lO$R~LsO#q~",
tokenizers: [operatorTokenizer, 1, 2, 3, tokenizer, new LocalTokenGroup("[~RP!O!PU~ZO#a~~", 11)],
topRules: {"Program":[0,35]},
specialized: [{term: 28, get: (value: any, stack: any) => (specializeKeyword(value, stack) << 1), external: specializeKeyword},{term: 28, get: (value: keyof typeof spec_Identifier) => spec_Identifier[value] || -1}],
tokenPrec: 2373
tokenPrec: 2428
})

View File

@ -447,5 +447,14 @@ end`).toMatchTree(`
Number 1
Identifier b
`)
test('parses $.pid just fine', () => {
expect(`$.pid`).toMatchTree(`
FunctionCallOrIdentifier
DotGet
Dollar $
Identifier pid
`)
})
})
})

View File

@ -8,7 +8,8 @@ describe('string interpolation', () => {
String
StringFragment ${'hello '}
Interpolation
Identifier name
FunctionCallOrIdentifier
Identifier name
`)
})
@ -44,7 +45,8 @@ describe('string interpolation', () => {
String
StringFragment x/
Interpolation
Identifier y
FunctionCallOrIdentifier
Identifier y
StringFragment /z
`)
})
@ -122,7 +124,8 @@ describe('string escape sequences', () => {
String
StringFragment value:
Interpolation
Identifier x
FunctionCallOrIdentifier
Identifier x
EscapeSeq \\n
`)
})

View File

@ -1,5 +1,6 @@
// The prelude creates all the builtin Shrimp functions.
import { join, resolve } from 'path'
import {
type Value, type VM, toValue,
extractParamInfo, isWrapped, getOriginalFunction,
@ -22,6 +23,20 @@ export const globals = {
math,
str,
// shrimp runtime info
$: {
args: Bun.argv.slice(3),
argv: Bun.argv.slice(1),
env: process.env,
pid: process.pid,
cwd: process.env.PWD,
script: {
name: Bun.argv[2] || '(shrimp)',
path: resolve(join('.', Bun.argv[2] ?? ''))
},
},
// hello
echo: (...args: any[]) => {
console.log(...args.map(a => {
@ -66,7 +81,6 @@ export const globals = {
},
// env
args: Bun.argv.slice(1),
exit: (num: number) => process.exit(num ?? 0),
// type predicates

View File

@ -80,15 +80,15 @@ describe('introspection', () => {
describe('environment', () => {
test('args is an array', async () => {
await expect(`array? args`).toEvaluateTo(true, globals)
await expect(`array? $.args`).toEvaluateTo(true, globals)
})
test('args can be accessed', async () => {
await expect(`type args`).toEvaluateTo('array', globals)
await expect(`type $.args`).toEvaluateTo('array', globals)
})
test('', async () => {
await expect(`list.first args | str.ends-with? 'shrimp.test.ts'`).toEvaluateTo(true)
test('argv includes more than just the args', async () => {
await expect(`list.first $.argv | str.ends-with? 'shrimp.test.ts'`).toEvaluateTo(true)
})
})
@ -103,3 +103,38 @@ describe('ref', () => {
expect(`rnd = ref math.random; rnd | type`).toEvaluateTo('number')
expect(`rnd = ref math.random; ref rnd | type`).toEvaluateTo('native')
})
describe('$ global dictionary', () => {
test('$.args is an array', async () => {
await expect(`$.args | array?`).toEvaluateTo(true, globals)
})
test('$.args can be accessed', async () => {
await expect(`$.args | type`).toEvaluateTo('array', globals)
})
test('$.script.name is a string', async () => {
await expect(`$.script.name | string?`).toEvaluateTo(true, globals)
})
test('$.script.path is a string', async () => {
await expect(`$.script.path | string?`).toEvaluateTo(true, globals)
})
test('$.env is a dict', async () => {
await expect(`$.env | dict?`).toEvaluateTo(true, globals)
})
test('$.pid is a number', async () => {
await expect(`$.pid | number?`).toEvaluateTo(true, globals)
await expect(`$.pid > 0`).toEvaluateTo(true, globals)
})
test('$.cwd is a string', async () => {
await expect(`$.cwd | string?`).toEvaluateTo(true, globals)
})
test('$.cwd returns current working directory', async () => {
await expect(`$.cwd`).toEvaluateTo(process.cwd(), globals)
})
})