Compare commits
5 Commits
67e0db090b
...
4fc1a965eb
| Author | SHA1 | Date | |
|---|---|---|---|
| 4fc1a965eb | |||
| 6cb4d69088 | |||
| 75a304bf18 | |||
| 7cf7d7de48 | |||
| 120244003c |
|
|
@ -54,7 +54,6 @@ export class Compiler {
|
||||||
fnLabelCount = 0
|
fnLabelCount = 0
|
||||||
ifLabelCount = 0
|
ifLabelCount = 0
|
||||||
tryLabelCount = 0
|
tryLabelCount = 0
|
||||||
loopLabelCount = 0
|
|
||||||
bytecode: Bytecode
|
bytecode: Bytecode
|
||||||
pipeCounter = 0
|
pipeCounter = 0
|
||||||
|
|
||||||
|
|
@ -389,7 +388,9 @@ export class Compiler {
|
||||||
return instructions
|
return instructions
|
||||||
}
|
}
|
||||||
|
|
||||||
case terms.Block: {
|
case terms.ThenBlock:
|
||||||
|
case terms.SingleLineThenBlock:
|
||||||
|
case terms.TryBlock: {
|
||||||
const children = getAllChildren(node)
|
const children = getAllChildren(node)
|
||||||
const instructions: ProgramItem[] = []
|
const instructions: ProgramItem[] = []
|
||||||
|
|
||||||
|
|
@ -673,24 +674,6 @@ export class Compiler {
|
||||||
return instructions
|
return instructions
|
||||||
}
|
}
|
||||||
|
|
||||||
case terms.WhileExpr: {
|
|
||||||
const [_while, test, _colon, block] = getAllChildren(node)
|
|
||||||
const instructions: ProgramItem[] = []
|
|
||||||
|
|
||||||
this.loopLabelCount++
|
|
||||||
const startLoop = `.loop_${this.loopLabelCount}:`
|
|
||||||
const endLoop = `.end_loop_${this.loopLabelCount}:`
|
|
||||||
|
|
||||||
instructions.push([`${startLoop}:`])
|
|
||||||
instructions.push(...this.#compileNode(test!, input))
|
|
||||||
instructions.push(['JUMP_IF_FALSE', endLoop])
|
|
||||||
instructions.push(...this.#compileNode(block!, input))
|
|
||||||
instructions.push(['JUMP', startLoop])
|
|
||||||
instructions.push([`${endLoop}:`])
|
|
||||||
|
|
||||||
return instructions
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new CompilerError(
|
throw new CompilerError(
|
||||||
`Compiler doesn't know how to handle a "${node.type.name}" node.`,
|
`Compiler doesn't know how to handle a "${node.type.name}" node.`,
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ const tagCall = (tagName: string, atNamed = {}, ...args: any[]) => {
|
||||||
const space = attrs.length ? ' ' : ''
|
const space = attrs.length ? ' ' : ''
|
||||||
const children = args
|
const children = args
|
||||||
.reverse()
|
.reverse()
|
||||||
.map(a => a === TAG_TOKEN ? buffer.pop() : a)
|
.map(a => a === null ? buffer.pop() : a)
|
||||||
.reverse().join(' ')
|
.reverse().join(' ')
|
||||||
.replaceAll(` ${NOSPACE_TOKEN} `, '')
|
.replaceAll(` ${NOSPACE_TOKEN} `, '')
|
||||||
|
|
||||||
|
|
@ -50,16 +50,13 @@ const tagCall = (tagName: string, atNamed = {}, ...args: any[]) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const tag = async (tagName: string, atNamed = {}, ...args: any[]) => {
|
const tag = async (tagName: string, atNamed = {}, ...args: any[]) => {
|
||||||
if (typeof args[0] === 'function') {
|
if (typeof args[0] === 'function')
|
||||||
await tagBlock(tagName, atNamed, args[0])
|
await tagBlock(tagName, atNamed, args[0])
|
||||||
} else {
|
else
|
||||||
tagCall(tagName, atNamed, ...args)
|
tagCall(tagName, atNamed, ...args)
|
||||||
return TAG_TOKEN
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const NOSPACE_TOKEN = '!!ribbit-nospace!!'
|
const NOSPACE_TOKEN = '!!ribbit-nospace!!'
|
||||||
const TAG_TOKEN = '!!ribbit-tag!!'
|
|
||||||
const SELF_CLOSING = ["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]
|
const SELF_CLOSING = ["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]
|
||||||
|
|
||||||
describe('ribbit', () => {
|
describe('ribbit', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
import { describe } from 'bun:test'
|
|
||||||
import { expect, test } from 'bun:test'
|
|
||||||
|
|
||||||
describe('while', () => {
|
|
||||||
test('basic variable', () => {
|
|
||||||
expect(`
|
|
||||||
a = true
|
|
||||||
b = ''
|
|
||||||
while a:
|
|
||||||
a = false
|
|
||||||
b = done
|
|
||||||
end
|
|
||||||
b`)
|
|
||||||
.toEvaluateTo('done')
|
|
||||||
})
|
|
||||||
|
|
||||||
test('basic expression', () => {
|
|
||||||
expect(`
|
|
||||||
a = 0
|
|
||||||
while a < 10:
|
|
||||||
a += 1
|
|
||||||
end
|
|
||||||
a`)
|
|
||||||
.toEvaluateTo(10)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('compound expression', () => {
|
|
||||||
expect(`
|
|
||||||
a = 1
|
|
||||||
b = 0
|
|
||||||
while a > 0 and b < 100:
|
|
||||||
b += 1
|
|
||||||
end
|
|
||||||
b`)
|
|
||||||
.toEvaluateTo(100)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('returns value', () => {
|
|
||||||
expect(`
|
|
||||||
a = 0
|
|
||||||
ret = while a < 10:
|
|
||||||
a += 1
|
|
||||||
done
|
|
||||||
end
|
|
||||||
ret`)
|
|
||||||
.toEvaluateTo('done')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
@ -210,7 +210,7 @@ export const getIfExprParts = (node: SyntaxNode, input: string) => {
|
||||||
}
|
}
|
||||||
elseThenBlock = parts.at(-1)
|
elseThenBlock = parts.at(-1)
|
||||||
} else if (child.type.id === terms.ElseIfExpr) {
|
} else if (child.type.id === terms.ElseIfExpr) {
|
||||||
const [_else, _if, conditional, _colon, thenBlock] = parts
|
const [_keyword, conditional, _colon, thenBlock] = parts
|
||||||
if (!conditional || !thenBlock) {
|
if (!conditional || !thenBlock) {
|
||||||
const names = parts.map((p) => p.type.name).join(', ')
|
const names = parts.map((p) => p.type.name).join(', ')
|
||||||
const message = `ElseIfExpr expected conditional and thenBlock, got ${names}`
|
const message = `ElseIfExpr expected conditional and thenBlock, got ${names}`
|
||||||
|
|
@ -309,7 +309,7 @@ export const getDotGetParts = (node: SyntaxNode, input: string) => {
|
||||||
export const getTryExprParts = (node: SyntaxNode, input: string) => {
|
export const getTryExprParts = (node: SyntaxNode, input: string) => {
|
||||||
const children = getAllChildren(node)
|
const children = getAllChildren(node)
|
||||||
|
|
||||||
// First child is always 'try' keyword, second is colon, third is Block
|
// First child is always 'try' keyword, second is colon, third is TryBlock or statement
|
||||||
const [tryKeyword, _colon, tryBlock, ...rest] = children
|
const [tryKeyword, _colon, tryBlock, ...rest] = children
|
||||||
|
|
||||||
if (!tryKeyword || !tryBlock) {
|
if (!tryKeyword || !tryBlock) {
|
||||||
|
|
|
||||||
|
|
@ -25,17 +25,8 @@
|
||||||
Underscore { "_" }
|
Underscore { "_" }
|
||||||
Regex { "//" (![/\\\n[] | "\\" ![\n] | "[" (![\n\\\]] | "\\" ![\n])* "]")+ ("//" $[gimsuy]*)? } // Stolen from the lezer JavaScript grammar
|
Regex { "//" (![/\\\n[] | "\\" ![\n] | "[" (![\n\\\]] | "\\" ![\n])* "]")+ ("//" $[gimsuy]*)? } // Stolen from the lezer JavaScript grammar
|
||||||
"|"[@name=operator]
|
"|"[@name=operator]
|
||||||
}
|
|
||||||
|
|
||||||
end { @specialize[@name=keyword]<Identifier, "end"> }
|
}
|
||||||
while { @specialize[@name=keyword]<Identifier, "while"> }
|
|
||||||
if { @specialize[@name=keyword]<Identifier, "if"> }
|
|
||||||
else { @specialize[@name=keyword]<Identifier, "else"> }
|
|
||||||
try { @specialize[@name=keyword]<Identifier, "try"> }
|
|
||||||
catch { @specialize[@name=keyword]<Identifier, "catch"> }
|
|
||||||
finally { @specialize[@name=keyword]<Identifier, "finally"> }
|
|
||||||
throw { @specialize[@name=keyword]<Identifier, "throw"> }
|
|
||||||
null { @specialize[@name=Null]<Identifier, "null"> }
|
|
||||||
|
|
||||||
@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 }
|
@external specialize {Identifier} specializeKeyword from "./tokenizer" { Do }
|
||||||
|
|
@ -56,9 +47,9 @@ item {
|
||||||
newlineOrSemicolon // allow blank lines
|
newlineOrSemicolon // allow blank lines
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
consumeToTerminator {
|
consumeToTerminator {
|
||||||
PipeExpr |
|
PipeExpr |
|
||||||
WhileExpr |
|
|
||||||
FunctionCallWithBlock |
|
FunctionCallWithBlock |
|
||||||
ambiguousFunctionCall |
|
ambiguousFunctionCall |
|
||||||
TryExpr |
|
TryExpr |
|
||||||
|
|
@ -80,16 +71,16 @@ pipeOperand {
|
||||||
FunctionCall | FunctionCallOrIdentifier
|
FunctionCall | FunctionCallOrIdentifier
|
||||||
}
|
}
|
||||||
|
|
||||||
WhileExpr {
|
|
||||||
while (ConditionalOp | expression) colon Block end
|
|
||||||
}
|
|
||||||
|
|
||||||
Block {
|
|
||||||
consumeToTerminator | newlineOrSemicolon block
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionCallWithBlock {
|
FunctionCallWithBlock {
|
||||||
ambiguousFunctionCall colon Block CatchExpr? FinallyExpr? end
|
singleLineFunctionCallWithBlock | multiLineFunctionCallWithBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
singleLineFunctionCallWithBlock {
|
||||||
|
ambiguousFunctionCall colon consumeToTerminator CatchExpr? FinallyExpr? @specialize[@name=keyword]<Identifier, "end">
|
||||||
|
}
|
||||||
|
|
||||||
|
multiLineFunctionCallWithBlock {
|
||||||
|
ambiguousFunctionCall colon newlineOrSemicolon block CatchExpr? FinallyExpr? @specialize[@name=keyword]<Identifier, "end">
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionCallOrIdentifier {
|
FunctionCallOrIdentifier {
|
||||||
|
|
@ -108,6 +99,7 @@ arg {
|
||||||
PositionalArg | NamedArg
|
PositionalArg | NamedArg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PositionalArg {
|
PositionalArg {
|
||||||
expression | FunctionDef | Underscore
|
expression | FunctionDef | Underscore
|
||||||
}
|
}
|
||||||
|
|
@ -117,35 +109,71 @@ NamedArg {
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionDef {
|
FunctionDef {
|
||||||
Do Params colon (consumeToTerminator | newlineOrSemicolon block) CatchExpr? FinallyExpr? end
|
singleLineFunctionDef | multilineFunctionDef
|
||||||
|
}
|
||||||
|
|
||||||
|
singleLineFunctionDef {
|
||||||
|
Do Params colon consumeToTerminator CatchExpr? FinallyExpr? @specialize[@name=keyword]<Identifier, "end">
|
||||||
|
}
|
||||||
|
|
||||||
|
multilineFunctionDef {
|
||||||
|
Do Params colon newlineOrSemicolon block CatchExpr? FinallyExpr? @specialize[@name=keyword]<Identifier, "end">
|
||||||
}
|
}
|
||||||
|
|
||||||
IfExpr {
|
IfExpr {
|
||||||
if (ConditionalOp | expression) colon Block ElseIfExpr* ElseExpr? end
|
singleLineIf | multilineIf
|
||||||
|
}
|
||||||
|
|
||||||
|
singleLineIf {
|
||||||
|
@specialize[@name=keyword]<Identifier, "if"> (ConditionalOp | expression) colon SingleLineThenBlock @specialize[@name=keyword]<Identifier, "end">
|
||||||
|
}
|
||||||
|
|
||||||
|
multilineIf {
|
||||||
|
@specialize[@name=keyword]<Identifier, "if"> (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock ElseIfExpr* ElseExpr? @specialize[@name=keyword]<Identifier, "end">
|
||||||
}
|
}
|
||||||
|
|
||||||
ElseIfExpr {
|
ElseIfExpr {
|
||||||
else if (ConditionalOp | expression) colon Block
|
@specialize[@name=keyword]<Identifier, "elseif"> (ConditionalOp | expression) colon newlineOrSemicolon ThenBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
ElseExpr {
|
ElseExpr {
|
||||||
else colon Block
|
@specialize[@name=keyword]<Identifier, "else"> colon newlineOrSemicolon ThenBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
ThenBlock {
|
||||||
|
block
|
||||||
|
}
|
||||||
|
|
||||||
|
SingleLineThenBlock {
|
||||||
|
consumeToTerminator
|
||||||
}
|
}
|
||||||
|
|
||||||
TryExpr {
|
TryExpr {
|
||||||
try colon Block CatchExpr? FinallyExpr? end
|
singleLineTry | multilineTry
|
||||||
|
}
|
||||||
|
|
||||||
|
singleLineTry {
|
||||||
|
@specialize[@name=keyword]<Identifier, "try"> colon consumeToTerminator CatchExpr? FinallyExpr? @specialize[@name=keyword]<Identifier, "end">
|
||||||
|
}
|
||||||
|
|
||||||
|
multilineTry {
|
||||||
|
@specialize[@name=keyword]<Identifier, "try"> colon newlineOrSemicolon TryBlock CatchExpr? FinallyExpr? @specialize[@name=keyword]<Identifier, "end">
|
||||||
}
|
}
|
||||||
|
|
||||||
CatchExpr {
|
CatchExpr {
|
||||||
catch Identifier colon Block
|
@specialize[@name=keyword]<Identifier, "catch"> Identifier colon (newlineOrSemicolon TryBlock | consumeToTerminator)
|
||||||
}
|
}
|
||||||
|
|
||||||
FinallyExpr {
|
FinallyExpr {
|
||||||
finally colon Block
|
@specialize[@name=keyword]<Identifier, "finally"> colon (newlineOrSemicolon TryBlock | consumeToTerminator)
|
||||||
|
}
|
||||||
|
|
||||||
|
TryBlock {
|
||||||
|
block
|
||||||
}
|
}
|
||||||
|
|
||||||
Throw {
|
Throw {
|
||||||
throw (BinOp | ConditionalOp | expression)
|
@specialize[@name=keyword]<Identifier, "throw"> (BinOp | ConditionalOp | expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
ConditionalOp {
|
ConditionalOp {
|
||||||
|
|
@ -164,7 +192,7 @@ Params {
|
||||||
}
|
}
|
||||||
|
|
||||||
NamedParam {
|
NamedParam {
|
||||||
NamedArgPrefix (String | Number | Boolean | null)
|
NamedArgPrefix (String | Number | Boolean | @specialize[@name=Null]<Identifier, "null">)
|
||||||
}
|
}
|
||||||
|
|
||||||
Assign {
|
Assign {
|
||||||
|
|
@ -202,6 +230,7 @@ expression {
|
||||||
}
|
}
|
||||||
|
|
||||||
String { "'" stringContent* "'" }
|
String { "'" stringContent* "'" }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stringContent {
|
stringContent {
|
||||||
|
|
@ -237,7 +266,7 @@ Array {
|
||||||
// to go through ambiguousFunctionCall (which is what we want semantically).
|
// to go through ambiguousFunctionCall (which is what we want semantically).
|
||||||
// Yes, it is annoying and I gave up trying to use GLR to fix it.
|
// Yes, it is annoying and I gave up trying to use GLR to fix it.
|
||||||
expressionWithoutIdentifier {
|
expressionWithoutIdentifier {
|
||||||
ParenExpr | Word | String | Number | Boolean | Regex | Dict | Array | null
|
ParenExpr | Word | String | Number | Boolean | Regex | Dict | Array | @specialize[@name=Null]<Identifier, "null">
|
||||||
}
|
}
|
||||||
|
|
||||||
block {
|
block {
|
||||||
|
|
|
||||||
|
|
@ -47,19 +47,20 @@ export const
|
||||||
Null = 45,
|
Null = 45,
|
||||||
colon = 46,
|
colon = 46,
|
||||||
CatchExpr = 47,
|
CatchExpr = 47,
|
||||||
keyword = 68,
|
keyword = 70,
|
||||||
Block = 49,
|
TryBlock = 49,
|
||||||
FinallyExpr = 50,
|
FinallyExpr = 50,
|
||||||
Underscore = 53,
|
Underscore = 53,
|
||||||
Array = 54,
|
Array = 54,
|
||||||
ConditionalOp = 55,
|
ConditionalOp = 55,
|
||||||
PositionalArg = 56,
|
PositionalArg = 56,
|
||||||
WhileExpr = 58,
|
FunctionCallWithBlock = 58,
|
||||||
FunctionCallWithBlock = 60,
|
TryExpr = 59,
|
||||||
TryExpr = 61,
|
Throw = 61,
|
||||||
Throw = 63,
|
IfExpr = 63,
|
||||||
IfExpr = 65,
|
SingleLineThenBlock = 65,
|
||||||
|
ThenBlock = 66,
|
||||||
ElseIfExpr = 67,
|
ElseIfExpr = 67,
|
||||||
ElseExpr = 69,
|
ElseExpr = 69,
|
||||||
CompoundAssign = 70,
|
CompoundAssign = 71,
|
||||||
Assign = 71
|
Assign = 72
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@ import {operatorTokenizer} from "./operatorTokenizer"
|
||||||
import {tokenizer, specializeKeyword} 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,null:90, catch:96, finally:102, end:104, while:118, try:124, throw:128, if:132, else:136}
|
const spec_Identifier = {__proto__:null,null:90, catch:96, finally:102, end:104, try:120, throw:124, if:128, elseif:136, else:140}
|
||||||
export const parser = LRParser.deserialize({
|
export const parser = LRParser.deserialize({
|
||||||
version: 14,
|
version: 14,
|
||||||
states: "9OQYQbOOO#zQcO'#C{O$zOSO'#C}OOQa'#DT'#DTO&TQbO'#DdO'iQcO'#E]OOQa'#E]'#E]O(lQcO'#E]O)nQcO'#E[O*UQRO'#C|O+eQcO'#EWO+uQcO'#EWO,PQbO'#CzO,wOpO'#CxOOQ`'#EX'#EXO,|QbO'#EWO-WQRO'#DtOOQ`'#EW'#EWO-lQQO'#EVOOQ`'#EV'#EVOOQ`'#Dv'#DvQYQbOOO-tQbO'#DWO.PQbO'#DhO.tQQO'#DkO.PQbO'#DmO.PQbO'#DoO.yQbO'#DUOOQa'#E['#E[OOQ`'#Df'#DfOOQ`'#Ek'#EkOOQ`'#EO'#EOO/TQbO,59cO/}QbO'#DPO0VQWO'#DQOOOO'#E_'#E_OOOO'#Dw'#DwO0kOSO,59iOOQa,59i,59iOOQ`'#Dx'#DxO0yQbO,5:OO1QQQO,59oOOQa,5:O,5:OO1]QbO,5:OO1gQbO,5:aO.PQbO,59hO.PQbO,59hO.PQbO,59hO.PQbO,5:PO.PQbO,5:PO.PQbO,5:PO1zQRO,59fO2RQRO,59fO2dQRO,59fO2_QQO,59fO2oQQO,59fO2wObO,59dO3SQbO'#EPO3_QbO,59bO3yQbO,5:UO1gQbO,5:`OOQ`,5:q,5:qOOQ`-E7t-E7tOOQ`'#Dy'#DyO4aQbO'#DXO4lQbO'#DYOOQO'#Dz'#DzO4dQQO'#DXO4zQQO,59rO5kQRO,5:SO5rQRO,5:SO3yQbO,5:VO5}QcO,5:XO6yQcO,5:XO7ZQcO,5:XO7eQRO,5:ZO7lQRO,5:ZOOQ`,59p,59pOOQ`-E7|-E7|OOOO,59k,59kOOOO,59l,59lOOOO-E7u-E7uOOQa1G/T1G/TOOQ`-E7v-E7vO7wQQO1G/ZOOQa1G/j1G/jO8SQbO1G/jOOQO'#D|'#D|O7wQQO1G/ZOOQa1G/Z1G/ZOOQ`'#D}'#D}O8SQbO1G/jOOQ`1G/{1G/{OOQa1G/S1G/SO9OQcO1G/SO9YQcO1G/SO9dQcO1G/SOOQa1G/k1G/kO;YQcO1G/kO;aQcO1G/kO;hQcO1G/kOOQa1G/Q1G/QOOQa1G/O1G/OO!dQbO'#C{O;oQbO'#CwOOQ`,5:k,5:kOOQ`-E7}-E7}OOQ`'#D_'#D_O;|QbO'#D_O<pQbO1G/pOOQ`1G/z1G/zOOQ`-E7w-E7wO<{QQO,59sOOQO,59t,59tOOQO-E7x-E7xO=TQbO1G/^O3yQbO1G/nO=kQbO1G/qO3yQbO1G/uO=vQQO7+$uOOQa7+$u7+$uO>RQbO7+%UOOQa7+%U7+%UOOQO-E7z-E7zOOQ`-E7{-E7{OOQ`'#D{'#D{O>]QQO'#D{O>bQbO'#EhOOQ`,59y,59yO?UQbO'#D]O?ZQQO'#D`OOQ`7+%[7+%[O?`QbO7+%[O?eQbO7+%[O?mQbO7+$xO?xQbO7+$xO@iQbO7+%YOOQ`7+%]7+%]O@nQbO7+%]O@sQbO7+%]O@{QbO7+%aOOQa<<Ha<<HaOOQa<<Hp<<HpOOQ`,5:g,5:gOOQ`-E7y-E7yOATQQO,59wO3yQbO,59zOOQ`<<Hv<<HvOAYQbO<<HvOOQ`<<Hd<<HdOA_QbO<<HdOAdQbO<<HdOAlQbO<<HdOOQ`<<Ht<<HtOOQ`<<Hw<<HwOAwQbO<<HwOOQ`'#EQ'#EQOA|QbO<<H{OBUQbO'#DsOOQ`<<H{<<H{OB^QbO<<H{O3yQbO1G/cOOQ`1G/f1G/fOOQ`AN>bAN>bOOQ`AN>OAN>OOBcQbOAN>OOBhQbOAN>OOOQ`AN>cAN>cOOQ`-E8O-E8OOOQ`AN>gAN>gOBpQbOAN>gO.PQbO,5:]O3yQbO,5:_OOQ`7+$}7+$}OOQ`G23jG23jOBuQbOG23jPBXQbO'#DqOOQ`G24RG24ROBzQRO1G/wOCRQRO1G/wOOQ`1G/y1G/yOOQ`LD)ULD)UO3yQbO7+%cOOQ`<<H}<<H}",
|
states: "<[QYQbOOO#tQcO'#C{O$tOSO'#C}O%SQbO'#EiOOQ`'#DW'#DWOOQa'#DT'#DTO&YQbO'#DdO'kQcO'#E^OOQa'#E^'#E^O(nQcO'#E^O)pQcO'#E]O*TQRO'#C|O+aQcO'#EXO+qQcO'#EXO+{QbO'#CzO,sOpO'#CxOOQ`'#EY'#EYO,xQbO'#EXOOQ`'#Dh'#DhO-SQQO'#EqOOQ`'#Di'#DiO-XQbO'#DkO-XQbO'#EsOOQ`'#Dm'#DmO-|QRO'#DuOOQ`'#EX'#EXO.bQQO'#EWOOQ`'#EW'#EWOOQ`'#Dw'#DwQYQbOOO.jQbO'#DUOOQa'#E]'#E]OOQ`'#Df'#DfOOQ`'#En'#EnOOQ`'#EP'#EPO.tQbO,59cO/kQbO'#DPO/sQWO'#DQOOOO'#E`'#E`OOOO'#Dx'#DxO0XOSO,59iOOQa,59i,59iOOQ`'#Dz'#DzO0gQbO'#DXO0rQbO'#DYOOQO'#D{'#D{O0jQQO'#DXO1QQQO,5;TOOQ`'#Dy'#DyO1VQbO,5:OO1^QQO,59oOOQa,5:O,5:OO1iQbO,5:OO1sQbO,5:bO-XQbO,59hO-XQbO,59hO-XQbO,59hO-XQbO,5:PO-XQbO,5:PO-XQbO,5:PO2TQRO,59fO2[QRO,59fO2mQRO,59fO2hQQO,59fO2xQQO,59fO3QObO,59dO3]QbO'#EQO3hQbO,59bO4PQbO,5;ZO4dQbO,5;]O4wQcO,5:VO5mQcO,5:VO5}QcO,5:VO6sQRO,5;_O6zQRO,5;_O1sQbO,5:aOOQ`,5:r,5:rOOQ`-E7u-E7uOOQ`,59p,59pOOQ`-E7}-E7}OOOO,59k,59kOOOO,59l,59lOOOO-E7v-E7vOOQa1G/T1G/TOOQ`-E7x-E7xO7VQQO,59sOOQO,59t,59tOOQO-E7y-E7yO7_QbO1G0oOOQ`-E7w-E7wO7rQQO1G/ZOOQa1G/j1G/jO7}QbO1G/jOOQO'#D}'#D}O7rQQO1G/ZOOQa1G/Z1G/ZOOQ`'#EO'#EOO7}QbO1G/jOOQ`1G/|1G/|OOQa1G/S1G/SO8vQcO1G/SO9QQcO1G/SO9[QcO1G/SOOQa1G/k1G/kO:zQcO1G/kO;RQcO1G/kO;YQcO1G/kOOQa1G/Q1G/QOOQa1G/O1G/OO!aQbO'#C{O;aQbO'#CwOOQ`,5:l,5:lOOQ`-E8O-E8OO;nQbO1G0uO;yQbO1G0vO<gQbO1G0wO;yQbO1G0xO<rQbO1G0yOOQ`1G/{1G/{O=VQbO7+&ZO;yQbO7+&]O=bQQO7+$uOOQa7+$u7+$uO=mQbO7+%UOOQa7+%U7+%UOOQO-E7{-E7{OOQ`-E7|-E7|O=wQbO'#D]O=|QQO'#D`OOQ`7+&a7+&aO>RQbO7+&aO>WQbO7+&aOOQ`'#D|'#D|O>`QQO'#D|O>eQbO'#EjO?XQbO7+&bOOQ`7+&c7+&cO?dQbO7+&cO?iQbO7+&cOOQ`'#D_'#D_O?qQbO7+&dOOQ`'#Do'#DoO?|QbO7+&eO@RQbO7+&fOOQ`<<Iu<<IuO@oQbO<<IuO@tQbO<<IuO@|QbO<<IwOOQa<<Ha<<HaOOQa<<Hp<<HpOAXQQO,59wOA^QbO,59zOOQ`<<I{<<I{OAqQbO<<I{OOQ`,5:h,5:hOOQ`-E7z-E7zOOQ`<<I|<<I|OAvQbO<<I|OA{QbO<<I|OOQ`<<I}<<I}OBTQbO<<I}OOQ`<<JO<<JOOBYQbO<<JOOB_QbO<<JOOOQ`<<JP<<JPOOQ`'#Dp'#DpOBgQbO<<JQOOQ`AN?aAN?aOBrQbOAN?aOOQ`AN?cAN?cOBwQbOAN?cOB|QbOAN?cOCUQbO1G/cOCiQbO1G/fOOQ`1G/f1G/fOOQ`AN?gAN?gOOQ`AN?hAN?hODPQbOAN?hOOQ`AN?iAN?iOOQ`AN?jAN?jODUQbOAN?jO-XQbO'#DqOOQ`'#ER'#ERODZQbOAN?lODfQQO'#DsOOQ`AN?lAN?lODkQbOAN?lOOQ`G24{G24{OOQ`G24}G24}ODpQbOG24}ODuQbO7+$}OOQ`7+$}7+$}OOQ`7+%Q7+%QOOQ`G25SG25SOOQ`G25UG25UOE`QRO,5:]OEgQRO,5:]OOQ`-E8P-E8POOQ`G25WG25WOErQbOG25WOEwQQO,5:_OOQ`LD*iLD*iOOQ`<<Hi<<HiOE|QQO1G/wOOQ`LD*rLD*rOCiQbO1G/yO@RQbO7+%cOOQ`7+%e7+%eOOQ`<<H}<<H}",
|
||||||
stateData: "Ca~O!wOS!xOS~OdPOe`OfUOg]OhfOmUOuUOvUO}UO!]gO!`hO!biO!djO!}[O#QQO#XRO#YSO#ZcO~OdlOfUOg]OhfOmUOuUOvUOykO}UO!VmO!}[O#QQO#XRO#YSO!ZoX#ZoX#`oX#^oX!QoX!ToX!UoX!foX~OP#OXQ#OXR#OXS#OXT#OXU#OXW#OXX#OXY#OXZ#OX[#OX]#OX^#OX!OoX~P!dOrsO#QvO#SqO#TrO~OdlOfUOg]OmUOuUOvUOykO}UO!}[O#QQO#XRO#YSO#ZwO~O#]zO~P%YOP#PXQ#PXR#PXS#PXT#PXU#PXW#PXX#PXY#PXZ#PX[#PX]#PX^#PX#Z#PX#`#PX!Q#PX!T#PX!U#PX!f#PX~OdlOfUOg]OhfOmUOuUOvUOykO}UO!VmO!}[O#QQO#XRO#YSO#^#PX~P&[OV|O~P&[OP#OXQ#OXR#OXS#OXT#OXU#OXW#OXX#OXY#OXZ#OX[#OX]#OX^#OX~O#Z!zX#`!zX!Q!zX!T!zX!U!zX!f!zX~P(sOP!OOQ!OOR!POS!POT!ROU!SOW!QOX!QOY!QOZ!QO[!QO]!QO^}O~O#Z!zX#`!zX!Q!zX!T!zX!U!zX!f!zX~OP!OOQ!OOR!POS!PO~P+POT!ROU!SO~P+POdPOfUOg]OhfOmUOuUOvUO}UO!}[O#QQO#XRO#YSO~O!|!YO~O!O!]O!Z!ZO~P+POV|O_!^O`!^Oa!^Ob!^Oc!^O~O#Z!_O#`!_O~Od!aOy!cO!O{P~OdlOfUOg]OmUOuUOvUO}UO!}[O#QQO#XRO#YSO~O!O!iO~OhfO!V!oO~P.POhfOykO!VmO!Oka!Zka#Zka#`ka#^ka!Qka!Tka!Uka!fka~P.POd!qO!}[O~O#Q!rO#S!rO#T!rO#U!rO#V!rO#W!rO~OrsO#Q!tO#SqO#TrO~O#]!wO~P%YOykO#Z!yO#]!{O~O#Z!|O#]!wO~P.POe`O!]gO!`hO!biO!djO~P,PO#^#XO~P(sOP!OOQ!OOR!POS!PO#^#XO~OT!ROU!SO#^#XO~O!Z!ZO#^#XO~Od#YOm#YO!}[O~Od#ZOg]O!}[O~O!Z!ZO#Zja#`ja#^ja!Qja!Tja!Uja!fja~Oe`O!]gO!`hO!biO!djO#Z#`O~P,POd!aOy!cO!O{X~Om#eOu#eO}#eO#QQO~O!O#gO~OT!ROU!SOW!QOX!QOY!QOZ!QO[!QO]!QO~O!O#hO~P5POT!ROU!SO!O#hO~O#Z!aa#`!aa!Q!aa!T!aa!U!aa!f!aa~P*UO#Z!aa#`!aa!Q!aa!T!aa!U!aa!f!aa~OP!OOQ!OOR!POS!PO~P6eOT!ROU!SO~P6eO!O#jO~P5POT!ROU!SO!O#jO~OykO#Z!yO#]#lO~O#Z!|O#]#nO~P.PO^}ORpiSpi#Zpi#`pi#^pi!Qpi!Tpi!Upi!fpi~OPpiQpi~P8^OP!OOQ!OO~P8^OP!OOQ!OORpiSpi#Zpi#`pi#^pi!Qpi!Tpi!Upi!fpi~OW!QOX!QOY!QOZ!QO[!QO]!QOT!Xi#Z!Xi#`!Xi#^!Xi!O!Xi!Q!Xi!T!Xi!U!Xi!f!Xi~OU!SO~P:XOU!SO~P:kOU!Xi~P:XOhfOykO!VmO~P.POe`O!]gO!`hO!biO!djO#Z#qO!Q#[P!T#[P!U#[P!f#[P~P,PO!Q#uO!T#vO!U#wO~Oy!cO!O{a~Oe`O!]gO!`hO!biO!djO#Z#{O~P,PO!Q#uO!T#vO!U#}O~OykO#Z!yO#]$RO~O#Z!|O#]$SO~P.PO#Z$TO~Oe`O!]gO!`hO!biO!djO#Z#qO!Q#[X!T#[X!U#[X!f#[X~P,POd$VO~O!O$WO~O!U$XO~O!T#vO!U$XO~O!Q#uO!T#vO!U$ZO~Oe`O!]gO!`hO!biO!djO#Z#qO!Q#[P!T#[P!U#[P~P,PO!U$_O~O!U$`O~O!T#vO!U$`O~O!U$eO!f$dO~O!O$gO~O!U$iO~O!U$jO~O!T#vO!U$jO~O!Q#uO!T#vO!U$jO~O!U$mO~O!U$oO!f$dO~O!O$rO!d$qO~O!U$oO~O!U$tO~O!T#vO!U$tO~O!U$wO~O!U${O~O!O$|O~P5POT!ROU!SO!O$|O~Omv~",
|
stateData: "FU~O!xOS!yOS~OdPOehOfWOg_OhROmWOuWOvWO}WO!^cO!`eO!bfO#O^O#RQO#YTO#ZUO#[kO~OdoOfWOg_OhROmWOuWOvWOynO}WO!VpO#O^O#RQO#YTO#ZUO!ZoX#[oX#ioX#aoX!QoX!ToX!UoX~OP#PXQ#PXR#PXS#PXT#PXU#PXW#PXX#PXY#PXZ#PX[#PX]#PX^#PX!OoX~P!aOrvO#RyO#TtO#UuO~OdzOy|O!O{P~OdoOfWOg_OmWOuWOvWOynO}WO#O^O#RQO#YTO#ZUO#[!QO~O#`!TO~P%_OP#QXQ#QXR#QXS#QXT#QXU#QXW#QXX#QXY#QXZ#QX[#QX]#QX^#QX#[#QX#i#QX!Q#QX!T#QX!U#QX~OdoOfWOg_OhROmWOuWOvWOynO}WO!VpO#O^O#RQO#YTO#ZUO#a#QX~P&aOV!VO~P&aOP#PXQ#PXR#PXS#PXT#PXU#PXW#PXX#PXY#PXZ#PX[#PX]#PX^#PX~O#[!{X#i!{X!Q!{X!T!{X!U!{X~P(uOP!XOQ!XOR!YOS!YOT![OU!]OW!ZOX!ZOY!ZOZ!ZO[!ZO]!ZO^!WO~O#[!{X#i!{X!Q!{X!T!{X!U!{X~OP!XOQ!XOR!YOS!YO~P+OOT![OU!]O~P+OOdPOfWOg_OhROmWOuWOvWO}WO#O^O#RQO#YTO#ZUO~O!}!cO~O!O!fO!Z!dO~P+OO!O!gO~OdoOfWOg_OmWOuWOvWO}WO#O^O#RQO#YTO#ZUO~OV!VO_!mO`!mOa!mOb!mOc!mO~O#[!nO#i!nO~OhRO!V!pO~P-XOhROynO!VpO!Oka!Zka#[ka#ika#aka!Qka!Tka!Uka~P-XOd!rO#O^O~O#R!sO#T!sO#U!sO#V!sO#W!sO#X!sO~OrvO#R!uO#TtO#UuO~OdzOy|O!O{X~Om!xOu!xO}!xO#RQO~O!O!zO~O#`!}O~P%_OynO#[#PO#`#RO~O#[#SO#`!}O~P-XOehO!^cO!`eO!bfO~P+{O#a#_O~P(uOP!XOQ!XOR!YOS!YO#a#_O~OT![OU!]O#a#_O~O!Z!dO#a#_O~Od#`Om#`O#O^O~Od#aOg_O#O^O~O!Z!dO#[ja#ija#aja!Qja!Tja!Uja~OehO!^cO!`eO!bfO#[#fO~P+{OehO!^cO!`eO!bfO#[#hO~P+{O#[!_a#i!_a!Q!_a!T!_a!U!_a~P*TO#[!_a#i!_a!Q!_a!T!_a!U!_a~OP!XOQ!XOR!YOS!YO~P5[OT![OU!]O~P5[OT![OU!]OW!ZOX!ZOY!ZOZ!ZO[!ZO]!ZO~O!O#iO~P6XOT![OU!]O!O#iO~Oy|O!O{a~OehO!^cO!`eO!bfO#[#lO~P+{OynO#[#PO#`#nO~O#[#SO#`#pO~P-XO^!WORpiSpi#[pi#ipi#api!Qpi!Tpi!Upi~OPpiQpi~P8XOP!XOQ!XO~P8XOP!XOQ!XORpiSpi#[pi#ipi#api!Qpi!Tpi!Upi~OW!ZOX!ZOY!ZOZ!ZO[!ZO]!ZOT!Xi#[!Xi#i!Xi#a!Xi!O!Xi!Q!Xi!T!Xi!U!Xi~OU!]O~P9|OU!]O~P:`OU!Xi~P9|OhROynO!VpO~P-XO!Q#sO!T#tO!U#uO~OehO!^cO!`eO!bfO#[#xO!Q#^P!T#^P!U#^P~P+{O!Q#sO!T#tO!U#|O~OehO!^cO!`eO!bfO#[$TO~P+{O!Q#sO!T#tO!U$UO~OynO#[#PO#`$YO~O#[#SO#`$ZO~P-XOd$[O~O!O$]O~O!U$^O~O!T#tO!U$^O~O#[$`O~OehO!^cO!`eO!bfO#[#xO!Q#^X!T#^X!U#^X!f#^X!h#^X~P+{O!Q#sO!T#tO!U$bO~O!U$eO~O!T#tO!U$eO~O!Q#sO!T#tO!U$gO~O!U$jO~OehO!^cO!`eO!bfO#[#xO!U#^P!f#^P!h#^P~P+{O!U$mO~O!T#tO!U$mO~O!Q#sO!T#tO!U$oO~O!O$rO~OehO!^cO!`eO!bfO#[$sO~P+{O!U$uO~O!U$vO~O!T#tO!U$vO~O!U$xO~O!U$yO~O!T#tO!U$yO~O!U%PO!f${O!h%OO~O!U%RO~O!U%SO~O!T#tO!U%SO~OehO!^cO!`eO!bfO#[%UO~P+{OehO!^cO!`eO!bfO#[#xO!U#^P~P+{O!U%XO~O!U%YO~O!U%^O!f${O!h%OO~O!O%`O~O!U%^O~O!U%aO~OehO!^cO!`eO!bfO#[#xO!T#^P!U#^P~P+{O!O%cO~P6XOT![OU!]O!O%cO~O!U%dO~O#[%eO~O#[%fO~Omv~",
|
||||||
goto: "3}#`PPPPPPPPPPPPPPPPPPPPPPPPPP#a#v$[P%[#v&b'QP(O(OPP(S(}P)b*R*UPP*[P*h+QPPP+h,e-^P-eP-e-eP-eP-eP-wP-{-e-e.R.X._.e.k.u.|/W/b/k/rPPPP/x/|0jPP1S2mP3lPPPPPPPP3pPP3vpaOe|!]!^!i#`#g#h#j#s#{$W$g$r$|R!W[u^O[e|!Z!]!^!i#`#g#h#j#s#{$W$g$r$|rPO[e|!]!^!i#`#g#h#j#s#{$W$g$r$||lPSTgijkpx{}!O!P!Q!R!S!x!}#Z#[#m$qR#Z!ZrTO[e|!]!^!i#`#g#h#j#s#{$W$g$r$||UPSTgijkpx{}!O!P!Q!R!S!x!}#Z#[#m$qQ!qqQ#Y!YR#[!ZpYOe|!]!^!i#`#g#h#j#s#{$W$g$r$|Q!U[Q!kiQ#P!OR#S!P!pUOPST[egijkpx{|}!O!P!Q!R!S!]!^!i!x!}#Z#[#`#g#h#j#m#s#{$W$g$q$r$|R#e!cTsQu!qUOPST[egijkpx{|}!O!P!Q!R!S!]!^!i!x!}#Z#[#`#g#h#j#m#s#{$W$g$q$r$|YnPTp#Z#[QySQ!vxX!yy!v!z#kpaOe|!]!^!i#`#g#h#j#s#{$W$g$r$|YmPTp#Z#[Q!W[R!okR!ffX!df!b!e#dQ#y#aQ$P#iQ$]#zR$l$^Q#a!]Q#i!iQ#|#hQ$Q#jQ$h$WQ$s$gQ$z$rR$}$|Q#x#aQ$O#iQ$Y#yQ$[#zQ$a$PS$k$]$^R$u$l!OUPST[gijkpx{}!O!P!Q!R!S!x!}#Z#[#m$qqVOe|!]!^!i#`#g#h#j#s#{$W$g$r$|pZOe|!]!^!i#`#g#h#j#s#{$W$g$r$|Q!V[Q!hgQ!liQ!njQ#T!SQ#V!RR$y$qZnPTp#Z#[qaOe|!]!^!i#`#g#h#j#s#{$W$g$r$|T$b$Q$cQ$f$QR$p$cQeOR!`eQuQR!suQxSR!uxQ!bfR#c!bQ!efQ#d!bT#f!e#dS#s#`#{R$U#sQ!zyQ#k!vT#o!z#kQ!}{Q#m!xT#p!}#mWpPT#Z#[R!ppS![_!XR#^![Q$c$QR$n$cTdOeSbOeQ#O|`#_!]!i#h#j$W$g$r$|Q#b!^U#r#`#s#{R#z#gp_Oe|!]!^!i#`#g#h#j#s#{$W$g$r$|Q!X[R#]!ZrXO[e|!]!^!i#`#g#h#j#s#{$W$g$r$|YmPTp#Z#[Q{SQ!ggQ!jiQ!mjQ!okQ!xxW!|{!x!}#mQ#P}Q#Q!OQ#R!PQ#T!QQ#U!RQ#W!SR$x$qpWOe|!]!^!i#`#g#h#j#s#{$W$g$r$||lPSTgijkpx{}!O!P!Q!R!S!x!}#Z#[#m$qR!T[TtQuQ#t#`R$^#{ZoPTp#Z#[",
|
goto: "7s#iPPPPPPPPPPPPPPPPPPPPPPPPPP#j$S$kP%m$S&u'hP(h(hPP(l)iP)|*p*sPP*yP+]+fPPP,[-Z.SP.Z.ZP.ZP.ZP.p.s.|P/QP.Z.Z/W/^/d/j/p/z0X0c0m0v0}PPPP1T1X2QPP2m4WP5XPPPPPPPP5]5y5]PP6Z6b6b6w6w7^7^viOm!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fR!a^{`O^m!V!d!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fxPO^m!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fzoPUVefns!R!U!W!X!Y!Z![!]#O#T#a#b#o${R#a!dxVO^m!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fzWPUVefns!R!U!W!X!Y!Z![!]#O#T#a#b#o${Q!rtQ#`!cR#b!dv[Om!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fQ!_^Q!ieQ#V!XR#Y!Y!tWOPUV^efmns!R!U!V!W!X!Y!Z![!]!f!g!m!z#O#T#a#b#f#h#i#l#o#z$T$]$r$s${%U%e%fR!x|TvQx!uWOPUV^efmns!R!U!V!W!X!Y!Z![!]!f!g!m!z#O#T#a#b#f#h#i#l#o#z$T$]$r$s${%U%e%fYqPVs#a#bQ!SUQ!|!RX#P!S!|#Q#mviOm!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fYpPVs#a#bQ!a^R!pnR!PRX}R{!O!wQ#w#eQ$O#gQ$W#kQ$d#{Q$i$QR$q$XQ$Q#hQ%W$sR%b%UQ#v#eQ#}#gQ$V#kQ$_#wQ$c#{Q$f$OQ$h$QQ$n$WQ$p$XQ$w$dQ$z$iR%T$q|WPUV^efns!R!U!W!X!Y!Z![!]#O#T#a#b#o${wXOm!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fv]Om!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fQ!`^Q!jeQ!lfQ#Z!]Q#]![R%[${ZqPVs#a#bwiOm!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fR$S#iQ$l$TQ%g%eR%h%fT$|$l$}Q%Q$lR%_$}QmOR!omQxQR!txQ!RUR!{!RQ{RR!v{Q!ORQ!w{T!y!O!w`#z#f#h#l$T$s%U%e%fR$a#zQ#Q!SQ#m!|T#q#Q#mQ#T!UQ#o#OT#r#T#oWsPV#a#bR!qsS!ea!bR#d!eQ$}$lR%]$}TlOmSjOmQ#U!VQ#e!fQ#g!gQ#j!mQ#k!zb#y#f#h#l#z$T$s%U%e%fQ$R#iQ$t$]R%V$rvaOm!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fQ!b^R#c!dxZO^m!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fYpPVs#a#bQ!UUQ!heQ!kfQ!pnQ#O!RW#S!U#O#T#oQ#V!WQ#W!XQ#X!YQ#Z!ZQ#[![Q#^!]R%Z${vYOm!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fzoPUVefns!R!U!W!X!Y!Z![!]#O#T#a#b#o${R!^^TwQx!VSOPV^mns!V!f!g!m!z#a#b#f#h#i#l#z$T$]$r$s%U%e%fQ#{#fU$P#h$s%UQ$X#lV$k$T%e%fZrPVs#a#bwbOm!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fwdOm!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%fwgOm!V!f!g!m!z#f#h#i#l#z$T$]$r$s%U%e%f",
|
||||||
nodeNames: "⚠ Star Slash Plus Minus And Or Eq EqEq Neq Lt Lte Gt Gte Modulo PlusEq MinusEq StarEq SlashEq ModuloEq Identifier AssignableIdentifier Word IdentifierBeforeDot Do Program PipeExpr FunctionCall DotGet Number ParenExpr FunctionCallOrIdentifier BinOp String StringFragment Interpolation EscapeSeq Boolean Regex Dict NamedArg NamedArgPrefix FunctionDef Params NamedParam Null colon CatchExpr keyword Block FinallyExpr keyword keyword Underscore Array ConditionalOp PositionalArg operator WhileExpr keyword FunctionCallWithBlock TryExpr keyword Throw keyword IfExpr keyword ElseIfExpr keyword ElseExpr CompoundAssign Assign",
|
nodeNames: "⚠ Star Slash Plus Minus And Or Eq EqEq Neq Lt Lte Gt Gte Modulo PlusEq MinusEq StarEq SlashEq ModuloEq Identifier AssignableIdentifier Word IdentifierBeforeDot Do Program PipeExpr FunctionCall DotGet Number ParenExpr FunctionCallOrIdentifier BinOp String StringFragment Interpolation EscapeSeq Boolean Regex Dict NamedArg NamedArgPrefix FunctionDef Params NamedParam Null colon CatchExpr keyword TryBlock FinallyExpr keyword keyword Underscore Array ConditionalOp PositionalArg operator FunctionCallWithBlock TryExpr keyword Throw keyword IfExpr keyword SingleLineThenBlock ThenBlock ElseIfExpr keyword ElseExpr keyword CompoundAssign Assign",
|
||||||
maxTerm: 108,
|
maxTerm: 117,
|
||||||
context: trackScope,
|
context: trackScope,
|
||||||
nodeProps: [
|
nodeProps: [
|
||||||
["closedBy", 46,"end"]
|
["closedBy", 46,"end"]
|
||||||
|
|
@ -19,9 +19,9 @@ export const parser = LRParser.deserialize({
|
||||||
propSources: [highlighting],
|
propSources: [highlighting],
|
||||||
skippedNodes: [0],
|
skippedNodes: [0],
|
||||||
repeatNodeCount: 11,
|
repeatNodeCount: 11,
|
||||||
tokenData: "C_~R|OX#{XY$jYZ%TZp#{pq$jqs#{st%ntu'Vuw#{wx'[xy'ayz'zz{#{{|(e|}#{}!O+X!O!P#{!P!Q-n!Q![)S![!]6Z!]!^%T!^!}#{!}#O6t#O#P8j#P#Q8o#Q#R#{#R#S9Y#S#T#{#T#Y,Y#Y#Z9s#Z#b,Y#b#c>q#c#f,Y#f#g?n#g#h,Y#h#i@k#i#o,Y#o#p#{#p#qBo#q;'S#{;'S;=`$d<%l~#{~O#{~~CYS$QUrSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{S$gP;=`<%l#{^$qUrS!wYOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U%[UrS#ZQOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{^%uZrS!xYOY%nYZ#{Zt%ntu&huw%nwx&hx#O%n#O#P&h#P;'S%n;'S;=`'P<%lO%nY&mS!xYOY&hZ;'S&h;'S;=`&y<%lO&hY&|P;=`<%l&h^'SP;=`<%l%n~'[O#S~~'aO#Q~U'hUrS!}QOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U(RUrS#^QOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U(jWrSOt#{uw#{x!Q#{!Q![)S![#O#{#P;'S#{;'S;=`$d<%lO#{U)ZYrSmQOt#{uw#{x!O#{!O!P)y!P!Q#{!Q![)S![#O#{#P;'S#{;'S;=`$d<%lO#{U*OWrSOt#{uw#{x!Q#{!Q![*h![#O#{#P;'S#{;'S;=`$d<%lO#{U*oWrSmQOt#{uw#{x!Q#{!Q![*h![#O#{#P;'S#{;'S;=`$d<%lO#{U+^^rSOt#{uw#{x}#{}!O,Y!O!Q#{!Q![)S![!_#{!_!`-T!`#O#{#P#T#{#T#o,Y#o;'S#{;'S;=`$d<%lO#{U,_[rSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#o,Y#o;'S#{;'S;=`$d<%lO#{U-[UyQrSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U-sWrSOt#{uw#{x!P#{!P!Q.]!Q#O#{#P;'S#{;'S;=`$d<%lO#{U.b^rSOY/^YZ#{Zt/^tu0auw/^wx0ax!P/^!P!Q#{!Q!}/^!}#O5S#O#P2o#P;'S/^;'S;=`6T<%lO/^U/e^rSvQOY/^YZ#{Zt/^tu0auw/^wx0ax!P/^!P!Q3U!Q!}/^!}#O5S#O#P2o#P;'S/^;'S;=`6T<%lO/^Q0fXvQOY0aZ!P0a!P!Q1R!Q!}0a!}#O1p#O#P2o#P;'S0a;'S;=`3O<%lO0aQ1UP!P!Q1XQ1^UvQ#Z#[1X#]#^1X#a#b1X#g#h1X#i#j1X#m#n1XQ1sVOY1pZ#O1p#O#P2Y#P#Q0a#Q;'S1p;'S;=`2i<%lO1pQ2]SOY1pZ;'S1p;'S;=`2i<%lO1pQ2lP;=`<%l1pQ2rSOY0aZ;'S0a;'S;=`3O<%lO0aQ3RP;=`<%l0aU3ZWrSOt#{uw#{x!P#{!P!Q3s!Q#O#{#P;'S#{;'S;=`$d<%lO#{U3zbrSvQOt#{uw#{x#O#{#P#Z#{#Z#[3s#[#]#{#]#^3s#^#a#{#a#b3s#b#g#{#g#h3s#h#i#{#i#j3s#j#m#{#m#n3s#n;'S#{;'S;=`$d<%lO#{U5X[rSOY5SYZ#{Zt5Stu1puw5Swx1px#O5S#O#P2Y#P#Q/^#Q;'S5S;'S;=`5}<%lO5SU6QP;=`<%l5SU6WP;=`<%l/^U6bUrS!OQOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U6{W#YQrSOt#{uw#{x!_#{!_!`7e!`#O#{#P;'S#{;'S;=`$d<%lO#{U7jVrSOt#{uw#{x#O#{#P#Q8P#Q;'S#{;'S;=`$d<%lO#{U8WU#XQrSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{~8oO#T~U8vU#]QrSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U9aUrS!VQOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U9x]rSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#U:q#U#o,Y#o;'S#{;'S;=`$d<%lO#{U:v^rSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#`,Y#`#a;r#a#o,Y#o;'S#{;'S;=`$d<%lO#{U;w^rSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#g,Y#g#h<s#h#o,Y#o;'S#{;'S;=`$d<%lO#{U<x^rSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#X,Y#X#Y=t#Y#o,Y#o;'S#{;'S;=`$d<%lO#{U={[uQrSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#o,Y#o;'S#{;'S;=`$d<%lO#{^>x[#UWrSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#o,Y#o;'S#{;'S;=`$d<%lO#{^?u[#WWrSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#o,Y#o;'S#{;'S;=`$d<%lO#{^@r^#VWrSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#f,Y#f#gAn#g#o,Y#o;'S#{;'S;=`$d<%lO#{UAs^rSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#i,Y#i#j<s#j#o,Y#o;'S#{;'S;=`$d<%lO#{UBvU!ZQrSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{~C_O#`~",
|
tokenData: "C_~R|OX#{XY$jYZ%TZp#{pq$jqs#{st%ntu'Vuw#{wx'[xy'ayz'zz{#{{|(e|}#{}!O+X!O!P#{!P!Q-n!Q![)S![!]6Z!]!^%T!^!}#{!}#O6t#O#P8j#P#Q8o#Q#R#{#R#S9Y#S#T#{#T#Y,Y#Y#Z9s#Z#b,Y#b#c>q#c#f,Y#f#g?n#g#h,Y#h#i@k#i#o,Y#o#p#{#p#qBo#q;'S#{;'S;=`$d<%l~#{~O#{~~CYS$QUrSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{S$gP;=`<%l#{^$qUrS!xYOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U%[UrS#[QOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{^%uZrS!yYOY%nYZ#{Zt%ntu&huw%nwx&hx#O%n#O#P&h#P;'S%n;'S;=`'P<%lO%nY&mS!yYOY&hZ;'S&h;'S;=`&y<%lO&hY&|P;=`<%l&h^'SP;=`<%l%n~'[O#T~~'aO#R~U'hUrS#OQOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U(RUrS#aQOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U(jWrSOt#{uw#{x!Q#{!Q![)S![#O#{#P;'S#{;'S;=`$d<%lO#{U)ZYrSmQOt#{uw#{x!O#{!O!P)y!P!Q#{!Q![)S![#O#{#P;'S#{;'S;=`$d<%lO#{U*OWrSOt#{uw#{x!Q#{!Q![*h![#O#{#P;'S#{;'S;=`$d<%lO#{U*oWrSmQOt#{uw#{x!Q#{!Q![*h![#O#{#P;'S#{;'S;=`$d<%lO#{U+^^rSOt#{uw#{x}#{}!O,Y!O!Q#{!Q![)S![!_#{!_!`-T!`#O#{#P#T#{#T#o,Y#o;'S#{;'S;=`$d<%lO#{U,_[rSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#o,Y#o;'S#{;'S;=`$d<%lO#{U-[UyQrSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U-sWrSOt#{uw#{x!P#{!P!Q.]!Q#O#{#P;'S#{;'S;=`$d<%lO#{U.b^rSOY/^YZ#{Zt/^tu0auw/^wx0ax!P/^!P!Q#{!Q!}/^!}#O5S#O#P2o#P;'S/^;'S;=`6T<%lO/^U/e^rSvQOY/^YZ#{Zt/^tu0auw/^wx0ax!P/^!P!Q3U!Q!}/^!}#O5S#O#P2o#P;'S/^;'S;=`6T<%lO/^Q0fXvQOY0aZ!P0a!P!Q1R!Q!}0a!}#O1p#O#P2o#P;'S0a;'S;=`3O<%lO0aQ1UP!P!Q1XQ1^UvQ#Z#[1X#]#^1X#a#b1X#g#h1X#i#j1X#m#n1XQ1sVOY1pZ#O1p#O#P2Y#P#Q0a#Q;'S1p;'S;=`2i<%lO1pQ2]SOY1pZ;'S1p;'S;=`2i<%lO1pQ2lP;=`<%l1pQ2rSOY0aZ;'S0a;'S;=`3O<%lO0aQ3RP;=`<%l0aU3ZWrSOt#{uw#{x!P#{!P!Q3s!Q#O#{#P;'S#{;'S;=`$d<%lO#{U3zbrSvQOt#{uw#{x#O#{#P#Z#{#Z#[3s#[#]#{#]#^3s#^#a#{#a#b3s#b#g#{#g#h3s#h#i#{#i#j3s#j#m#{#m#n3s#n;'S#{;'S;=`$d<%lO#{U5X[rSOY5SYZ#{Zt5Stu1puw5Swx1px#O5S#O#P2Y#P#Q/^#Q;'S5S;'S;=`5}<%lO5SU6QP;=`<%l5SU6WP;=`<%l/^U6bUrS!OQOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U6{W#ZQrSOt#{uw#{x!_#{!_!`7e!`#O#{#P;'S#{;'S;=`$d<%lO#{U7jVrSOt#{uw#{x#O#{#P#Q8P#Q;'S#{;'S;=`$d<%lO#{U8WU#YQrSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{~8oO#U~U8vU#`QrSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U9aUrS!VQOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{U9x]rSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#U:q#U#o,Y#o;'S#{;'S;=`$d<%lO#{U:v^rSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#`,Y#`#a;r#a#o,Y#o;'S#{;'S;=`$d<%lO#{U;w^rSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#g,Y#g#h<s#h#o,Y#o;'S#{;'S;=`$d<%lO#{U<x^rSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#X,Y#X#Y=t#Y#o,Y#o;'S#{;'S;=`$d<%lO#{U={[uQrSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#o,Y#o;'S#{;'S;=`$d<%lO#{^>x[#VWrSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#o,Y#o;'S#{;'S;=`$d<%lO#{^?u[#XWrSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#o,Y#o;'S#{;'S;=`$d<%lO#{^@r^#WWrSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#f,Y#f#gAn#g#o,Y#o;'S#{;'S;=`$d<%lO#{UAs^rSOt#{uw#{x}#{}!O,Y!O!_#{!_!`-T!`#O#{#P#T#{#T#i,Y#i#j<s#j#o,Y#o;'S#{;'S;=`$d<%lO#{UBvU!ZQrSOt#{uw#{x#O#{#P;'S#{;'S;=`$d<%lO#{~C_O#i~",
|
||||||
tokenizers: [operatorTokenizer, 1, 2, 3, tokenizer, new LocalTokenGroup("[~RP!O!PU~ZO!|~~", 11)],
|
tokenizers: [operatorTokenizer, 1, 2, 3, tokenizer, new LocalTokenGroup("[~RP!O!PU~ZO!}~~", 11)],
|
||||||
topRules: {"Program":[0,25]},
|
topRules: {"Program":[0,25]},
|
||||||
specialized: [{term: 20, get: (value: any, stack: any) => (specializeKeyword(value, stack) << 1), external: specializeKeyword},{term: 20, get: (value: keyof typeof spec_Identifier) => spec_Identifier[value] || -1}],
|
specialized: [{term: 20, get: (value: any, stack: any) => (specializeKeyword(value, stack) << 1), external: specializeKeyword},{term: 20, get: (value: keyof typeof spec_Identifier) => spec_Identifier[value] || -1}],
|
||||||
tokenPrec: 1578
|
tokenPrec: 1705
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -752,7 +752,7 @@ Assign
|
||||||
EqEq ==
|
EqEq ==
|
||||||
Number 5
|
Number 5
|
||||||
colon :
|
colon :
|
||||||
Block
|
ThenBlock
|
||||||
Boolean true
|
Boolean true
|
||||||
keyword end
|
keyword end
|
||||||
keyword end
|
keyword end
|
||||||
|
|
@ -794,7 +794,7 @@ Assign
|
||||||
EqEq ==
|
EqEq ==
|
||||||
Number 5
|
Number 5
|
||||||
colon :
|
colon :
|
||||||
Block
|
ThenBlock
|
||||||
Boolean true
|
Boolean true
|
||||||
keyword end
|
keyword end
|
||||||
keyword end
|
keyword end
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ describe('if/else if/else', () => {
|
||||||
EqEq ==
|
EqEq ==
|
||||||
Number 1
|
Number 1
|
||||||
colon :
|
colon :
|
||||||
Block
|
SingleLineThenBlock
|
||||||
String
|
String
|
||||||
StringFragment cool
|
StringFragment cool
|
||||||
keyword end
|
keyword end
|
||||||
|
|
@ -26,7 +26,7 @@ describe('if/else if/else', () => {
|
||||||
keyword if
|
keyword if
|
||||||
Identifier x
|
Identifier x
|
||||||
colon :
|
colon :
|
||||||
Block
|
SingleLineThenBlock
|
||||||
Number 2
|
Number 2
|
||||||
keyword end
|
keyword end
|
||||||
`)
|
`)
|
||||||
|
|
@ -44,7 +44,7 @@ describe('if/else if/else', () => {
|
||||||
Lt <
|
Lt <
|
||||||
Number 9
|
Number 9
|
||||||
colon :
|
colon :
|
||||||
Block
|
ThenBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier yes
|
Identifier yes
|
||||||
keyword end
|
keyword end
|
||||||
|
|
@ -61,13 +61,13 @@ describe('if/else if/else', () => {
|
||||||
keyword if
|
keyword if
|
||||||
Identifier with-else
|
Identifier with-else
|
||||||
colon :
|
colon :
|
||||||
Block
|
ThenBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier x
|
Identifier x
|
||||||
ElseExpr
|
ElseExpr
|
||||||
keyword else
|
keyword else
|
||||||
colon :
|
colon :
|
||||||
Block
|
ThenBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier y
|
Identifier y
|
||||||
keyword end
|
keyword end
|
||||||
|
|
@ -75,24 +75,23 @@ describe('if/else if/else', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('parses multiline if with elseif', () => {
|
test('parses multiline if with elseif', () => {
|
||||||
expect(`if with-else-if:
|
expect(`if with-elseif:
|
||||||
x
|
x
|
||||||
elseif another-condition:
|
elseif another-condition:
|
||||||
y
|
y
|
||||||
end`).toMatchTree(`
|
end`).toMatchTree(`
|
||||||
IfExpr
|
IfExpr
|
||||||
keyword if
|
keyword if
|
||||||
Identifier with-else-if
|
Identifier with-elseif
|
||||||
colon :
|
colon :
|
||||||
Block
|
ThenBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier x
|
Identifier x
|
||||||
ElseIfExpr
|
ElseIfExpr
|
||||||
keyword else
|
keyword elseif
|
||||||
keyword if
|
|
||||||
Identifier another-condition
|
Identifier another-condition
|
||||||
colon :
|
colon :
|
||||||
Block
|
ThenBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier y
|
Identifier y
|
||||||
keyword end
|
keyword end
|
||||||
|
|
@ -100,7 +99,7 @@ describe('if/else if/else', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('parses multiline if with multiple elseif and else', () => {
|
test('parses multiline if with multiple elseif and else', () => {
|
||||||
expect(`if with-else-if-else:
|
expect(`if with-elseif-else:
|
||||||
x
|
x
|
||||||
elseif another-condition:
|
elseif another-condition:
|
||||||
y
|
y
|
||||||
|
|
@ -111,31 +110,29 @@ describe('if/else if/else', () => {
|
||||||
end`).toMatchTree(`
|
end`).toMatchTree(`
|
||||||
IfExpr
|
IfExpr
|
||||||
keyword if
|
keyword if
|
||||||
Identifier with-else-if-else
|
Identifier with-elseif-else
|
||||||
colon :
|
colon :
|
||||||
Block
|
ThenBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier x
|
Identifier x
|
||||||
ElseIfExpr
|
ElseIfExpr
|
||||||
keyword else
|
keyword elseif
|
||||||
keyword if
|
|
||||||
Identifier another-condition
|
Identifier another-condition
|
||||||
colon :
|
colon :
|
||||||
Block
|
ThenBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier y
|
Identifier y
|
||||||
ElseIfExpr
|
ElseIfExpr
|
||||||
keyword else
|
keyword elseif
|
||||||
keyword if
|
|
||||||
Identifier yet-another-condition
|
Identifier yet-another-condition
|
||||||
colon :
|
colon :
|
||||||
Block
|
ThenBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier z
|
Identifier z
|
||||||
ElseExpr
|
ElseExpr
|
||||||
keyword else
|
keyword else
|
||||||
colon :
|
colon :
|
||||||
Block
|
ThenBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier oh-no
|
Identifier oh-no
|
||||||
keyword end
|
keyword end
|
||||||
|
|
@ -151,124 +148,9 @@ describe('if/else if/else', () => {
|
||||||
keyword if
|
keyword if
|
||||||
Boolean true
|
Boolean true
|
||||||
colon :
|
colon :
|
||||||
Block
|
SingleLineThenBlock
|
||||||
Number 2
|
Number 2
|
||||||
keyword end
|
keyword end
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('while', () => {
|
|
||||||
test('infinite loop', () => {
|
|
||||||
expect(`while true: true end`).toMatchTree(`
|
|
||||||
WhileExpr
|
|
||||||
keyword while
|
|
||||||
Boolean true
|
|
||||||
colon :
|
|
||||||
Block
|
|
||||||
Boolean true
|
|
||||||
keyword end`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('basic expression', () => {
|
|
||||||
expect(`while a > 0: true end`).toMatchTree(`
|
|
||||||
WhileExpr
|
|
||||||
keyword while
|
|
||||||
ConditionalOp
|
|
||||||
Identifier a
|
|
||||||
Gt >
|
|
||||||
Number 0
|
|
||||||
colon :
|
|
||||||
Block
|
|
||||||
Boolean true
|
|
||||||
keyword end`)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
test('compound expression', () => {
|
|
||||||
expect(`while a > 0 and b < 100 and c < 1000: true end`).toMatchTree(`
|
|
||||||
WhileExpr
|
|
||||||
keyword while
|
|
||||||
ConditionalOp
|
|
||||||
ConditionalOp
|
|
||||||
ConditionalOp
|
|
||||||
Identifier a
|
|
||||||
Gt >
|
|
||||||
Number 0
|
|
||||||
And and
|
|
||||||
ConditionalOp
|
|
||||||
Identifier b
|
|
||||||
Lt <
|
|
||||||
Number 100
|
|
||||||
And and
|
|
||||||
ConditionalOp
|
|
||||||
Identifier c
|
|
||||||
Lt <
|
|
||||||
Number 1000
|
|
||||||
colon :
|
|
||||||
Block
|
|
||||||
Boolean true
|
|
||||||
keyword end`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('multiline infinite loop', () => {
|
|
||||||
expect(`
|
|
||||||
while true:
|
|
||||||
true
|
|
||||||
end`).toMatchTree(`
|
|
||||||
WhileExpr
|
|
||||||
keyword while
|
|
||||||
Boolean true
|
|
||||||
colon :
|
|
||||||
Block
|
|
||||||
Boolean true
|
|
||||||
keyword end`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('multiline basic expression', () => {
|
|
||||||
expect(`
|
|
||||||
while a > 0:
|
|
||||||
true
|
|
||||||
end`).toMatchTree(`
|
|
||||||
WhileExpr
|
|
||||||
keyword while
|
|
||||||
ConditionalOp
|
|
||||||
Identifier a
|
|
||||||
Gt >
|
|
||||||
Number 0
|
|
||||||
colon :
|
|
||||||
Block
|
|
||||||
Boolean true
|
|
||||||
keyword end`)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
test('multiline compound expression', () => {
|
|
||||||
expect(`
|
|
||||||
while a > 0 and b < 100 and c < 1000:
|
|
||||||
true
|
|
||||||
end`).toMatchTree(`
|
|
||||||
WhileExpr
|
|
||||||
keyword while
|
|
||||||
ConditionalOp
|
|
||||||
ConditionalOp
|
|
||||||
ConditionalOp
|
|
||||||
Identifier a
|
|
||||||
Gt >
|
|
||||||
Number 0
|
|
||||||
And and
|
|
||||||
ConditionalOp
|
|
||||||
Identifier b
|
|
||||||
Lt <
|
|
||||||
Number 100
|
|
||||||
And and
|
|
||||||
ConditionalOp
|
|
||||||
Identifier c
|
|
||||||
Lt <
|
|
||||||
Number 1000
|
|
||||||
colon :
|
|
||||||
Block
|
|
||||||
Boolean true
|
|
||||||
keyword end`)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
@ -12,14 +12,14 @@ describe('try/catch/finally/throw', () => {
|
||||||
TryExpr
|
TryExpr
|
||||||
keyword try
|
keyword try
|
||||||
colon :
|
colon :
|
||||||
Block
|
TryBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier risky-operation
|
Identifier risky-operation
|
||||||
CatchExpr
|
CatchExpr
|
||||||
keyword catch
|
keyword catch
|
||||||
Identifier err
|
Identifier err
|
||||||
colon :
|
colon :
|
||||||
Block
|
TryBlock
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier handle-error
|
Identifier handle-error
|
||||||
PositionalArg
|
PositionalArg
|
||||||
|
|
@ -37,13 +37,13 @@ describe('try/catch/finally/throw', () => {
|
||||||
TryExpr
|
TryExpr
|
||||||
keyword try
|
keyword try
|
||||||
colon :
|
colon :
|
||||||
Block
|
TryBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier do-work
|
Identifier do-work
|
||||||
FinallyExpr
|
FinallyExpr
|
||||||
keyword finally
|
keyword finally
|
||||||
colon :
|
colon :
|
||||||
Block
|
TryBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier cleanup
|
Identifier cleanup
|
||||||
keyword end
|
keyword end
|
||||||
|
|
@ -61,14 +61,14 @@ describe('try/catch/finally/throw', () => {
|
||||||
TryExpr
|
TryExpr
|
||||||
keyword try
|
keyword try
|
||||||
colon :
|
colon :
|
||||||
Block
|
TryBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier risky-operation
|
Identifier risky-operation
|
||||||
CatchExpr
|
CatchExpr
|
||||||
keyword catch
|
keyword catch
|
||||||
Identifier err
|
Identifier err
|
||||||
colon :
|
colon :
|
||||||
Block
|
TryBlock
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier handle-error
|
Identifier handle-error
|
||||||
PositionalArg
|
PositionalArg
|
||||||
|
|
@ -76,7 +76,7 @@ describe('try/catch/finally/throw', () => {
|
||||||
FinallyExpr
|
FinallyExpr
|
||||||
keyword finally
|
keyword finally
|
||||||
colon :
|
colon :
|
||||||
Block
|
TryBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier cleanup
|
Identifier cleanup
|
||||||
keyword end
|
keyword end
|
||||||
|
|
@ -91,7 +91,6 @@ describe('try/catch/finally/throw', () => {
|
||||||
TryExpr
|
TryExpr
|
||||||
keyword try
|
keyword try
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier parse-number
|
Identifier parse-number
|
||||||
PositionalArg
|
PositionalArg
|
||||||
|
|
@ -100,7 +99,6 @@ describe('try/catch/finally/throw', () => {
|
||||||
keyword catch
|
keyword catch
|
||||||
Identifier err
|
Identifier err
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
Number 0
|
Number 0
|
||||||
keyword end
|
keyword end
|
||||||
`)
|
`)
|
||||||
|
|
@ -111,19 +109,16 @@ describe('try/catch/finally/throw', () => {
|
||||||
TryExpr
|
TryExpr
|
||||||
keyword try
|
keyword try
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier work
|
Identifier work
|
||||||
CatchExpr
|
CatchExpr
|
||||||
keyword catch
|
keyword catch
|
||||||
Identifier err
|
Identifier err
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
Number 0
|
Number 0
|
||||||
FinallyExpr
|
FinallyExpr
|
||||||
keyword finally
|
keyword finally
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier cleanup
|
Identifier cleanup
|
||||||
keyword end
|
keyword end
|
||||||
|
|
@ -169,14 +164,12 @@ describe('try/catch/finally/throw', () => {
|
||||||
TryExpr
|
TryExpr
|
||||||
keyword try
|
keyword try
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier work
|
Identifier work
|
||||||
CatchExpr
|
CatchExpr
|
||||||
keyword catch
|
keyword catch
|
||||||
Identifier err
|
Identifier err
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
Number 0
|
Number 0
|
||||||
keyword end
|
keyword end
|
||||||
`)
|
`)
|
||||||
|
|
@ -206,7 +199,7 @@ describe('function-level exception handling', () => {
|
||||||
keyword catch
|
keyword catch
|
||||||
Identifier e
|
Identifier e
|
||||||
colon :
|
colon :
|
||||||
Block
|
TryBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier empty-string
|
Identifier empty-string
|
||||||
keyword end
|
keyword end
|
||||||
|
|
@ -234,7 +227,7 @@ describe('function-level exception handling', () => {
|
||||||
FinallyExpr
|
FinallyExpr
|
||||||
keyword finally
|
keyword finally
|
||||||
colon :
|
colon :
|
||||||
Block
|
TryBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier close-resources
|
Identifier close-resources
|
||||||
keyword end
|
keyword end
|
||||||
|
|
@ -266,7 +259,7 @@ describe('function-level exception handling', () => {
|
||||||
keyword catch
|
keyword catch
|
||||||
Identifier err
|
Identifier err
|
||||||
colon :
|
colon :
|
||||||
Block
|
TryBlock
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier log
|
Identifier log
|
||||||
PositionalArg
|
PositionalArg
|
||||||
|
|
@ -276,7 +269,7 @@ describe('function-level exception handling', () => {
|
||||||
FinallyExpr
|
FinallyExpr
|
||||||
keyword finally
|
keyword finally
|
||||||
colon :
|
colon :
|
||||||
Block
|
TryBlock
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier cleanup
|
Identifier cleanup
|
||||||
keyword end
|
keyword end
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ describe('single line function blocks', () => {
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier trap
|
Identifier trap
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier echo
|
Identifier echo
|
||||||
PositionalArg
|
PositionalArg
|
||||||
|
|
@ -28,7 +27,6 @@ describe('single line function blocks', () => {
|
||||||
PositionalArg
|
PositionalArg
|
||||||
Word EXIT
|
Word EXIT
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier echo
|
Identifier echo
|
||||||
PositionalArg
|
PositionalArg
|
||||||
|
|
@ -49,7 +47,6 @@ describe('single line function blocks', () => {
|
||||||
String
|
String
|
||||||
StringFragment exit
|
StringFragment exit
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier echo
|
Identifier echo
|
||||||
PositionalArg
|
PositionalArg
|
||||||
|
|
@ -76,7 +73,6 @@ describe('single line function blocks', () => {
|
||||||
String
|
String
|
||||||
StringFragment EXIT
|
StringFragment EXIT
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier echo
|
Identifier echo
|
||||||
PositionalArg
|
PositionalArg
|
||||||
|
|
@ -99,7 +95,6 @@ end
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier trap
|
Identifier trap
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier echo
|
Identifier echo
|
||||||
PositionalArg
|
PositionalArg
|
||||||
|
|
@ -121,7 +116,6 @@ end`).toMatchTree(`
|
||||||
PositionalArg
|
PositionalArg
|
||||||
Word EXIT
|
Word EXIT
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier echo
|
Identifier echo
|
||||||
PositionalArg
|
PositionalArg
|
||||||
|
|
@ -148,7 +142,6 @@ end`).toMatchTree(`
|
||||||
NamedArgPrefix code=
|
NamedArgPrefix code=
|
||||||
Number 1
|
Number 1
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier echo
|
Identifier echo
|
||||||
PositionalArg
|
PositionalArg
|
||||||
|
|
@ -179,7 +172,6 @@ end`).toMatchTree(`
|
||||||
String
|
String
|
||||||
StringFragment EXIT
|
StringFragment EXIT
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier echo
|
Identifier echo
|
||||||
PositionalArg
|
PositionalArg
|
||||||
|
|
@ -203,7 +195,6 @@ end`).toMatchTree(`
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier head
|
Identifier head
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier title
|
Identifier title
|
||||||
PositionalArg
|
PositionalArg
|
||||||
|
|
@ -239,7 +230,6 @@ end`).toMatchTree(`
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier list
|
Identifier list
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier li
|
Identifier li
|
||||||
NamedArg
|
NamedArg
|
||||||
|
|
@ -270,7 +260,6 @@ end`)
|
||||||
FunctionCallOrIdentifier
|
FunctionCallOrIdentifier
|
||||||
Identifier p
|
Identifier p
|
||||||
colon :
|
colon :
|
||||||
Block
|
|
||||||
FunctionCall
|
FunctionCall
|
||||||
Identifier h1
|
Identifier h1
|
||||||
NamedArg
|
NamedArg
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user