Merge branch 'array-destructuring' into bang
This commit is contained in:
commit
bc62987abb
26
bin/repl
26
bin/repl
|
|
@ -144,19 +144,33 @@ async function repl() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
codeHistory.push(trimmed)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const compiler = new Compiler(trimmed, Object.keys(globals))
|
const compiler = new Compiler(trimmed, Object.keys(globals))
|
||||||
|
|
||||||
vm.appendBytecode(compiler.bytecode)
|
// Save VM state before appending bytecode, in case execution fails
|
||||||
|
const savedInstructions = [...vm.instructions]
|
||||||
|
const savedConstants = [...vm.constants]
|
||||||
|
const savedPc = vm.pc
|
||||||
|
const savedScope = vm.scope
|
||||||
|
const savedStopped = vm.stopped
|
||||||
|
|
||||||
const result = await vm.continue()
|
try {
|
||||||
|
vm.appendBytecode(compiler.bytecode)
|
||||||
|
const result = await vm.continue()
|
||||||
|
|
||||||
console.log(`${colors.dim}=>${colors.reset} ${formatValue(result)}`)
|
codeHistory.push(trimmed)
|
||||||
|
console.log(`${colors.dim}=>${colors.reset} ${formatValue(result)}`)
|
||||||
|
} catch (error: any) {
|
||||||
|
vm.instructions = savedInstructions
|
||||||
|
vm.constants = savedConstants
|
||||||
|
vm.pc = savedPc
|
||||||
|
vm.scope = savedScope
|
||||||
|
vm.stopped = savedStopped
|
||||||
|
|
||||||
|
console.log(`\n${colors.red}Error:${colors.reset} ${error.message}`)
|
||||||
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(`\n${colors.red}Error:${colors.reset} ${error.message}`)
|
console.log(`\n${colors.red}Error:${colors.reset} ${error.message}`)
|
||||||
codeHistory.pop()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.prompt()
|
rl.prompt()
|
||||||
|
|
|
||||||
2
bun.lock
2
bun.lock
|
|
@ -62,7 +62,7 @@
|
||||||
|
|
||||||
"hono": ["hono@4.9.8", "", {}, "sha512-JW8Bb4RFWD9iOKxg5PbUarBYGM99IcxFl2FPBo2gSJO11jjUDqlP1Bmfyqt8Z/dGhIQ63PMA9LdcLefXyIasyg=="],
|
"hono": ["hono@4.9.8", "", {}, "sha512-JW8Bb4RFWD9iOKxg5PbUarBYGM99IcxFl2FPBo2gSJO11jjUDqlP1Bmfyqt8Z/dGhIQ63PMA9LdcLefXyIasyg=="],
|
||||||
|
|
||||||
"reefvm": ["reefvm@git+https://git.nose.space/defunkt/reefvm#9618dd64148ccf6f0cdfd8a80a0f58efe3e0819d", { "peerDependencies": { "typescript": "^5" } }, "9618dd64148ccf6f0cdfd8a80a0f58efe3e0819d"],
|
"reefvm": ["reefvm@git+https://git.nose.space/defunkt/reefvm#c69b172c78853756ec8acba5bc33d93eb6a571c6", { "peerDependencies": { "typescript": "^5" } }, "c69b172c78853756ec8acba5bc33d93eb6a571c6"],
|
||||||
|
|
||||||
"style-mod": ["style-mod@4.1.2", "", {}, "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="],
|
"style-mod": ["style-mod@4.1.2", "", {}, "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="],
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
"dev": "bun generate-parser && bun --hot src/server/server.tsx",
|
"dev": "bun generate-parser && bun --hot src/server/server.tsx",
|
||||||
"generate-parser": "lezer-generator src/parser/shrimp.grammar --typeScript -o src/parser/shrimp.ts",
|
"generate-parser": "lezer-generator src/parser/shrimp.grammar --typeScript -o src/parser/shrimp.ts",
|
||||||
"repl": "bun generate-parser && bun bin/repl",
|
"repl": "bun generate-parser && bun bin/repl",
|
||||||
"update-reef": "cd packages/ReefVM && git pull origin main"
|
"update-reef": "rm -rf ~/.bun/install/cache/ && bun update reefvm"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/view": "^6.38.3",
|
"@codemirror/view": "^6.38.3",
|
||||||
|
|
|
||||||
|
|
@ -237,11 +237,31 @@ export class Compiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
case terms.Assign: {
|
case terms.Assign: {
|
||||||
const { identifier, right } = getAssignmentParts(node)
|
const assignParts = getAssignmentParts(node)
|
||||||
const instructions: ProgramItem[] = []
|
const instructions: ProgramItem[] = []
|
||||||
instructions.push(...this.#compileNode(right, input))
|
|
||||||
instructions.push(['DUP']) // Keep a copy on the stack after storing
|
// right-hand side
|
||||||
const identifierName = input.slice(identifier.from, identifier.to)
|
instructions.push(...this.#compileNode(assignParts.right, input))
|
||||||
|
|
||||||
|
// array destructuring: [ a b ] = [ 1 2 3 4 ]
|
||||||
|
if ('arrayPattern' in assignParts) {
|
||||||
|
const identifiers = assignParts.arrayPattern ?? []
|
||||||
|
if (identifiers.length === 0) return instructions
|
||||||
|
|
||||||
|
for (let i = 0; i < identifiers.length; i++) {
|
||||||
|
instructions.push(['DUP'])
|
||||||
|
instructions.push(['PUSH', i])
|
||||||
|
instructions.push(['DOT_GET'])
|
||||||
|
instructions.push(['STORE', input.slice(identifiers[i]!.from, identifiers[i]!.to)])
|
||||||
|
}
|
||||||
|
|
||||||
|
// original array still on stack as the return value
|
||||||
|
return instructions
|
||||||
|
}
|
||||||
|
|
||||||
|
// simple assignment: x = value
|
||||||
|
instructions.push(['DUP'])
|
||||||
|
const identifierName = input.slice(assignParts.identifier.from, assignParts.identifier.to)
|
||||||
instructions.push(['STORE', identifierName])
|
instructions.push(['STORE', identifierName])
|
||||||
|
|
||||||
return instructions
|
return instructions
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,28 @@ describe('compiler', () => {
|
||||||
expect('sum = 2 + 3; sum').toEvaluateTo(5)
|
expect('sum = 2 + 3; sum').toEvaluateTo(5)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('array destructuring with two variables', () => {
|
||||||
|
expect('[ a b ] = [ 1 2 3 4 ]; a').toEvaluateTo(1)
|
||||||
|
expect('[ a b ] = [ 1 2 3 4 ]; b').toEvaluateTo(2)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('array destructuring with one variable', () => {
|
||||||
|
expect('[ x ] = [ 42 ]; x').toEvaluateTo(42)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('array destructuring with missing elements assigns null', () => {
|
||||||
|
expect('[ a b c ] = [ 1 2 ]; c').toEvaluateTo(null)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('array destructuring returns the original array', () => {
|
||||||
|
expect('[ a b ] = [ 1 2 3 4 ]').toEvaluateTo([1, 2, 3, 4])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('array destructuring with emoji identifiers', () => {
|
||||||
|
expect('[ 🚀 💎 ] = [ 1 2 ]; 🚀').toEvaluateTo(1)
|
||||||
|
expect('[ 🚀 💎 ] = [ 1 2 ]; 💎').toEvaluateTo(2)
|
||||||
|
})
|
||||||
|
|
||||||
test('parentheses', () => {
|
test('parentheses', () => {
|
||||||
expect('(2 + 3) * 4').toEvaluateTo(20)
|
expect('(2 + 3) * 4').toEvaluateTo(20)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -40,15 +40,23 @@ export const getAssignmentParts = (node: SyntaxNode) => {
|
||||||
const children = getAllChildren(node)
|
const children = getAllChildren(node)
|
||||||
const [left, equals, right] = children
|
const [left, equals, right] = children
|
||||||
|
|
||||||
if (!left || left.type.id !== terms.AssignableIdentifier) {
|
if (!equals || !right) {
|
||||||
throw new CompilerError(
|
throw new CompilerError(
|
||||||
`Assign left child must be an AssignableIdentifier, got ${left ? left.type.name : 'none'}`,
|
`Assign expected 3 children, got ${children.length}`,
|
||||||
node.from,
|
node.from,
|
||||||
node.to
|
node.to
|
||||||
)
|
)
|
||||||
} else if (!equals || !right) {
|
}
|
||||||
|
|
||||||
|
// array destructuring
|
||||||
|
if (left && left.type.id === terms.Array) {
|
||||||
|
const identifiers = getAllChildren(left).filter(child => child.type.id === terms.Identifier)
|
||||||
|
return { arrayPattern: identifiers, right }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!left || left.type.id !== terms.AssignableIdentifier) {
|
||||||
throw new CompilerError(
|
throw new CompilerError(
|
||||||
`Assign expected 3 children, got ${children.length}`,
|
`Assign left child must be an AssignableIdentifier or Array, got ${left ? left.type.name : 'none'}`,
|
||||||
node.from,
|
node.from,
|
||||||
node.to
|
node.to
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,7 @@ Params {
|
||||||
}
|
}
|
||||||
|
|
||||||
Assign {
|
Assign {
|
||||||
AssignableIdentifier Eq consumeToTerminator
|
(AssignableIdentifier | Array) Eq consumeToTerminator
|
||||||
}
|
}
|
||||||
|
|
||||||
BinOp {
|
BinOp {
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ import {highlighting} from "./highlight"
|
||||||
const spec_Identifier = {__proto__:null,catch:82, finally:88, end:90, null:96, try:106, throw:110, if:114, elseif:122, else:126}
|
const spec_Identifier = {__proto__:null,catch:82, finally:88, end:90, null:96, try:106, throw:110, if:114, elseif:122, else:126}
|
||||||
export const parser = LRParser.deserialize({
|
export const parser = LRParser.deserialize({
|
||||||
version: 14,
|
version: 14,
|
||||||
states: "8xQYQbOOO#tQcO'#CvO$qOSO'#CxO%PQbO'#E`OOQ`'#DR'#DROOQa'#DO'#DOO&SQbO'#D]O'XQcO'#ETOOQa'#ET'#ETO)cQcO'#ESO)vQRO'#CwO+SQcO'#EOO+dQcO'#EOO+nQbO'#CuO,fOpO'#CsOOQ`'#EP'#EPO,kQbO'#EOO,rQQO'#EfOOQ`'#Db'#DbO,wQbO'#DdO,wQbO'#EhOOQ`'#Df'#DfO-lQRO'#DnOOQ`'#EO'#EOO-qQQO'#D}OOQ`'#D}'#D}OOQ`'#Do'#DoQYQbOOO-yQbO'#DPOOQa'#ES'#ESOOQ`'#D`'#D`OOQ`'#Ee'#EeOOQ`'#Dv'#DvO.TQbO,59^O.nQbO'#CzO.vQWO'#C{OOOO'#EV'#EVOOOO'#Dp'#DpO/[OSO,59dOOQa,59d,59dOOQ`'#Dr'#DrO/jQbO'#DSO/rQQO,5:zOOQ`'#Dq'#DqO/wQbO,59wO0OQQO,59jOOQa,59w,59wO0ZQbO,59wO,wQbO,59cO,wQbO,59cO,wQbO,59cO,wQbO,59yO,wQbO,59yO,wQbO,59yO0eQRO,59aO0lQRO,59aO0}QRO,59aO0xQQO,59aO1YQQO,59aO1bObO,59_O1mQbO'#DwO1xQbO,59]O2aQbO,5;QO2tQcO,5:OO3jQcO,5:OO3zQcO,5:OO4pQRO,5;SO4wQRO,5;SO5SQbO,5:YOOQ`,5:i,5:iOOQ`-E7m-E7mOOQ`,59k,59kOOQ`-E7t-E7tOOOO,59f,59fOOOO,59g,59gOOOO-E7n-E7nOOQa1G/O1G/OOOQ`-E7p-E7pO5dQbO1G0fOOQ`-E7o-E7oO5wQQO1G/UOOQa1G/c1G/cO6SQbO1G/cOOQO'#Dt'#DtO5wQQO1G/UOOQa1G/U1G/UOOQ`'#Du'#DuO6SQbO1G/cOOQa1G.}1G.}O6{QcO1G.}O7VQcO1G.}O7aQcO1G.}OOQa1G/e1G/eO9PQcO1G/eO9WQcO1G/eO9_QcO1G/eOOQa1G.{1G.{OOQa1G.y1G.yO!aQbO'#CvO&ZQbO'#CrOOQ`,5:c,5:cOOQ`-E7u-E7uO9fQbO1G0lO9qQbO1G0mO:_QbO1G0nOOQ`1G/t1G/tO:rQbO7+&QO9qQbO7+&SO:}QQO7+$pOOQa7+$p7+$pO;YQbO7+$}OOQa7+$}7+$}OOQO-E7r-E7rOOQ`-E7s-E7sO;dQbO'#DUO;iQQO'#DXOOQ`7+&W7+&WO;nQbO7+&WO;sQbO7+&WOOQ`'#Ds'#DsO;{QQO'#DsO<QQbO'#EaOOQ`'#DW'#DWO<tQbO7+&XOOQ`'#Dh'#DhO=PQbO7+&YO=UQbO7+&ZOOQ`<<Il<<IlO=rQbO<<IlO=wQbO<<IlO>PQbO<<InOOQa<<H[<<H[OOQa<<Hi<<HiO>[QQO,59pO>aQbO,59sOOQ`<<Ir<<IrO>tQbO<<IrOOQ`,5:_,5:_OOQ`-E7q-E7qOOQ`<<Is<<IsO>yQbO<<IsO?OQbO<<IsOOQ`<<It<<ItOOQ`'#Di'#DiO?WQbO<<IuOOQ`AN?WAN?WO?cQbOAN?WOOQ`AN?YAN?YO?hQbOAN?YO?mQbOAN?YO?uQbO1G/[O@YQbO1G/_OOQ`1G/_1G/_OOQ`AN?^AN?^OOQ`AN?_AN?_O@pQbOAN?_O,wQbO'#DjOOQ`'#Dx'#DxO@uQbOAN?aOAQQQO'#DlOOQ`AN?aAN?aOAVQbOAN?aOOQ`G24rG24rOOQ`G24tG24tOA[QbOG24tOAaQbO7+$vOOQ`7+$v7+$vOOQ`7+$y7+$yOOQ`G24yG24yOAzQRO,5:UOBRQRO,5:UOOQ`-E7v-E7vOOQ`G24{G24{OB^QbOG24{OBcQQO,5:WOOQ`LD*`LD*`OOQ`<<Hb<<HbOBhQQO1G/pOOQ`LD*gLD*gO@YQbO1G/rO=UQbO7+%[OOQ`7+%^7+%^OOQ`<<Hv<<Hv",
|
states: "9OQYQbOOO#tQcO'#CvO$qOSO'#CxO%PQbO'#E`OOQ`'#DR'#DROOQa'#DO'#DOO&SQbO'#D]O'eQcO'#ETOOQa'#ET'#ETO(hQcO'#ETO)jQcO'#ESO)}QRO'#CwO+ZQcO'#EOO+kQcO'#EOO+uQbO'#CuO,mOpO'#CsOOQ`'#EP'#EPO,rQbO'#EOO,yQQO'#EfOOQ`'#Db'#DbO-OQbO'#DdO-OQbO'#EhOOQ`'#Df'#DfO-sQRO'#DnOOQ`'#EO'#EOO-xQQO'#D}OOQ`'#D}'#D}OOQ`'#Do'#DoQYQbOOO.QQbO'#DPOOQa'#ES'#ESOOQ`'#D`'#D`OOQ`'#Ee'#EeOOQ`'#Dv'#DvO.[QbO,59^O/OQbO'#CzO/WQWO'#C{OOOO'#EV'#EVOOOO'#Dp'#DpO/lOSO,59dOOQa,59d,59dOOQ`'#Dr'#DrO/zQbO'#DSO0SQQO,5:zOOQ`'#Dq'#DqO0XQbO,59wO0`QQO,59jOOQa,59w,59wO0kQbO,59wO0uQbO,5:YO-OQbO,59cO-OQbO,59cO-OQbO,59cO-OQbO,59yO-OQbO,59yO-OQbO,59yO1VQRO,59aO1^QRO,59aO1oQRO,59aO1jQQO,59aO1zQQO,59aO2SObO,59_O2_QbO'#DwO2jQbO,59]O3RQbO,5;QO3fQcO,5:OO4[QcO,5:OO4lQcO,5:OO5bQRO,5;SO5iQRO,5;SOOQ`,5:i,5:iOOQ`-E7m-E7mOOQ`,59k,59kOOQ`-E7t-E7tOOOO,59f,59fOOOO,59g,59gOOOO-E7n-E7nOOQa1G/O1G/OOOQ`-E7p-E7pO5tQbO1G0fOOQ`-E7o-E7oO6XQQO1G/UOOQa1G/c1G/cO6dQbO1G/cOOQO'#Dt'#DtO6XQQO1G/UOOQa1G/U1G/UOOQ`'#Du'#DuO6dQbO1G/cOOQ`1G/t1G/tOOQa1G.}1G.}O7]QcO1G.}O7gQcO1G.}O7qQcO1G.}OOQa1G/e1G/eO9aQcO1G/eO9hQcO1G/eO9oQcO1G/eOOQa1G.{1G.{OOQa1G.y1G.yO!aQbO'#CvO9vQbO'#CrOOQ`,5:c,5:cOOQ`-E7u-E7uO:TQbO1G0lO:`QbO1G0mO:|QbO1G0nO;aQbO7+&QO:`QbO7+&SO;lQQO7+$pOOQa7+$p7+$pO;wQbO7+$}OOQa7+$}7+$}OOQO-E7r-E7rOOQ`-E7s-E7sO<RQbO'#DUO<WQQO'#DXOOQ`7+&W7+&WO<]QbO7+&WO<bQbO7+&WOOQ`'#Ds'#DsO<jQQO'#DsO<oQbO'#EaOOQ`'#DW'#DWO=cQbO7+&XOOQ`'#Dh'#DhO=nQbO7+&YO=sQbO7+&ZOOQ`<<Il<<IlO>aQbO<<IlO>fQbO<<IlO>nQbO<<InOOQa<<H[<<H[OOQa<<Hi<<HiO>yQQO,59pO?OQbO,59sOOQ`<<Ir<<IrO?cQbO<<IrOOQ`,5:_,5:_OOQ`-E7q-E7qOOQ`<<Is<<IsO?hQbO<<IsO?mQbO<<IsOOQ`<<It<<ItOOQ`'#Di'#DiO?uQbO<<IuOOQ`AN?WAN?WO@QQbOAN?WOOQ`AN?YAN?YO@VQbOAN?YO@[QbOAN?YO@dQbO1G/[O@wQbO1G/_OOQ`1G/_1G/_OOQ`AN?^AN?^OOQ`AN?_AN?_OA_QbOAN?_O-OQbO'#DjOOQ`'#Dx'#DxOAdQbOAN?aOAoQQO'#DlOOQ`AN?aAN?aOAtQbOAN?aOOQ`G24rG24rOOQ`G24tG24tOAyQbOG24tOBOQbO7+$vOOQ`7+$v7+$vOOQ`7+$y7+$yOOQ`G24yG24yOBiQRO,5:UOBpQRO,5:UOOQ`-E7v-E7vOOQ`G24{G24{OB{QbOG24{OCQQQO,5:WOOQ`LD*`LD*`OOQ`<<Hb<<HbOCVQQO1G/pOOQ`LD*gLD*gO@wQbO1G/rO=sQbO7+%[OOQ`7+%^7+%^OOQ`<<Hv<<Hv",
|
||||||
stateData: "Bp~O!oOS!pOS~O_PO`fOaWOb^OcROhWOpWOqWO!QWO!VaO!XcO!ZdO!u]O!xQO#PTO#QUO#RiO~O_mOaWOb^OcROhWOpWOqWOtlO!OnO!QWO!u]O!xQO#PTO#QUO!TjX#RjX#^jX#WjXyjX|jX}jX~OP!vXQ!vXR!vXS!vXT!vXU!vXW!vXX!vXY!vXZ!vX[!vX]!vX^!vX~P!aOmtO!xwO!zrO!{sO~O_xOwvP~O_mOaWOb^OhWOpWOqWOtlO!QWO!u]O!xQO#PTO#QUO#R{O~O#V!OO~P%XO_mOaWOb^OcROhWOpWOqWOtlO!OnO!QWO!u]O!xQO#PTO#QUO~OP!wXQ!wXR!wXS!wXT!wXU!wXW!wXX!wXY!wXZ!wX[!wX]!wX^!wX#R!wX#^!wX#W!wXy!wX|!wX}!wX~P&ZOP!vXQ!vXR!vXS!vXT!vXU!vXW!vXX!vXY!vXZ!vX[!vX]!vX^!vX~O#R!rX#^!rXy!rX|!rX}!rX~P(hOP!ROQ!ROR!SOS!SOT!UOU!VOW!TOX!TOY!TOZ!TO[!TO]!TO^!QO~O#R!rX#^!rXy!rX|!rX}!rX~OP!ROQ!ROR!SOS!SO~P*qOT!UOU!VO~P*qO_POaWOb^OcROhWOpWOqWO!QWO!u]O!xQO#PTO#QUO~O!t!]O~O!T!^O~P*qOw!`O~O_mOaWOb^OhWOpWOqWO!QWO!u]O!xQO#PTO#QUO~OV!fO~O#R!gO#^!gO~OcRO!O!iO~P,wO!Tfa#Rfa#^fa#Wfayfa|fa}fa~P&ZO_!kO!u]O~O!x!lO!z!lO!{!lO!|!lO!}!lO#O!lO~OmtO!x!nO!zrO!{sO~O_xOwvX~Ow!pO~O#V!sO~P%XOtlO#R!uO#V!wO~O#R!xO#V!sO~P,wO#W#SO~P(hOP!ROQ!ROR!SOS!SO#W#SO~OT!UOU!VO#W#SO~O!T!^O#W#SO~O_#TOh#TO!u]O~O_#UOb^O!u]O~O!T!^O#Rea#^ea#Weayea|ea}ea~O`fO!VaO!XcO!ZdO#R#ZO~P+nO#R!Wa#^!Way!Wa|!Wa}!Wa~P)vO#R!Wa#^!Way!Wa|!Wa}!Wa~OP!ROQ!ROR!SOS!SO~P3XOT!UOU!VO~P3XOT!UOU!VOW!TOX!TOY!TOZ!TO[!TO]!TO~Ow#[O~P4UOT!UOU!VOw#[O~O`fO!VaO!XcO!ZdO~P+nO`fO!VaO!XcO!ZdO#R#_O~P+nOtlO#R!uO#V#aO~O#R!xO#V#cO~P,wO^!QORkiSki#Rki#^ki#Wkiyki|ki}ki~OPkiQki~P6^OP!ROQ!RO~P6^OP!ROQ!RORkiSki#Rki#^ki#Wkiyki|ki}ki~OW!TOX!TOY!TOZ!TO[!TO]!TOT!Ri#R!Ri#^!Ri#W!Riw!Riy!Ri|!Ri}!Ri~OU!VO~P8ROU!VO~P8eOU!Ri~P8ROy#fO|#gO}#hO~O`fO!VaO!XcO!ZdO#R#kOy#TP|#TP}#TP~P+nO`fO!VaO!XcO!ZdO#R#rO~P+nOy#fO|#gO}#sO~OtlO#R!uO#V#wO~O#R!xO#V#xO~P,wO_#yO~Ow#zO~O}#{O~O|#gO}#{O~O#R#}O~O`fO!VaO!XcO!ZdO#R#kOy#TX|#TX}#TX!_#TX!a#TX~P+nOy#fO|#gO}$PO~O}$SO~O`fO!VaO!XcO!ZdO#R#kO}#TP!_#TP!a#TP~P+nO}$VO~O|#gO}$VO~Oy#fO|#gO}$XO~Ow$[O~O`fO!VaO!XcO!ZdO#R$]O~P+nO}$_O~O}$`O~O|#gO}$`O~O}$fO!_$bO!a$eO~O}$hO~O}$iO~O|#gO}$iO~O`fO!VaO!XcO!ZdO#R$kO~P+nO`fO!VaO!XcO!ZdO#R#kO}#TP~P+nO}$nO~O}$rO!_$bO!a$eO~Ow$tO~O}$rO~O}$uO~O`fO!VaO!XcO!ZdO#R#kO|#TP}#TP~P+nOw$wO~P4UOT!UOU!VOw$wO~O}$xO~O#R$yO~O#R$zO~Ohq~",
|
stateData: "C_~O!oOS!pOS~O_PO`gOaWOb_OcROhWOpWOqWO!QWO!VbO!XdO!ZeO!u^O!xQO#PTO#QUO#RjO~O_nOaWOb_OcROhWOpWOqWOtmO!OoO!QWO!u^O!xQO#PTO#QUO!TjX#RjX#^jX#WjXyjX|jX}jX~OP!vXQ!vXR!vXS!vXT!vXU!vXW!vXX!vXY!vXZ!vX[!vX]!vX^!vX~P!aOmuO!xxO!zsO!{tO~O_yOwvP~O_nOaWOb_OhWOpWOqWOtmO!QWO!u^O!xQO#PTO#QUO#R|O~O#V!PO~P%XOP!wXQ!wXR!wXS!wXT!wXU!wXW!wXX!wXY!wXZ!wX[!wX]!wX^!wX#R!wX#^!wXy!wX|!wX}!wX~O_nOaWOb_OcROhWOpWOqWOtmO!OoO!QWO!u^O!xQO#PTO#QUO#W!wX~P&ZOV!RO~P&ZOP!vXQ!vXR!vXS!vXT!vXU!vXW!vXX!vXY!vXZ!vX[!vX]!vX^!vX~O#R!rX#^!rXy!rX|!rX}!rX~P(oOP!TOQ!TOR!UOS!UOT!WOU!XOW!VOX!VOY!VOZ!VO[!VO]!VO^!SO~O#R!rX#^!rXy!rX|!rX}!rX~OP!TOQ!TOR!UOS!UO~P*xOT!WOU!XO~P*xO_POaWOb_OcROhWOpWOqWO!QWO!u^O!xQO#PTO#QUO~O!t!_O~O!T!`O~P*xOw!bO~O_nOaWOb_OhWOpWOqWO!QWO!u^O!xQO#PTO#QUO~OV!RO~O#R!hO#^!hO~OcRO!O!jO~P-OOcROtmO!OoO!Tfa#Rfa#^fa#Wfayfa|fa}fa~P-OO_!lO!u^O~O!x!mO!z!mO!{!mO!|!mO!}!mO#O!mO~OmuO!x!oO!zsO!{tO~O_yOwvX~Ow!qO~O#V!tO~P%XOtmO#R!vO#V!xO~O#R!yO#V!tO~P-OO`gO!VbO!XdO!ZeO~P+uO#W#UO~P(oOP!TOQ!TOR!UOS!UO#W#UO~OT!WOU!XO#W#UO~O!T!`O#W#UO~O_#VOh#VO!u^O~O_#WOb_O!u^O~O!T!`O#Rea#^ea#Weayea|ea}ea~O`gO!VbO!XdO!ZeO#R#]O~P+uO#R!Wa#^!Way!Wa|!Wa}!Wa~P)}O#R!Wa#^!Way!Wa|!Wa}!Wa~OP!TOQ!TOR!UOS!UO~P3yOT!WOU!XO~P3yOT!WOU!XOW!VOX!VOY!VOZ!VO[!VO]!VO~Ow#^O~P4vOT!WOU!XOw#^O~O`gO!VbO!XdO!ZeO#R#`O~P+uOtmO#R!vO#V#bO~O#R!yO#V#dO~P-OO^!SORkiSki#Rki#^ki#Wkiyki|ki}ki~OPkiQki~P6nOP!TOQ!TO~P6nOP!TOQ!TORkiSki#Rki#^ki#Wkiyki|ki}ki~OW!VOX!VOY!VOZ!VO[!VO]!VOT!Ri#R!Ri#^!Ri#W!Riw!Riy!Ri|!Ri}!Ri~OU!XO~P8cOU!XO~P8uOU!Ri~P8cOcROtmO!OoO~P-OOy#gO|#hO}#iO~O`gO!VbO!XdO!ZeO#R#lOy#TP|#TP}#TP~P+uO`gO!VbO!XdO!ZeO#R#sO~P+uOy#gO|#hO}#tO~OtmO#R!vO#V#xO~O#R!yO#V#yO~P-OO_#zO~Ow#{O~O}#|O~O|#hO}#|O~O#R$OO~O`gO!VbO!XdO!ZeO#R#lOy#TX|#TX}#TX!_#TX!a#TX~P+uOy#gO|#hO}$QO~O}$TO~O`gO!VbO!XdO!ZeO#R#lO}#TP!_#TP!a#TP~P+uO}$WO~O|#hO}$WO~Oy#gO|#hO}$YO~Ow$]O~O`gO!VbO!XdO!ZeO#R$^O~P+uO}$`O~O}$aO~O|#hO}$aO~O}$gO!_$cO!a$fO~O}$iO~O}$jO~O|#hO}$jO~O`gO!VbO!XdO!ZeO#R$lO~P+uO`gO!VbO!XdO!ZeO#R#lO}#TP~P+uO}$oO~O}$sO!_$cO!a$fO~Ow$uO~O}$sO~O}$vO~O`gO!VbO!XdO!ZeO#R#lO|#TP}#TP~P+uOw$xO~P4vOT!WOU!XOw$xO~O}$yO~O#R$zO~O#R${O~Ohq~",
|
||||||
goto: "3U#^PPPPPPPPPPPPPPPPPPPPP#_#t$YP%X#t&^&|P'v'vPP&|'zP(_)OP)RP)_)hPPP&|P*Q*vP*}P*}P*}P+a+d+mP+qP*}+w+},T,Z,a,m,w-R-[-cPPPP-i-m._PP.w0_P1]PPPPPPPP1a1z1aPP2X2`2`2r2rpgOk!`!f!p#Z#[#_#m#r#z$[$]$k$y$zR!Z]u_O]k!^!`!f!p#Z#[#_#m#r#z$[$]$k$y$zrPO]k!`!f!p#Z#[#_#m#r#z$[$]$k$y$zzmPUVcdlq|!P!Q!R!S!T!U!V!t!y#U#V#b$bR#U!^rVO]k!`!f!p#Z#[#_#m#r#z$[$]$k$y$zzWPUVcdlq|!P!Q!R!S!T!U!V!t!y#U#V#b$bQ!krQ#T!]R#V!^pZOk!`!f!p#Z#[#_#m#r#z$[$]$k$y$zQ!X]Q!bcQ!z!RR!}!S!oWOPUV]cdklq|!P!Q!R!S!T!U!V!`!f!p!t!y#U#V#Z#[#_#b#m#r#z$[$]$b$k$y$zTtQvYoPVq#U#VQ}UQ!r|X!u}!r!v#`pgOk!`!f!p#Z#[#_#m#r#z$[$]$k$y$zYnPVq#U#VQ!Z]R!ilRzRQ#j#YQ#u#^Q$R#oR$Z#vQ#o#ZQ$m$]R$v$kQ#i#YQ#t#^Q#|#jQ$Q#oQ$W#uQ$Y#vQ$a$RR$j$Zp[Ok!`!f!p#Z#[#_#m#r#z$[$]$k$y$zQ!Y]Q!ccQ!edQ#O!VQ#Q!UR$p$bZoPVq#U#VqgOk!`!f!p#Z#[#_#m#r#z$[$]$k$y$zR#q#[Q$U#rQ${$yR$|$zT$c$U$dQ$g$UR$s$dQkOR!hkQvQR!mvQ|UR!q|QyRR!oy^#m#Z#_#r$]$k$y$zR$O#mQ!v}Q#`!rT#d!v#`Q!y!PQ#b!tT#e!y#bWqPV#U#VR!jqS!_`![R#X!_Q$d$UR$q$dTjOkShOkQ#Y!`Q#]!fQ#^!p`#l#Z#_#m#r$]$k$y$zQ#p#[Q$^#zR$l$[p`Ok!`!f!p#Z#[#_#m#r#z$[$]$k$y$zQ![]R#W!^rYO]k!`!f!p#Z#[#_#m#r#z$[$]$k$y$zYnPVq#U#VQ!PUQ!acQ!ddQ!ilQ!t|W!x!P!t!y#bQ!z!QQ!{!RQ!|!SQ#O!TQ#P!UQ#R!VR$o$bpXOk!`!f!p#Z#[#_#m#r#z$[$]$k$y$zzmPUVcdlq|!P!Q!R!S!T!U!V!t!y#U#V#b$bR!W]TuQv!PSOPV]klq!`!f!p#U#V#Z#[#_#m#r#z$[$]$k$y$zU#n#Z$]$kQ#v#_V$T#r$y$zZpPVq#U#VqbOk!`!f!p#Z#[#_#m#r#z$[$]$k$y$zqeOk!`!f!p#Z#[#_#m#r#z$[$]$k$y$z",
|
goto: "4Q#^PPPPPPPPPPPPPPPPPPPPP#_#t$YP%X#t&^&|P'v'vPP&|'zP(_)OP)RP)_)hPPP*QP*|+rP+yP+yP+yP,],`,iP,mP+y,s,y-P-V-]-i-s-}.W._PPPP.e.i/ZPP/s1ZP2XPPPPPPPP2]2v2]PP3T3[3[3n3nphOl!R!b!q#]#^#`#n#s#{$]$^$l$z${R!]^u`O^l!R!`!b!q#]#^#`#n#s#{$]$^$l$z${rPO^l!R!b!q#]#^#`#n#s#{$]$^$l$z${znPUVdemr}!Q!S!T!U!V!W!X!u!z#W#X#c$cR#W!`rVO^l!R!b!q#]#^#`#n#s#{$]$^$l$z${zWPUVdemr}!Q!S!T!U!V!W!X!u!z#W#X#c$cQ!lsQ#V!_R#X!`p[Ol!R!b!q#]#^#`#n#s#{$]$^$l$z${Q!Z^Q!ddQ!|!TR#P!U!oWOPUV^delmr}!Q!R!S!T!U!V!W!X!b!q!u!z#W#X#]#^#`#c#n#s#{$]$^$c$l$z${TuQwYpPVr#W#XQ!OUQ!s}X!v!O!s!w#aphOl!R!b!q#]#^#`#n#s#{$]$^$l$z${YoPVr#W#XQ!]^R!jmR{RQ#k#[Q#v#_Q$S#pR$[#wQ#p#]Q$n$^R$w$lQ#j#[Q#u#_Q#}#kQ$R#pQ$X#vQ$Z#wQ$b$SR$k$[|WPUV^demr}!Q!S!T!U!V!W!X!u!z#W#X#c$cqXOl!R!b!q#]#^#`#n#s#{$]$^$l$z${p]Ol!R!b!q#]#^#`#n#s#{$]$^$l$z${Q![^Q!edQ!geQ#Q!XQ#S!WR$q$cZpPVr#W#XqhOl!R!b!q#]#^#`#n#s#{$]$^$l$z${R#r#^Q$V#sQ$|$zR$}${T$d$V$eQ$h$VR$t$eQlOR!ilQwQR!nwQ}UR!r}QzRR!pz^#n#]#`#s$^$l$z${R$P#nQ!w!OQ#a!sT#e!w#aQ!z!QQ#c!uT#f!z#cWrPV#W#XR!krS!aa!^R#Z!aQ$e$VR$r$eTkOlSiOlQ!{!RQ#[!bQ#_!q`#m#]#`#n#s$^$l$z${Q#q#^Q$_#{R$m$]paOl!R!b!q#]#^#`#n#s#{$]$^$l$z${Q!^^R#Y!`rZO^l!R!b!q#]#^#`#n#s#{$]$^$l$z${YoPVr#W#XQ!QUQ!cdQ!feQ!jmQ!u}W!y!Q!u!z#cQ!|!SQ!}!TQ#O!UQ#Q!VQ#R!WQ#T!XR$p$cpYOl!R!b!q#]#^#`#n#s#{$]$^$l$z${znPUVdemr}!Q!S!T!U!V!W!X!u!z#W#X#c$cR!Y^TvQw!PSOPV^lmr!R!b!q#W#X#]#^#`#n#s#{$]$^$l$z${U#o#]$^$lQ#w#`V$U#s$z${ZqPVr#W#XqcOl!R!b!q#]#^#`#n#s#{$]$^$l$z${qfOl!R!b!q#]#^#`#n#s#{$]$^$l$z${",
|
||||||
nodeNames: "⚠ Star Slash Plus Minus And Or Eq EqEq Neq Lt Lte Gt Gte Modulo Identifier AssignableIdentifier Word IdentifierBeforeDot Do Program PipeExpr FunctionCall DotGet Number ParenExpr FunctionCallOrIdentifier BinOp String StringFragment Interpolation EscapeSeq Boolean Regex Dict NamedArg NamedArgPrefix FunctionDef Params colon CatchExpr keyword TryBlock FinallyExpr keyword keyword Underscore Array Null ConditionalOp PositionalArg operator TryExpr keyword Throw keyword IfExpr keyword SingleLineThenBlock ThenBlock ElseIfExpr keyword ElseExpr keyword Assign",
|
nodeNames: "⚠ Star Slash Plus Minus And Or Eq EqEq Neq Lt Lte Gt Gte Modulo Identifier AssignableIdentifier Word IdentifierBeforeDot Do Program PipeExpr FunctionCall DotGet Number ParenExpr FunctionCallOrIdentifier BinOp String StringFragment Interpolation EscapeSeq Boolean Regex Dict NamedArg NamedArgPrefix FunctionDef Params colon CatchExpr keyword TryBlock FinallyExpr keyword keyword Underscore Array Null ConditionalOp PositionalArg operator TryExpr keyword Throw keyword IfExpr keyword SingleLineThenBlock ThenBlock ElseIfExpr keyword ElseExpr keyword Assign",
|
||||||
maxTerm: 106,
|
maxTerm: 106,
|
||||||
context: trackScope,
|
context: trackScope,
|
||||||
|
|
@ -23,5 +23,5 @@ export const parser = LRParser.deserialize({
|
||||||
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!t~~", 11)],
|
||||||
topRules: {"Program":[0,20]},
|
topRules: {"Program":[0,20]},
|
||||||
specialized: [{term: 15, get: (value: any, stack: any) => (specializeKeyword(value, stack) << 1), external: specializeKeyword},{term: 15, get: (value: keyof typeof spec_Identifier) => spec_Identifier[value] || -1}],
|
specialized: [{term: 15, get: (value: any, stack: any) => (specializeKeyword(value, stack) << 1), external: specializeKeyword},{term: 15, get: (value: keyof typeof spec_Identifier) => spec_Identifier[value] || -1}],
|
||||||
tokenPrec: 1547
|
tokenPrec: 1576
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -594,6 +594,44 @@ describe('Comments', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('Array destructuring', () => {
|
||||||
|
test('parses array pattern with two variables', () => {
|
||||||
|
expect('[ a b ] = [ 1 2 3 4]').toMatchTree(`
|
||||||
|
Assign
|
||||||
|
Array
|
||||||
|
Identifier a
|
||||||
|
Identifier b
|
||||||
|
Eq =
|
||||||
|
Array
|
||||||
|
Number 1
|
||||||
|
Number 2
|
||||||
|
Number 3
|
||||||
|
Number 4`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('parses array pattern with one variable', () => {
|
||||||
|
expect('[ x ] = [ 42 ]').toMatchTree(`
|
||||||
|
Assign
|
||||||
|
Array
|
||||||
|
Identifier x
|
||||||
|
Eq =
|
||||||
|
Array
|
||||||
|
Number 42`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('parses array pattern with emoji identifiers', () => {
|
||||||
|
expect('[ 🚀 💎 ] = [ 1 2 ]').toMatchTree(`
|
||||||
|
Assign
|
||||||
|
Array
|
||||||
|
Identifier 🚀
|
||||||
|
Identifier 💎
|
||||||
|
Eq =
|
||||||
|
Array
|
||||||
|
Number 1
|
||||||
|
Number 2`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('Conditional ops', () => {
|
describe('Conditional ops', () => {
|
||||||
test('or can be chained', () => {
|
test('or can be chained', () => {
|
||||||
expect(`
|
expect(`
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user