Compare commits

...
12 Commits
40 changed files with 1045 additions and 618 deletions

No files matched your search

+1
View File
@@ -1,4 +1,5 @@
.idea/workspace.xml
.idea/discord.xml
/build/
/dist/
/output/
@@ -232,7 +232,7 @@ class AsmGen(private val options: CompilationOptions, private val program: Inter
private fun block2asm(blk: IntermediateProgram.ProgramBlock) {
block = blk
out("\n; ---- block: '${block.name}' ----")
out("\n\n; ---- block: '${block.name}' ----")
if(!blk.force_output)
out("${block.name}\t.proc\n")
if(block.address!=null) {
+1 -1
View File
@@ -26,7 +26,7 @@ which aims to provide many conveniences over raw assembly code (even when using
- abstracting away low level aspects such as ZeroPage handling, program startup, explicit memory addresses
- various code optimizations (code structure, logical and numerical expressions, unused code removal...)
- inline assembly allows you to have full control when every cycle or byte matters
- many built-in functions such as ``sin``, ``cos``, ``rnd``, ``abs``, ``min``, ``max``, ``sqrt``, ``msb``, ``rol``, ``ror``, ``swap``, ``memset``, ``memcopy``
- many built-in functions such as ``sin``, ``cos``, ``rnd``, ``abs``, ``min``, ``max``, ``sqrt``, ``msb``, ``rol``, ``ror``, ``swap``, ``memset``, ``memcopy``, ``sort`` and ``reverse``
Rapid edit-compile-run-debug cycle:
-3
View File
@@ -81,9 +81,6 @@ artifacts {
}
// To create a fat-jar use the 'create_compiler_jar' script for now
// @todo investigate https://imperceptiblethoughts.com/shadow/introduction/
shadowJar {
baseName = 'prog8compiler'
version = prog8version
+287
View File
@@ -1384,3 +1384,290 @@ _mod2b lda #0 ; self-modified
_done rts
.pend
sort_ub .proc
; 8bit unsigned sort
; sorting subroutine coded by mats rosengren (mats.rosengren@esa.int)
; input: address of array to sort in c64.SCRATCH_ZPWORD1, length in c64.SCRATCH_ZPB1
; first, put pointer BEFORE array
lda c64.SCRATCH_ZPWORD1
bne +
dec c64.SCRATCH_ZPWORD1+1
+ dec c64.SCRATCH_ZPWORD1
_sortloop ldy c64.SCRATCH_ZPB1 ;start of subroutine sort
lda (c64.SCRATCH_ZPWORD1),y ;last value in (what is left of) sequence to be sorted
sta c64.SCRATCH_ZPREG ;save value. will be over-written by largest number
jmp _l2
_l1 dey
beq _l3
lda (c64.SCRATCH_ZPWORD1),y
cmp c64.SCRATCH_ZPWORD2+1
bcc _l1
_l2 sty c64.SCRATCH_ZPWORD2 ;index of potentially largest value
sta c64.SCRATCH_ZPWORD2+1 ;potentially largest value
jmp _l1
_l3 ldy c64.SCRATCH_ZPB1 ;where the largest value shall be put
lda c64.SCRATCH_ZPWORD2+1 ;the largest value
sta (c64.SCRATCH_ZPWORD1),y ;put largest value in place
ldy c64.SCRATCH_ZPWORD2 ;index of free space
lda c64.SCRATCH_ZPREG ;the over-written value
sta (c64.SCRATCH_ZPWORD1),y ;put the over-written value in the free space
dec c64.SCRATCH_ZPB1 ;end of the shorter sequence still left
bne _sortloop ;start working with the shorter sequence
rts
.pend
sort_b .proc
; 8bit signed sort
; sorting subroutine coded by mats rosengren (mats.rosengren@esa.int)
; input: address of array to sort in c64.SCRATCH_ZPWORD1, length in c64.SCRATCH_ZPB1
; first, put pointer BEFORE array
lda c64.SCRATCH_ZPWORD1
bne +
dec c64.SCRATCH_ZPWORD1+1
+ dec c64.SCRATCH_ZPWORD1
_sortloop ldy c64.SCRATCH_ZPB1 ;start of subroutine sort
lda (c64.SCRATCH_ZPWORD1),y ;last value in (what is left of) sequence to be sorted
sta c64.SCRATCH_ZPREG ;save value. will be over-written by largest number
jmp _l2
_l1 dey
beq _l3
lda (c64.SCRATCH_ZPWORD1),y
cmp c64.SCRATCH_ZPWORD2+1
bmi _l1
_l2 sty c64.SCRATCH_ZPWORD2 ;index of potentially largest value
sta c64.SCRATCH_ZPWORD2+1 ;potentially largest value
jmp _l1
_l3 ldy c64.SCRATCH_ZPB1 ;where the largest value shall be put
lda c64.SCRATCH_ZPWORD2+1 ;the largest value
sta (c64.SCRATCH_ZPWORD1),y ;put largest value in place
ldy c64.SCRATCH_ZPWORD2 ;index of free space
lda c64.SCRATCH_ZPREG ;the over-written value
sta (c64.SCRATCH_ZPWORD1),y ;put the over-written value in the free space
dec c64.SCRATCH_ZPB1 ;end of the shorter sequence still left
bne _sortloop ;start working with the shorter sequence
rts
.pend
sort_uw .proc
; 16bit unsigned sort
; sorting subroutine coded by mats rosengren (mats.rosengren@esa.int)
; input: address of array to sort in c64.SCRATCH_ZPWORD1, length in c64.SCRATCH_ZPB1
; first: subtract 2 of the pointer
asl c64.SCRATCH_ZPB1 ; *2 because words
lda c64.SCRATCH_ZPWORD1
sec
sbc #2
sta c64.SCRATCH_ZPWORD1
bcs _sort_loop
dec c64.SCRATCH_ZPWORD1+1
_sort_loop ldy c64.SCRATCH_ZPB1 ;start of subroutine sort
lda (c64.SCRATCH_ZPWORD1),y ;last value in (what is left of) sequence to be sorted
sta _work3 ;save value. will be over-written by largest number
iny
lda (c64.SCRATCH_ZPWORD1),y
sta _work3+1
dey
jmp _l2
_l1 dey
dey
beq _l3
iny
lda (c64.SCRATCH_ZPWORD1),y
dey
cmp c64.SCRATCH_ZPWORD2+1
bne +
lda (c64.SCRATCH_ZPWORD1),y
cmp c64.SCRATCH_ZPWORD2
+ bcc _l1
_l2 sty _work1 ;index of potentially largest value
lda (c64.SCRATCH_ZPWORD1),y
sta c64.SCRATCH_ZPWORD2 ;potentially largest value
iny
lda (c64.SCRATCH_ZPWORD1),y
sta c64.SCRATCH_ZPWORD2+1
dey
jmp _l1
_l3 ldy c64.SCRATCH_ZPB1 ;where the largest value shall be put
lda c64.SCRATCH_ZPWORD2 ;the largest value
sta (c64.SCRATCH_ZPWORD1),y ;put largest value in place
iny
lda c64.SCRATCH_ZPWORD2+1
sta (c64.SCRATCH_ZPWORD1),y
ldy _work1 ;index of free space
lda _work3 ;the over-written value
sta (c64.SCRATCH_ZPWORD1),y ;put the over-written value in the free space
iny
lda _work3+1
sta (c64.SCRATCH_ZPWORD1),y
dey
dec c64.SCRATCH_ZPB1 ;end of the shorter sequence still left
dec c64.SCRATCH_ZPB1
bne _sort_loop ;start working with the shorter sequence
rts
_work1 .byte 0
_work3 .word 0
.pend
sort_w .proc
; 16bit signed sort
; sorting subroutine coded by mats rosengren (mats.rosengren@esa.int)
; input: address of array to sort in c64.SCRATCH_ZPWORD1, length in c64.SCRATCH_ZPB1
; first: subtract 2 of the pointer
asl c64.SCRATCH_ZPB1 ; *2 because words
lda c64.SCRATCH_ZPWORD1
sec
sbc #2
sta c64.SCRATCH_ZPWORD1
bcs _sort_loop
dec c64.SCRATCH_ZPWORD1+1
_sort_loop ldy c64.SCRATCH_ZPB1 ;start of subroutine sort
lda (c64.SCRATCH_ZPWORD1),y ;last value in (what is left of) sequence to be sorted
sta _work3 ;save value. will be over-written by largest number
iny
lda (c64.SCRATCH_ZPWORD1),y
sta _work3+1
dey
jmp _l2
_l1 dey
dey
beq _l3
lda (c64.SCRATCH_ZPWORD1),y
cmp c64.SCRATCH_ZPWORD2
iny
lda (c64.SCRATCH_ZPWORD1),y
dey
sbc c64.SCRATCH_ZPWORD2+1
bvc +
eor #$80
+ bmi _l1
_l2 sty _work1 ;index of potentially largest value
lda (c64.SCRATCH_ZPWORD1),y
sta c64.SCRATCH_ZPWORD2 ;potentially largest value
iny
lda (c64.SCRATCH_ZPWORD1),y
sta c64.SCRATCH_ZPWORD2+1
dey
jmp _l1
_l3 ldy c64.SCRATCH_ZPB1 ;where the largest value shall be put
lda c64.SCRATCH_ZPWORD2 ;the largest value
sta (c64.SCRATCH_ZPWORD1),y ;put largest value in place
iny
lda c64.SCRATCH_ZPWORD2+1
sta (c64.SCRATCH_ZPWORD1),y
ldy _work1 ;index of free space
lda _work3 ;the over-written value
sta (c64.SCRATCH_ZPWORD1),y ;put the over-written value in the free space
iny
lda _work3+1
sta (c64.SCRATCH_ZPWORD1),y
dey
dec c64.SCRATCH_ZPB1 ;end of the shorter sequence still left
dec c64.SCRATCH_ZPB1
bne _sort_loop ;start working with the shorter sequence
rts
_work1 .byte 0
_work3 .word 0
.pend
reverse_b .proc
; --- reverse an array of bytes (in-place)
; inputs: pointer to array in c64.SCRATCH_ZPWORD1, length in A
_left_index = c64.SCRATCH_ZPWORD2
_right_index = c64.SCRATCH_ZPWORD2+1
pha
sec
sbc #1
sta _left_index
lda #0
sta _right_index
pla
lsr a
tay
_loop sty c64.SCRATCH_ZPREG
ldy _left_index
lda (c64.SCRATCH_ZPWORD1),y
pha
ldy _right_index
lda (c64.SCRATCH_ZPWORD1),y
ldy _left_index
sta (c64.SCRATCH_ZPWORD1),y
pla
ldy _right_index
sta (c64.SCRATCH_ZPWORD1),y
inc _right_index
dec _left_index
ldy c64.SCRATCH_ZPREG
dey
bne _loop
rts
.pend
reverse_w .proc
; --- reverse an array of words (in-place)
; inputs: pointer to array in c64.SCRATCH_ZPWORD1, length in A
_left_index = c64.SCRATCH_ZPWORD2
_right_index = c64.SCRATCH_ZPWORD2+1
pha
asl a ; *2 because words
sec
sbc #2
sta _left_index
lda #0
sta _right_index
pla
lsr a
pha
tay
; first reverse the lsbs
_loop_lo sty c64.SCRATCH_ZPREG
ldy _left_index
lda (c64.SCRATCH_ZPWORD1),y
pha
ldy _right_index
lda (c64.SCRATCH_ZPWORD1),y
ldy _left_index
sta (c64.SCRATCH_ZPWORD1),y
pla
ldy _right_index
sta (c64.SCRATCH_ZPWORD1),y
inc _right_index
inc _right_index
dec _left_index
dec _left_index
ldy c64.SCRATCH_ZPREG
dey
bne _loop_lo
; now reverse the msbs
dec _right_index
inc _left_index
inc _left_index
inc _left_index
pla
tay
_loop_hi sty c64.SCRATCH_ZPREG
ldy _left_index
lda (c64.SCRATCH_ZPWORD1),y
pha
ldy _right_index
lda (c64.SCRATCH_ZPWORD1),y
ldy _left_index
sta (c64.SCRATCH_ZPWORD1),y
pla
ldy _right_index
sta (c64.SCRATCH_ZPWORD1),y
dec _right_index
dec _right_index
inc _left_index
inc _left_index
ldy c64.SCRATCH_ZPREG
dey
bne _loop_hi
rts
.pend
+2 -1
View File
@@ -1 +1,2 @@
1.52
1.60
@@ -315,13 +315,6 @@ class AstToSourceCode(val output: (text: String) -> Unit, val program: Program):
override fun visit(forLoop: ForLoop) {
output("for ")
if(forLoop.decltype!=null) {
output(datatypeString(forLoop.decltype))
if (forLoop.zeropage==ZeropageWish.REQUIRE_ZEROPAGE || forLoop.zeropage==ZeropageWish.PREFER_ZEROPAGE)
output(" @zp ")
else
output(" ")
}
if(forLoop.loopRegister!=null)
output(forLoop.loopRegister.toString())
else
+1 -3
View File
@@ -552,8 +552,6 @@ private fun prog8Parser.BranchconditionContext.toAst() = BranchCondition.valueOf
private fun prog8Parser.ForloopContext.toAst(): ForLoop {
val loopregister = register()?.toAst()
val datatype = datatype()?.toAst()
val zeropage = if(ZEROPAGE() != null) ZeropageWish.PREFER_ZEROPAGE else ZeropageWish.DONTCARE
val loopvar = identifier()?.toAst()
val iterable = expression()!!.toAst()
val scope =
@@ -561,7 +559,7 @@ private fun prog8Parser.ForloopContext.toAst(): ForLoop {
AnonymousScope(mutableListOf(statement().toAst()), statement().toPosition())
else
AnonymousScope(statement_block().toAst(), statement_block().toPosition())
return ForLoop(loopregister, datatype, zeropage, loopvar, iterable, scope, toPosition())
return ForLoop(loopregister, loopvar, iterable, scope, toPosition())
}
@@ -24,6 +24,14 @@ object InferredTypes {
return false
return isVoid==other.isVoid && datatype==other.datatype
}
override fun toString(): String {
return when {
datatype!=null -> datatype.toString()
isVoid -> "<void>"
else -> "<unkonwn>"
}
}
}
private val unknownInstance = InferredType.unknown()
@@ -1,5 +1,6 @@
package prog8.ast.processing
import prog8.ast.IFunctionCall
import prog8.ast.INameScope
import prog8.ast.Module
import prog8.ast.Program
@@ -694,7 +695,7 @@ internal class AstChecker(private val program: Program,
super.visit(array)
if(array.heapId==null)
if(array.heapId==null && array.parent !is IFunctionCall)
throw FatalAstException("array should have been moved to heap at ${array.position}")
}
@@ -831,7 +832,7 @@ internal class AstChecker(private val program: Program,
printWarning("result values of subroutine call are discarded", functionCallStatement.position)
}
if(functionCallStatement.target.nameInSource.last() in setOf("lsl", "lsr", "rol", "ror", "rol2", "ror2", "swap")) {
if(functionCallStatement.target.nameInSource.last() in setOf("lsl", "lsr", "rol", "ror", "rol2", "ror2", "swap", "sort", "reverse")) {
// in-place modification, can't be done on literals
if(functionCallStatement.arglist.any { it !is IdentifierReference && it !is RegisterExpr && it !is ArrayIndexedExpression && it !is DirectMemoryRead }) {
checkResult.add(ExpressionError("can't use that as argument to a in-place modifying function", functionCallStatement.position))
@@ -1207,7 +1208,7 @@ internal class AstChecker(private val program: Program,
private fun checkArrayValues(value: ArrayLiteralValue, type: DataType): Boolean {
if(value.heapId==null) {
// hmm weird, array literal that hasn't been moved to the heap yet?
val array = value.value.map { it.constValue(program)!! }
val array = value.value.mapNotNull { it.constValue(program) }
val correct: Boolean
when(type) {
DataType.ARRAY_UB -> {
@@ -7,7 +7,6 @@ import prog8.ast.Program
import prog8.ast.base.*
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.compiler.HeapValues
import prog8.compiler.target.c64.AssemblyProgram
import prog8.functions.BuiltinFunctions
@@ -68,7 +67,7 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
checkResult.add(NameError("builtin function cannot be redefined", decl.position))
if(decl.name in AssemblyProgram.opcodeNames)
checkResult.add(NameError("can't use a cpu opcode name as a symbol", decl.position))
checkResult.add(NameError("can't use a cpu opcode name as a symbol: '${decl.name}'", decl.position))
// is it a struct variable? then define all its struct members as mangled names,
// and include the original decl as well.
@@ -105,7 +104,7 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
override fun visit(subroutine: Subroutine): Statement {
if(subroutine.name in AssemblyProgram.opcodeNames) {
checkResult.add(NameError("can't use a cpu opcode name as a symbol", subroutine.position))
checkResult.add(NameError("can't use a cpu opcode name as a symbol: '${subroutine.name}'", subroutine.position))
} else if(subroutine.name in BuiltinFunctions) {
// the builtin functions can't be redefined
checkResult.add(NameError("builtin function cannot be redefined", subroutine.position))
@@ -166,7 +165,7 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
override fun visit(label: Label): Statement {
if(label.name in AssemblyProgram.opcodeNames)
checkResult.add(NameError("can't use a cpu opcode name as a symbol", label.position))
checkResult.add(NameError("can't use a cpu opcode name as a symbol: '${label.name}'", label.position))
if(label.name in BuiltinFunctions) {
// the builtin functions can't be redefined
@@ -185,28 +184,11 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
// For loops that loop over an interable variable (instead of a range of numbers) get an
// additional interation count variable in their scope.
if(forLoop.loopRegister!=null) {
if(forLoop.decltype!=null)
checkResult.add(SyntaxError("register loop variables have a fixed implicit datatype", forLoop.position))
if(forLoop.loopRegister == Register.X)
printWarning("writing to the X register is dangerous, because it's used as an internal pointer", forLoop.position)
} else {
val loopVar = forLoop.loopVar
if (loopVar != null) {
val varName = loopVar.nameInSource.last()
if (forLoop.decltype != null) {
val existing = if (forLoop.body.containsNoCodeNorVars()) null else forLoop.body.lookup(loopVar.nameInSource, forLoop.body.statements.first())
if (existing == null) {
// create the local scoped for loop variable itself
val vardecl = VarDecl(VarDeclType.VAR, forLoop.decltype, forLoop.zeropage, null, varName, null, null,
isArray = false, autogeneratedDontRemove = true, position = loopVar.position)
vardecl.linkParents(forLoop.body)
forLoop.body.statements.add(0, vardecl)
loopVar.parent = forLoop.body // loopvar 'is defined in the body'
} else if(existing.parent!==forLoop && existing.parent.parent!==forLoop) {
checkResult.add(NameError("for loop var was already defined at ${existing.position}", loopVar.position))
}
}
val validName = forLoop.body.name.replace("<", "").replace(">", "").replace("-", "")
val loopvarName = "prog8_loopvar_$validName"
if (forLoop.iterable !is RangeExpr) {
@@ -255,8 +237,8 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
if(array is ArrayLiteralValue) {
val vardecl = array.parent as? VarDecl
return if (vardecl!=null) {
fixupArrayDatatype(array, vardecl, program.heap)
} else {
fixupArrayDatatype(array, vardecl, program)
} else if(array.heapId!=null) {
// fix the datatype of the array (also on the heap) to the 'biggest' datatype in the array
// (we don't know the desired datatype here exactly so we guess)
val datatype = determineArrayDt(array.value)
@@ -264,7 +246,8 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
litval2.parent = array.parent
// finally, replace the literal array by a identifier reference.
makeIdentifierFromRefLv(litval2)
}
} else
array
}
return array
}
@@ -384,14 +367,58 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
}
internal fun fixupArrayDatatype(array: ArrayLiteralValue, vardecl: VarDecl, heap: HeapValues): ArrayLiteralValue {
internal fun fixupArrayDatatype(array: ArrayLiteralValue, program: Program): ArrayLiteralValue {
val dts = array.value.map {it.inferType(program).typeOrElse(DataType.STRUCT)}.toSet()
if(dts.any { it !in NumericDatatypes }) {
return array
}
val dt = when {
DataType.FLOAT in dts -> DataType.ARRAY_F
DataType.WORD in dts -> DataType.ARRAY_W
DataType.UWORD in dts -> DataType.ARRAY_UW
DataType.BYTE in dts -> DataType.ARRAY_B
else -> DataType.ARRAY_UB
}
if(dt==array.type)
return array
// convert values and array type
val elementType = ArrayElementTypes.getValue(dt)
val values = array.value.map { (it as NumericLiteralValue).cast(elementType) as Expression}.toTypedArray()
val array2 = ArrayLiteralValue(dt, values, array.heapId, array.position)
array2.linkParents(array.parent)
return array2
}
internal fun fixupArrayDatatype(array: ArrayLiteralValue, vardecl: VarDecl, program: Program): ArrayLiteralValue {
if(array.heapId!=null) {
val arrayDt = array.type
if(arrayDt!=vardecl.datatype) {
// fix the datatype of the array (also on the heap) to match the vardecl
val litval2 =
try {
array.cast(vardecl.datatype)!!
val result = array.cast(vardecl.datatype)
if(result==null) {
val constElements = array.value.mapNotNull { it.constValue(program) }
val elementDts = constElements.map { it.type }
if(DataType.FLOAT in elementDts) {
array.cast(DataType.ARRAY_F) ?: ArrayLiteralValue(DataType.ARRAY_F, array.value, array.heapId, array.position)
} else {
val numbers = constElements.map { it.number.toInt() }
val minValue = numbers.min()!!
val maxValue = numbers.max()!!
if (minValue >= 0) {
// only positive values, so uword or ubyte
val dt = if(maxValue<256) DataType.ARRAY_UB else DataType.ARRAY_UW
array.cast(dt) ?: ArrayLiteralValue(dt, array.value, array.heapId, array.position)
} else {
// negative value present, so word or byte
val dt = if(minValue >= -128 && maxValue<=127) DataType.ARRAY_B else DataType.ARRAY_W
array.cast(dt) ?: ArrayLiteralValue(dt, array.value, array.heapId, array.position)
}
}
}
else result
} catch(x: ExpressionError) {
// couldn't cast permanently.
// instead, simply adjust the array type and trust the AstChecker to report the exact error
@@ -399,11 +426,9 @@ internal fun fixupArrayDatatype(array: ArrayLiteralValue, vardecl: VarDecl, heap
}
vardecl.value = litval2
litval2.linkParents(vardecl)
litval2.addToHeap(heap)
litval2.addToHeap(program.heap)
return litval2
}
} else {
array.addToHeap(heap)
}
return array
}
@@ -1,7 +1,6 @@
package prog8.ast.processing
import prog8.ast.Module
import prog8.ast.Program
import prog8.ast.*
import prog8.ast.base.DataType
import prog8.ast.base.FatalAstException
import prog8.ast.base.initvarsSubName
@@ -64,7 +63,10 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
private val directivesToMove = setOf("%output", "%launcher", "%zeropage", "%zpreserved", "%address", "%option")
private val addReturns = mutableListOf<Pair<INameScope, Int>>()
override fun visit(module: Module) {
addReturns.clear()
super.visit(module)
val (blocks, other) = module.statements.partition { it is Block }
@@ -92,6 +94,13 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
val directives = module.statements.filter {it is Directive && it.directive in directivesToMove}
module.statements.removeAll(directives)
module.statements.addAll(0, directives)
for(pos in addReturns) {
println(pos)
val returnStmt = Return(null, pos.first.position)
returnStmt.linkParents(pos.first as Node)
pos.first.statements.add(pos.second, returnStmt)
}
}
override fun visit(block: Block): Statement {
@@ -161,6 +170,19 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
override fun visit(subroutine: Subroutine): Statement {
super.visit(subroutine)
val scope = subroutine.definingScope()
if(scope is Subroutine) {
for(stmt in scope.statements.withIndex()) {
if(stmt.index>0 && stmt.value===subroutine) {
val precedingStmt = scope.statements[stmt.index-1]
if(precedingStmt !is Jump && precedingStmt !is Subroutine) {
// insert a return statement before a nested subroutine, to avoid falling trough inside the subroutine
addReturns.add(Pair(scope, stmt.index))
}
}
}
}
val varDecls = subroutine.statements.filterIsInstance<VarDecl>()
subroutine.statements.removeAll(varDecls)
subroutine.statements.addAll(0, varDecls)
@@ -649,8 +649,6 @@ class BranchStatement(var condition: BranchCondition,
}
class ForLoop(val loopRegister: Register?,
val decltype: DataType?,
val zeropage: ZeropageWish,
var loopVar: IdentifierReference?,
var iterable: Expression,
var body: AnonymousScope,
@@ -660,7 +658,7 @@ class ForLoop(val loopRegister: Register?,
override fun linkParents(parent: Node) {
this.parent=parent
loopVar?.linkParents(if(decltype==null) this else body)
loopVar?.linkParents(this)
iterable.linkParents(this)
body.linkParents(this)
}
@@ -149,7 +149,7 @@ internal class AsmGen(val program: Program,
}
private fun block2asm(block: Block) {
out("\n; ---- block: '${block.name}' ----")
out("\n\n; ---- block: '${block.name}' ----")
out("${block.name}\t" + (if("force_output" in block.options()) ".block\n" else ".proc\n"))
if(block.address!=null) {
@@ -9,6 +9,8 @@ import prog8.ast.base.WordDatatypes
import prog8.ast.expressions.*
import prog8.ast.statements.AssignTarget
import prog8.ast.statements.FunctionCallStatement
import prog8.compiler.target.c64.MachineDefinition
import prog8.compiler.target.c64.MachineDefinition.C64Zeropage
import prog8.compiler.target.c64.MachineDefinition.ESTACK_HI_HEX
import prog8.compiler.target.c64.MachineDefinition.ESTACK_HI_PLUS1_HEX
import prog8.compiler.target.c64.MachineDefinition.ESTACK_LO_HEX
@@ -298,6 +300,74 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
else -> throw AssemblyError("weird type")
}
}
"sort" -> {
val variable = fcall.arglist.single()
if(variable is IdentifierReference) {
val decl = variable.targetVarDecl(program.namespace)!!
val varName = asmgen.asmIdentifierName(variable)
val numElements = decl.arraysize!!.size()
when(decl.datatype) {
DataType.ARRAY_UB, DataType.ARRAY_B -> {
asmgen.out("""
lda #<$varName
ldy #>$varName
sta ${C64Zeropage.SCRATCH_W1}
sty ${C64Zeropage.SCRATCH_W1+1}
lda #$numElements
sta ${C64Zeropage.SCRATCH_B1}
""")
asmgen.out(if(decl.datatype==DataType.ARRAY_UB) " jsr prog8_lib.sort_ub" else " jsr prog8_lib.sort_b")
}
DataType.ARRAY_UW, DataType.ARRAY_W -> {
asmgen.out("""
lda #<$varName
ldy #>$varName
sta ${C64Zeropage.SCRATCH_W1}
sty ${C64Zeropage.SCRATCH_W1+1}
lda #$numElements
sta ${C64Zeropage.SCRATCH_B1}
""")
asmgen.out(if(decl.datatype==DataType.ARRAY_UW) " jsr prog8_lib.sort_uw" else " jsr prog8_lib.sort_w")
}
DataType.ARRAY_F -> TODO("sort floats (consider another solution if possible - this will be very slow, if ever implemented)")
else -> throw AssemblyError("weird type")
}
}
else
throw AssemblyError("weird type")
}
"reverse" -> {
val variable = fcall.arglist.single()
if (variable is IdentifierReference) {
val decl = variable.targetVarDecl(program.namespace)!!
val varName = asmgen.asmIdentifierName(variable)
val numElements = decl.arraysize!!.size()
when (decl.datatype) {
DataType.ARRAY_UB, DataType.ARRAY_B -> {
asmgen.out("""
lda #<$varName
ldy #>$varName
sta ${C64Zeropage.SCRATCH_W1}
sty ${C64Zeropage.SCRATCH_W1 + 1}
lda #$numElements
jsr prog8_lib.reverse_b
""")
}
DataType.ARRAY_UW, DataType.ARRAY_W -> {
asmgen.out("""
lda #<$varName
ldy #>$varName
sta ${C64Zeropage.SCRATCH_W1}
sty ${C64Zeropage.SCRATCH_W1 + 1}
lda #$numElements
jsr prog8_lib.reverse_w
""")
}
DataType.ARRAY_F -> TODO("reverse floats (consider another solution if possible - this will be quite slow, if ever implemented)")
else -> throw AssemblyError("weird type")
}
}
}
else -> {
translateFunctionArguments(fcall.arglist, func)
asmgen.out(" jsr prog8_lib.func_$functionName")
@@ -21,37 +21,39 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
is NumericLiteralValue -> translateExpression(expression)
is RegisterExpr -> translateExpression(expression)
is IdentifierReference -> translateExpression(expression)
is FunctionCall -> {
val functionName = expression.target.nameInSource.last()
val builtinFunc = BuiltinFunctions[functionName]
if(builtinFunc!=null) {
asmgen.translateFunctioncallExpression(expression, builtinFunc)
} else {
asmgen.translateFunctionCall(expression)
val sub = expression.target.targetSubroutine(program.namespace)!!
val returns = sub.returntypes.zip(sub.asmReturnvaluesRegisters)
for((_, reg) in returns) {
if(!reg.stack) {
// result value in cpu or status registers, put it on the stack
if(reg.registerOrPair!=null) {
when(reg.registerOrPair) {
RegisterOrPair.A -> asmgen.out(" sta ${MachineDefinition.ESTACK_LO_HEX},x | dex")
RegisterOrPair.Y -> asmgen.out(" tya | sta ${MachineDefinition.ESTACK_LO_HEX},x | dex")
RegisterOrPair.AY -> asmgen.out(" sta ${MachineDefinition.ESTACK_LO_HEX},x | tya | sta ${MachineDefinition.ESTACK_HI_HEX},x | dex")
RegisterOrPair.X, RegisterOrPair.AX, RegisterOrPair.XY -> throw AssemblyError("can't push X register - use a variable")
}
}
// return value from a statusregister is not put on the stack, it should be acted on via a conditional branch such as if_cc
}
}
}
}
is FunctionCall -> translateExpression(expression)
is ArrayLiteralValue, is StringLiteralValue -> TODO("string/array/struct assignment?")
is StructLiteralValue -> throw AssemblyError("struct literal value assignment should have been flattened")
is RangeExpr -> throw AssemblyError("range expression should have been changed into array values")
}
}
private fun translateExpression(expression: FunctionCall) {
val functionName = expression.target.nameInSource.last()
val builtinFunc = BuiltinFunctions[functionName]
if (builtinFunc != null) {
asmgen.translateFunctioncallExpression(expression, builtinFunc)
} else {
asmgen.translateFunctionCall(expression)
val sub = expression.target.targetSubroutine(program.namespace)!!
val returns = sub.returntypes.zip(sub.asmReturnvaluesRegisters)
for ((_, reg) in returns) {
if (!reg.stack) {
// result value in cpu or status registers, put it on the stack
if (reg.registerOrPair != null) {
when (reg.registerOrPair) {
RegisterOrPair.A -> asmgen.out(" sta ${MachineDefinition.ESTACK_LO_HEX},x | dex")
RegisterOrPair.Y -> asmgen.out(" tya | sta ${MachineDefinition.ESTACK_LO_HEX},x | dex")
RegisterOrPair.AY -> asmgen.out(" sta ${MachineDefinition.ESTACK_LO_HEX},x | tya | sta ${MachineDefinition.ESTACK_HI_HEX},x | dex")
RegisterOrPair.X, RegisterOrPair.AX, RegisterOrPair.XY -> throw AssemblyError("can't push X register - use a variable")
}
}
// return value from a statusregister is not put on the stack, it should be acted on via a conditional branch such as if_cc
}
}
}
}
private fun translateExpression(expr: TypecastExpression) {
translateExpression(expr.expression)
when(expr.expression.inferType(program).typeOrElse(DataType.STRUCT)) {
@@ -175,7 +177,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
private val optimizedByteMultiplications = setOf(3,5,6,7,9,10,11,12,13,14,15,20,25,40)
private val optimizedWordMultiplications = setOf(3,5,6,7,9,10,12,15,20,25,40)
private val powerOfTwos = setOf(0,1,2,4,8,16,32,64,128,256)
private val powersOfTwo = setOf(0,1,2,4,8,16,32,64,128,256)
private fun translateExpression(expr: BinaryExpression) {
val leftIDt = expr.left.inferType(program)
@@ -215,7 +217,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
if(value!=null) {
if(rightDt in IntegerDatatypes) {
val amount = value.number.toInt()
if(amount in powerOfTwos)
if(amount in powersOfTwo)
printWarning("${expr.right.position} multiplication by power of 2 should have been optimized into a left shift instruction: $amount")
when(rightDt) {
DataType.UBYTE -> {
@@ -312,7 +314,6 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
}
}
private fun translatePushFromArray(arrayExpr: ArrayIndexedExpression) {
// assume *reading* from an array
val index = arrayExpr.arrayspec.index
@@ -27,10 +27,12 @@ val BuiltinFunctions = mapOf(
"ror2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null),
"lsl" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", IntegerDatatypes)), null),
"lsr" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", IntegerDatatypes)), null),
"sort" to FunctionSignature(false, listOf(BuiltinFunctionParam("array", ArrayDatatypes)), null),
"reverse" to FunctionSignature(false, listOf(BuiltinFunctionParam("array", ArrayDatatypes)), null),
// these few have a return value depending on the argument(s):
"max" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, _ -> collectionArgNeverConst(a, p) }, // type depends on args
"min" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, _ -> collectionArgNeverConst(a, p) }, // type depends on args
"sum" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, _ -> collectionArgNeverConst(a, p) }, // type depends on args
"max" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, prg -> collectionArg(a, p, prg, ::builtinMax) }, // type depends on args
"min" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, prg -> collectionArg(a, p, prg, ::builtinMin) }, // type depends on args
"sum" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, prg -> collectionArg(a, p, prg, ::builtinSum) }, // type depends on args
"abs" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", NumericDatatypes)), null, ::builtinAbs), // type depends on argument
"len" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", IterableDatatypes)), null, ::builtinLen), // type is UBYTE or UWORD depending on actual length
// normal functions follow:
@@ -56,8 +58,8 @@ val BuiltinFunctions = mapOf(
"round" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArgOutputWord(a, p, prg, Math::round) },
"floor" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArgOutputWord(a, p, prg, Math::floor) },
"ceil" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArgOutputWord(a, p, prg, Math::ceil) },
"any" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, _ -> collectionArgNeverConst(a, p) },
"all" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, _ -> collectionArgNeverConst(a, p) },
"any" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, prg -> collectionArg(a, p, prg, ::builtinAny) },
"all" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, prg -> collectionArg(a, p, prg, ::builtinAll) },
"lsb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { x: Int -> x and 255 }},
"msb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { x: Int -> x ushr 8 and 255}},
"mkword" to FunctionSignature(true, listOf(
@@ -75,18 +77,20 @@ val BuiltinFunctions = mapOf(
"read_flags" to FunctionSignature(false, emptyList(), DataType.UBYTE),
"swap" to FunctionSignature(false, listOf(BuiltinFunctionParam("first", NumericDatatypes), BuiltinFunctionParam("second", NumericDatatypes)), null),
"memcopy" to FunctionSignature(false, listOf(
BuiltinFunctionParam("from", IterableDatatypes + setOf(DataType.UWORD)),
BuiltinFunctionParam("to", IterableDatatypes + setOf(DataType.UWORD)),
BuiltinFunctionParam("from", IterableDatatypes + DataType.UWORD),
BuiltinFunctionParam("to", IterableDatatypes + DataType.UWORD),
BuiltinFunctionParam("numbytes", setOf(DataType.UBYTE))), null),
"memset" to FunctionSignature(false, listOf(
BuiltinFunctionParam("address", IterableDatatypes + setOf(DataType.UWORD)),
BuiltinFunctionParam("address", IterableDatatypes + DataType.UWORD),
BuiltinFunctionParam("numbytes", setOf(DataType.UWORD)),
BuiltinFunctionParam("bytevalue", ByteDatatypes)), null),
"memsetw" to FunctionSignature(false, listOf(
BuiltinFunctionParam("address", IterableDatatypes + setOf(DataType.UWORD)),
BuiltinFunctionParam("address", IterableDatatypes + DataType.UWORD),
BuiltinFunctionParam("numwords", setOf(DataType.UWORD)),
BuiltinFunctionParam("wordvalue", setOf(DataType.UWORD, DataType.WORD))), null),
"strlen" to FunctionSignature(true, listOf(BuiltinFunctionParam("string", StringDatatypes)), DataType.UBYTE, ::builtinStrlen),
// TODO clean up these vm-specific functions
"vm_write_memchr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", setOf(DataType.UWORD))), null),
"vm_write_memstr" to FunctionSignature(false, listOf(BuiltinFunctionParam("address", setOf(DataType.UWORD))), null),
"vm_write_num" to FunctionSignature(false, listOf(BuiltinFunctionParam("number", NumericDatatypes)), null),
@@ -112,20 +116,30 @@ val BuiltinFunctions = mapOf(
null)
)
fun builtinMax(array: List<Number>): Number = array.maxBy { it.toDouble() }!!
fun builtinMin(array: List<Number>): Number = array.minBy { it.toDouble() }!!
fun builtinSum(array: List<Number>): Number = array.sumByDouble { it.toDouble() }
fun builtinAny(array: List<Number>): Number = if(array.any { it.toDouble()!=0.0 }) 1 else 0
fun builtinAll(array: List<Number>): Number = if(array.all { it.toDouble()!=0.0 }) 1 else 0
fun builtinFunctionReturnType(function: String, args: List<Expression>, program: Program): InferredTypes.InferredType {
fun datatypeFromIterableArg(arglist: Expression): DataType {
if(arglist is ArrayLiteralValue) {
if(arglist.type== DataType.ARRAY_UB || arglist.type== DataType.ARRAY_UW || arglist.type== DataType.ARRAY_F) {
val dt = arglist.value.map {it.inferType(program)}
if(dt.any { !(it istype DataType.UBYTE) && !(it istype DataType.UWORD) && !(it istype DataType.FLOAT)}) {
throw FatalAstException("fuction $function only accepts arraysize of numeric values")
}
if(dt.any { it istype DataType.FLOAT }) return DataType.FLOAT
if(dt.any { it istype DataType.UWORD }) return DataType.UWORD
return DataType.UBYTE
val dt = arglist.value.map {it.inferType(program).typeOrElse(DataType.STRUCT)}.toSet()
if(dt.any { it !in NumericDatatypes }) {
throw FatalAstException("fuction $function only accepts array of numeric values")
}
if(DataType.FLOAT in dt) return DataType.FLOAT
if(DataType.UWORD in dt) return DataType.UWORD
if(DataType.WORD in dt) return DataType.WORD
if(DataType.BYTE in dt) return DataType.BYTE
return DataType.UBYTE
}
if(arglist is IdentifierReference) {
val idt = arglist.inferType(program)
@@ -215,12 +229,16 @@ private fun oneIntArgOutputInt(args: List<Expression>, position: Position, progr
return numericLiteral(function(integer).toInt(), args[0].position)
}
private fun collectionArgNeverConst(args: List<Expression>, position: Position): NumericLiteralValue {
private fun collectionArg(args: List<Expression>, position: Position, program: Program, function: (arg: List<Number>)->Number): NumericLiteralValue {
if(args.size!=1)
throw SyntaxError("builtin function requires one non-scalar argument", position)
// max/min/sum etc only work on arrays and these are never considered to be const for these functions
throw NotConstArgumentException()
val array= args[0] as? ArrayLiteralValue ?: throw NotConstArgumentException()
val constElements = array.value.map{it.constValue(program)?.number}
if(constElements.contains(null))
throw NotConstArgumentException()
return NumericLiteralValue.optimalNumeric(function(constElements.mapNotNull { it }), args[0].position)
}
private fun builtinAbs(args: List<Expression>, position: Position, program: Program): NumericLiteralValue {
@@ -258,6 +276,8 @@ private fun builtinLen(args: List<Expression>, position: Position, program: Prog
var arraySize = directMemVar?.arraysize?.size()
if(arraySize != null)
return NumericLiteralValue.optimalInteger(arraySize, position)
if(args[0] is ArrayLiteralValue)
return NumericLiteralValue.optimalInteger((args[0] as ArrayLiteralValue).value.size, position)
if(args[0] !is IdentifierReference)
throw SyntaxError("len argument should be an identifier, but is ${args[0]}", position)
val target = (args[0] as IdentifierReference).targetVarDecl(program.namespace)!!
@@ -39,9 +39,11 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
if(decl.isArray){
if(decl.arraysize==null) {
// for arrays that have no size specifier (or a non-constant one) attempt to deduce the size
val arrayval = (decl.value as ArrayLiteralValue).value
decl.arraysize = ArrayIndex(NumericLiteralValue.optimalInteger(arrayval.size, decl.position), decl.position)
optimizationsDone++
val arrayval = decl.value as? ArrayLiteralValue
if(arrayval!=null) {
decl.arraysize = ArrayIndex(NumericLiteralValue.optimalInteger(arrayval.value.size, decl.position), decl.position)
optimizationsDone++
}
}
else if(decl.arraysize?.size()==null) {
val size = decl.arraysize!!.index.accept(this)
@@ -165,6 +167,15 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
* replace identifiers that refer to const value, with the value itself (if it's a simple type)
*/
override fun visit(identifier: IdentifierReference): Expression {
// don't replace when it's an assignment target or loop variable
if(identifier.parent is AssignTarget)
return identifier
var forloop = identifier.parent as? ForLoop
if(forloop==null)
forloop = identifier.parent.parent as? ForLoop
if(forloop!=null && identifier===forloop.loopVar)
return identifier
return try {
val cval = identifier.constValue(program) ?: return identifier
return when {
@@ -183,9 +194,9 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
}
override fun visit(functionCall: FunctionCall): Expression {
super.visit(functionCall)
typeCastConstArguments(functionCall)
return try {
super.visit(functionCall)
typeCastConstArguments(functionCall)
functionCall.constValue(program) ?: functionCall
} catch (ax: AstException) {
addError(ax)
@@ -599,9 +610,14 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
override fun visit(arrayLiteral: ArrayLiteralValue): Expression {
val array = super.visit(arrayLiteral)
if(array is ArrayLiteralValue) {
if(array.heapId==null)
array.addToHeap(program.heap)
val vardecl = array.parent as? VarDecl
if (vardecl!=null) {
return fixupArrayDatatype(array, vardecl, program.heap)
return if (vardecl!=null) {
fixupArrayDatatype(array, vardecl, program)
} else {
// it's not an array associated with a vardecl, attempt to guess the data type from the array values
fixupArrayDatatype(array, program)
}
}
return array
@@ -608,8 +608,8 @@ internal class SimplifyExpressions(private val program: Program) : IAstModifying
}
private val powersOfTwo = (1 .. 16).map { (2.0).pow(it) }
private val negativePowersOfTwo = powersOfTwo.map { -it }
private val powersOfTwo = (1 .. 16).map { (2.0).pow(it) }.toSet()
private val negativePowersOfTwo = powersOfTwo.map { -it }.toSet()
private fun optimizeDivision(expr: BinaryExpression, leftVal: NumericLiteralValue?, rightVal: NumericLiteralValue?): Expression {
if(leftVal==null && rightVal==null)
@@ -712,7 +712,7 @@ internal class SimplifyExpressions(private val program: Program) : IAstModifying
optimizationsDone++
return expr.left
}
2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0, 4096.0, 8192.0, 16384.0, 32768.0, 65536.0 -> {
in powersOfTwo -> {
if(leftValue.inferType(program).typeOrElse(DataType.STRUCT) in IntegerDatatypes) {
// times a power of two => shift left
optimizationsDone++
@@ -720,7 +720,7 @@ internal class SimplifyExpressions(private val program: Program) : IAstModifying
return BinaryExpression(expr.left, "<<", NumericLiteralValue.optimalInteger(numshifts, expr.position), expr.position)
}
}
-2.0, -4.0, -8.0, -16.0, -32.0, -64.0, -128.0, -256.0, -512.0, -1024.0, -2048.0, -4096.0, -8192.0, -16384.0, -32768.0, -65536.0 -> {
in negativePowersOfTwo -> {
if(leftValue.inferType(program).typeOrElse(DataType.STRUCT) in IntegerDatatypes) {
// times a negative power of two => negate, then shift left
optimizationsDone++
+1 -1
View File
@@ -158,7 +158,7 @@ Design principles and features
- The compiler tries to optimize the program and generated code, but hand-tuning of the
performance or space-critical parts will likely still be required. This is supported by
the ability to easily write embedded assembly code directly in the program source code.
- There are many built-in functions such as ``sin``, ``cos``, ``rnd``, ``abs``, ``min``, ``max``, ``sqrt``, ``msb``, ``rol``, ``ror``, ``swap``, ``memset``, ``memcopy``
- There are many built-in functions such as ``sin``, ``cos``, ``rnd``, ``abs``, ``min``, ``max``, ``sqrt``, ``msb``, ``rol``, ``ror``, ``swap``, ``memset``, ``memcopy``, ``sort`` and ``reverse``
.. _requirements:
+22 -20
View File
@@ -395,8 +395,7 @@ Loops
-----
The *for*-loop is used to let a variable (or register) iterate over a range of values. Iteration is done in steps of 1, but you can change this.
The loop variable can be declared as byte or word earlier so you can reuse it for multiple occasions,
or you can declare one directly in the for statement which will only be visible in the for loop body.
The loop variable must be declared as byte or word earlier so you can reuse it for multiple occasions.
Iterating with a floating point variable is not supported. If you want to loop over a floating-point array, use a loop with an integer index variable instead.
The *while*-loop is used to repeat a piece of code while a certain condition is still true.
@@ -408,9 +407,6 @@ You can also create loops by using the ``goto`` statement, but this should usual
The value of the loop variable or register after executing the loop *is undefined*. Don't use it immediately
after the loop without first assigning a new value to it!
(this is an optimization issue to avoid having to deal with mostly useless post-loop logic to adjust the loop variable's value)
Loop variables that are declared inline are not different to them being
defined in a separate var declaration in the subroutine, it's just a readability convenience.
(this may change in the future if the compiler gets more advanced with additional sub-scopes)
Conditional Execution
@@ -663,52 +659,58 @@ cos16u(x)
Fast 16-bit uword cosine of angle 0..255, result is in range 0..65535
cos16(x)
Fast 16-bit word cosine of angle 0..255, result is in range -32767..32767
Fast 16-bit word cosine of angle 0..255, result is in range -32767..32767
abs(x)
Absolute value.
Absolute value.
tan(x)
Tangent.
Tangent.
atan(x)
Arctangent.
Arctangent.
ln(x)
Natural logarithm (base e).
Natural logarithm (base e).
log2(x)
Base 2 logarithm.
sqrt16(w)
16 bit unsigned integer Square root. Result is unsigned byte.
16 bit unsigned integer Square root. Result is unsigned byte.
sqrt(x)
Floating point Square root.
Floating point Square root.
round(x)
Rounds the floating point to the closest integer.
Rounds the floating point to the closest integer.
floor (x)
Rounds the floating point down to an integer towards minus infinity.
Rounds the floating point down to an integer towards minus infinity.
ceil(x)
Rounds the floating point up to an integer towards positive infinity.
Rounds the floating point up to an integer towards positive infinity.
rad(x)
Degrees to radians.
Degrees to radians.
deg(x)
Radians to degrees.
Radians to degrees.
max(x)
Maximum of the values in the array value x
Maximum of the values in the array value x
min(x)
Minimum of the values in the array value x
Minimum of the values in the array value x
sum(x)
Sum of the values in the array value x
Sum of the values in the array value x
sort(array)
Sort the array in ascending order (in-place)
reverse(array)
Reverse the values in the array (in-place). Can be used after sort() to sort an array in descending order.
len(x)
Number of values in the array value x, or the number of characters in a string (excluding the size or 0-byte).
+13 -16
View File
@@ -517,42 +517,39 @@ Loops
for loop
^^^^^^^^
The loop variable must be a register or a byte/word variable. It must be defined in the local scope (to reuse
an existing variable), or you can declare it in the for loop directly to make a new one that is only visible
in the body of the for loop.
The loop variable must be a register or a byte/word variable,
and must be defined first in the local scope of the for loop.
The expression that you loop over can be anything that supports iteration (such as ranges like ``0 to 100``,
array variables and strings) *except* floating-point arrays (because a floating-point loop variable is not supported).
You can use a single statement, or a statement block like in the example below::
for [byte | word] <loopvar> in <expression> [ step <amount> ] {
for <loopvar> in <expression> [ step <amount> ] {
; do something...
break ; break out of the loop
continue ; immediately enter next iteration
}
For example, this is a for loop using the existing byte variable ``i`` to loop over a certain range of numbers::
For example, this is a for loop using a byte variable ``i``, defined before, to loop over a certain range of numbers::
ubyte i
...
for i in 20 to 155 {
; do something
}
And this is a loop over the values of the array ``fibonacci_numbers`` where the loop variable is declared in the loop itself::
And this is a loop over the values of the array ``fibonacci_numbers``::
word[] fibonacci_numbers = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
uword[] fibonacci_numbers = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
for word fibnr in fibonacci_numbers {
; do something
uword number
for number in fibonacci_numbers {
; do something with number
}
You can inline the loop variable declaration in the for statement, including optional zp-tag. In this case
the variable is not visible outside of the for loop::
for ubyte @zp fastindex in 10 to 20 {
; do something
}
while loop
^^^^^^^^^^
+7 -11
View File
@@ -5,19 +5,18 @@ TODO
Memory Block Operations integrated in language?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
list,string memory block operations?
array/string memory block operations?
- list operations (whole list, individual element)
operations: set, get, copy (from another list with the same length), shift-N(left,right), rotate-N(left,right)
clear (set whole list to the given value, default 0)
- array operations
copy (from another array with the same length), shift-N(left,right), rotate-N(left,right)
clear (set whole array to the given value, default 0)
- list operations ofcourse work identical on vars and on memory mapped vars of these types.
- array operations ofcourse work identical on vars and on memory mapped vars of these types.
- strings: identical operations as on lists.
- strings: identical operations as on array.
these should call optimized pieces of assembly code, so they run as fast as possible
For now, we have the ``memcopy`` and ``memset`` builtin functions.
For now, we have the ``memcopy``, ``memset`` and ``strlen`` builtin functions.
More optimizations
^^^^^^^^^^^^^^^^^^
@@ -48,9 +47,6 @@ without having to to index into the stack?
Misc
^^^^
Add sort() function that can sort an array (ascending and descending)
Several ideas were discussed on my reddit post
https://www.reddit.com/r/programming/comments/alhj59/creating_a_programming_language_and_cross/
+4 -2
View File
@@ -17,7 +17,8 @@ sub start() {
c64.CLEARSCR()
while(true) {
for uword note in notes {
uword note
for note in notes {
ubyte note1 = lsb(note)
ubyte note2 = msb(note)
c64.FREQ1 = music_freq_table[note1] ; set lo+hi freq of voice 1
@@ -35,7 +36,8 @@ sub start() {
}
sub delay() {
for ubyte d in 0 to 12 {
ubyte d
for d in 0 to 12 {
while(c64.RASTER!=0) {
; tempo delay synced to screen refresh
}
+2 -1
View File
@@ -55,7 +55,8 @@ main {
float Azy = cosb*sinc
float Azz = cosb*cosc
for ubyte i in 0 to len(xcoor)-1 {
ubyte i
for i in 0 to len(xcoor)-1 {
rotatedx[i] = Axx*xcoor[i] + Axy*ycoor[i] + Axz*zcoor[i]
rotatedy[i] = Ayx*xcoor[i] + Ayy*ycoor[i] + Ayz*zcoor[i]
rotatedz[i] = Azx*xcoor[i] + Azy*ycoor[i] + Azz*zcoor[i]
+7 -7
View File
@@ -1,8 +1,6 @@
%import c64lib
%import c64utils
; TODO: some optimizer breaks this.. runs fine without optimization
spritedata $2000 {
; this memory block contains the sprite data
; it must start on an address aligned to 64 bytes.
@@ -122,7 +120,8 @@ main {
word Azy = wcosb*wsinc / 128
word Azz = wcosb*wcosc / 128
for ubyte i in 0 to len(xcoor)-1 {
ubyte i
for i in 0 to len(xcoor)-1 {
; don't normalize by dividing by 128, instead keep some precision for perspective calc later
rotatedx[i] = (Axx*xcoor[i] + Axy*ycoor[i] + Axz*zcoor[i])
rotatedy[i] = (Ayx*xcoor[i] + Ayy*ycoor[i] + Ayz*zcoor[i])
@@ -137,9 +136,10 @@ main {
; first sort vertices to sprite order so the back/front order is correct as well
; (simple bubble sort as it's only 8 items to sort)
; TODO make a builtin function sort()
for ubyte sorti in 6 to 0 step -1 {
for ubyte i1 in 0 to sorti {
ubyte i
ubyte i1
for i in 6 to 0 step -1 {
for i1 in 0 to i {
ubyte i2 = i1+1
if(rotatedz[i1] > rotatedz[i2]) {
swap(rotatedx[i1], rotatedx[i2])
@@ -151,7 +151,7 @@ main {
ubyte[] spritecolors = [1,1,7,15,12,11,9,9]
for ubyte i in 0 to 7 {
for i in 0 to 7 {
word zc = rotatedz[i]
word persp = 300+zc/256
ubyte sx = rotatedx[i] / persp + width/2 as ubyte + 20
+2 -2
View File
@@ -61,7 +61,8 @@ main {
word Azy = wcosb*wsinc / 128
word Azz = wcosb*wcosc / 128
for ubyte i in 0 to len(xcoor)-1 {
ubyte i
for i in 0 to len(xcoor)-1 {
; don't normalize by dividing by 128, instead keep some precision for perspective calc later
rotatedx[i] = (Axx*xcoor[i] + Axy*ycoor[i] + Axz*zcoor[i])
rotatedy[i] = (Ayx*xcoor[i] + Ayy*ycoor[i] + Ayz*zcoor[i])
@@ -79,7 +80,6 @@ main {
word persp
byte sx
byte sy
ubyte color
for i in 0 to len(xcoor)-1 {
rz = rotatedz[i]
+4 -3
View File
@@ -17,13 +17,14 @@ main {
; use iteration to write text
str question = "How are you?\n"
for ubyte char in question
ubyte char
for char in question
c64.CHROUT(char)
; use indexed loop to write characters
str bye = "Goodbye!\n"
for ubyte c in 0 to len(bye)
c64.CHROUT(bye[c])
for char in 0 to len(bye)
c64.CHROUT(bye[char])
float clock_seconds = ((mkword(c64.TIME_LO, c64.TIME_MID) as float) + (c64.TIME_HI as float)*65536.0) / 60
+5 -2
View File
@@ -16,10 +16,13 @@ main {
c64.TIME_MID=0
c64.TIME_LO=0
for ubyte pixely in 0 to height-1 {
ubyte pixelx
ubyte pixely
for pixely in 0 to height-1 {
float yy = (pixely as float)/0.4/height - 1.0
for ubyte pixelx in 0 to width-1 {
for pixelx in 0 to width-1 {
float xx = (pixelx as float)/0.3/width - 2.2
float xsquared = 0.0
+2 -1
View File
@@ -10,6 +10,7 @@ main {
str name = "????????????????????????????????????????"
str input = "??????????"
ubyte secretnumber = rnd() % 99 + 1 ; random number 1..100
ubyte attempts_left
c64.VMCSB |= 2 ; switch lowercase chars
c64scr.print("Please introduce yourself: ")
@@ -18,7 +19,7 @@ main {
c64scr.print(name)
c64scr.print(".\nLet's play a number guessing game.\nI am thinking of a number from 1 to 100!You'll have to guess it!\n")
for ubyte attempts_left in 10 to 1 step -1 {
for attempts_left in 10 to 1 step -1 {
c64scr.print("\nYou have ")
c64scr.print_ub(attempts_left)
+66
View File
@@ -0,0 +1,66 @@
%import c64lib
%import c64utils
%zeropage basicsafe
main {
sub start() {
ubyte[] uba = [10,0,2,8,5,4,3,9]
uword[] uwa = [1000,0,200,8000,50,40000,3,900]
byte[] ba = [-10,0,-2,8,5,4,-3,9,-99]
word[] wa = [-1000,0,-200,8000,50,31111,3,-900]
c64scr.print("original\n")
print_arrays()
sort(uba)
sort(uwa)
sort(ba)
sort(wa)
c64scr.print("sorted\n")
print_arrays()
reverse(uba)
reverse(uwa)
reverse(ba)
reverse(wa)
c64scr.print("reversed\n")
print_arrays()
return
sub print_arrays() {
ubyte ub
uword uw
byte bb
word ww
for ub in uba {
c64scr.print_ub(ub)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for uw in uwa {
c64scr.print_uw(uw)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for bb in ba {
c64scr.print_b(bb)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for ww in wa {
c64scr.print_w(ww)
c64.CHROUT(',')
}
c64.CHROUT('\n')
c64.CHROUT('\n')
}
}
}
+4 -2
View File
@@ -40,7 +40,8 @@ main {
c64scr.print("balloon sprites!\n...we are all floating...\n")
for ubyte i in 0 to 7 {
ubyte @zp i
for i in 0 to 7 {
c64.SPRPTR[i] = $0a00 / 64
c64.SPXY[i*2] = 50+25*i
c64.SPXY[i*2+1] = rnd()
@@ -58,7 +59,8 @@ irq {
c64.EXTCOL--
; float up & wobble horizontally
for ubyte @zp i in 0 to 14 step 2 {
ubyte @zp i
for i in 0 to 14 step 2 {
c64.SPXY[i+1]--
ubyte @zp r = rnd()
if r>200
+16 -9
View File
@@ -9,7 +9,6 @@
;
; @todo show ghost?
main {
const ubyte boardOffsetX = 14
@@ -195,7 +194,8 @@ waitkey:
if blocklogic.isLineFull(linepos) {
complete_lines[num_lines]=linepos
num_lines++
for ubyte x in boardOffsetX to boardOffsetX+boardWidth-1
ubyte x
for x in boardOffsetX to boardOffsetX+boardWidth-1
c64scr.setcc(x, linepos, 160, 1)
}
}
@@ -330,7 +330,8 @@ waitkey:
ubyte[] colors = [6,8,7,5,4]
for i in len(colors)-1 to 0 step -1 {
for ubyte x in 5 to 0 step -1 {
ubyte x
for x in 5 to 0 step -1 {
c64scr.setcc(6+x-i, 11+2*i, 102, colors[i])
}
}
@@ -350,7 +351,8 @@ waitkey:
sub drawNextBlock() {
const ubyte nextBlockXpos = 29
const ubyte nextBlockYpos = 5
for ubyte x in nextBlockXpos+3 to nextBlockXpos step -1 {
ubyte x
for x in nextBlockXpos+3 to nextBlockXpos step -1 {
c64scr.setcc(x, nextBlockYpos, ' ', 0)
c64scr.setcc(x, nextBlockYpos+1, ' ', 0)
}
@@ -365,7 +367,8 @@ waitkey:
sub drawHoldBlock() {
const ubyte holdBlockXpos = 7
const ubyte holdBlockYpos = 6
for ubyte x in holdBlockXpos+3 to holdBlockXpos step -1 {
ubyte x
for x in holdBlockXpos+3 to holdBlockXpos step -1 {
c64scr.setcc(x, holdBlockYpos, '@', 0)
c64scr.setcc(x, holdBlockYpos+1, '@', 0)
}
@@ -379,7 +382,8 @@ waitkey:
}
sub drawBlock(ubyte x, ubyte y, ubyte character) {
for ubyte i in 15 to 0 step -1 {
ubyte i
for i in 15 to 0 step -1 {
ubyte c=blocklogic.currentBlock[i]
if c
c64scr.setcc((i&3)+x, (i/4)+y, character, c)
@@ -527,7 +531,8 @@ blocklogic {
}
sub noCollision(ubyte xpos, ubyte ypos) -> ubyte {
for ubyte i in 15 to 0 step -1 {
ubyte i
for i in 15 to 0 step -1 {
if currentBlock[i] and c64scr.getchr(xpos + (i&3), ypos+i/4)!=32
return false
}
@@ -542,7 +547,8 @@ blocklogic {
}
sub isLineFull(ubyte ypos) -> ubyte {
for ubyte x in main.boardOffsetX to main.boardOffsetX+main.boardWidth-1 {
ubyte x
for x in main.boardOffsetX to main.boardOffsetX+main.boardWidth-1 {
if c64scr.getchr(x, ypos)==32
return false
}
@@ -551,7 +557,8 @@ blocklogic {
sub collapse(ubyte ypos) {
while(ypos>main.startYpos+1) {
for ubyte x in main.boardOffsetX+main.boardWidth-1 to main.boardOffsetX step -1 {
ubyte x
for x in main.boardOffsetX+main.boardWidth-1 to main.boardOffsetX step -1 {
ubyte char = c64scr.getchr(x, ypos-1)
ubyte color = c64scr.getclr(x, ypos-1)
c64scr.setcc(x, ypos, char, color)
+11 -71
View File
@@ -1,83 +1,23 @@
%import c64lib
%import c64utils
%import c64flt
%zeropage dontuse
%zeropage basicsafe
main {
sub start() {
byte ub = 100
byte ub2
word uw = 22222
word uw2
ub = -100
c64scr.print_b(ub >> 1)
c64.CHROUT('\n')
c64scr.print_b(ub >> 2)
c64.CHROUT('\n')
c64scr.print_b(ub >> 7)
c64.CHROUT('\n')
c64scr.print_b(ub >> 8)
c64.CHROUT('\n')
c64scr.print_b(ub >> 9)
c64.CHROUT('\n')
c64scr.print_b(ub >> 16)
c64.CHROUT('\n')
c64scr.print_b(ub >> 26)
c64.CHROUT('\n')
c64.CHROUT('\n')
const ubyte i = 33
ub = 100
c64scr.print_b(ub >> 1)
c64.CHROUT('\n')
c64scr.print_b(ub >> 2)
c64.CHROUT('\n')
c64scr.print_b(ub >> 7)
c64.CHROUT('\n')
c64scr.print_b(ub >> 8)
c64.CHROUT('\n')
c64scr.print_b(ub >> 9)
c64.CHROUT('\n')
c64scr.print_b(ub >> 16)
c64.CHROUT('\n')
c64scr.print_b(ub >> 26)
c64.CHROUT('\n')
c64.CHROUT('\n')
i=33
i++
const ubyte q=33
for q in [1,3,5,99] {
A=i
}
uw = -22222
c64scr.print_w(uw >> 1)
c64.CHROUT('\n')
c64scr.print_w(uw >> 7)
c64.CHROUT('\n')
c64scr.print_w(uw >> 8)
c64.CHROUT('\n')
c64scr.print_w(uw >> 9)
c64.CHROUT('\n')
c64scr.print_w(uw >> 15)
c64.CHROUT('\n')
c64scr.print_w(uw >> 16)
c64.CHROUT('\n')
c64scr.print_w(uw >> 26)
c64.CHROUT('\n')
c64.CHROUT('\n')
uw = 22222
c64scr.print_w(uw >> 1)
c64.CHROUT('\n')
c64scr.print_w(uw >> 7)
c64.CHROUT('\n')
c64scr.print_w(uw >> 8)
c64.CHROUT('\n')
c64scr.print_w(uw >> 9)
c64.CHROUT('\n')
c64scr.print_w(uw >> 15)
c64.CHROUT('\n')
c64scr.print_w(uw >> 16)
c64.CHROUT('\n')
c64scr.print_w(uw >> 26)
c64.CHROUT('\n')
while q<10 {
q++
}
}
}
-6
View File
@@ -2,10 +2,6 @@
%zeropage basicsafe
%option enable_floats
; TODO complete codegeneration for all lines in this
main {
sub start() {
@@ -34,8 +30,6 @@ main {
float fl
; read array
@($d020) = ub
A=s1[2]
ub=s1[2]
ub=s2[2]
+28 -25
View File
@@ -54,81 +54,84 @@ main {
c64.CHROUT('\n')
c64.CHROUT('\n')
for ubyte cc in "hello" {
ubyte cc
for cc in "hello" {
c64scr.print_ub(cc)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for ubyte cc2 in [1,3,5,99] {
c64scr.print_ub(cc2)
for cc in [1,3,5,99] {
c64scr.print_ub(cc)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for ubyte cc3 in 10 to 20 {
c64scr.print_ub(cc3)
for cc in 10 to 20 {
c64scr.print_ub(cc)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for ubyte cc4 in 20 to 10 step -1 {
c64scr.print_ub(cc4)
for cc in 20 to 10 step -1 {
c64scr.print_ub(cc)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for ubyte cc5 in 10 to 21 step 3 {
c64scr.print_ub(cc5)
for cc in 10 to 21 step 3 {
c64scr.print_ub(cc)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for ubyte cc6 in 24 to 10 step -3 {
c64scr.print_ub(cc6)
for cc in 24 to 10 step -3 {
c64scr.print_ub(cc)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for ubyte cc7 in barr {
c64scr.print_ub(cc7)
for cc in barr {
c64scr.print_ub(cc)
c64.CHROUT(',')
}
c64.CHROUT('\n')
c64.CHROUT('\n')
for uword ww1 in [1111, 2222, 3333] {
c64scr.print_uw(ww1)
uword uw
for uw in [1111, 2222, 3333] {
c64scr.print_uw(uw)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for word ww2 in warr {
c64scr.print_w(ww2)
word ww
for ww in warr {
c64scr.print_w(ww)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for uword ww3 in 1111 to 1117 {
c64scr.print_uw(ww3)
for uw in 1111 to 1117 {
c64scr.print_uw(uw)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for uword ww3b in 2000 to 1995 step -1 {
c64scr.print_uw(ww3b)
for uw in 2000 to 1995 step -1 {
c64scr.print_uw(uw)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for uword ww3c in 1111 to 50000 step 4444 {
c64scr.print_uw(ww3c)
for uw in 1111 to 50000 step 4444 {
c64scr.print_uw(uw)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for word ww4 in 999 to -999 step -500 {
c64scr.print_w(ww4)
for ww in 999 to -999 step -500 {
c64scr.print_w(ww)
c64.CHROUT(',')
}
c64.CHROUT('\n')
+8 -6
View File
@@ -34,8 +34,8 @@ spritedata $0a00 {
main {
sub start() {
for ubyte i in 0 to 7 {
ubyte i
for i in 0 to 7 {
c64.SPRPTR[i] = $0a00/64
}
c64.SPENA = 255 ; enable all sprites
@@ -48,16 +48,18 @@ irq {
sub irq() {
ubyte angle ; no initialization value so it keeps the previous one.
ubyte @zp spri
c64.EXTCOL--
angle++
c64.MSIGX=0
for ubyte @zp i in 7 to 0 step -1 {
uword @zp x = sin8u(angle*2-i*16) as uword + 50
ubyte @zp y = cos8u(angle*3-i*16) / 2 + 70
c64.SPXYW[i] = mkword(lsb(x), y)
for spri in 7 to 0 step -1 {
uword @zp x = sin8u(angle*2-spri*16) as uword + 50
ubyte @zp y = cos8u(angle*3-spri*16) / 2 + 70
c64.SPXYW[spri] = mkword(lsb(x), y)
lsl(c64.MSIGX)
if msb(x) c64.MSIGX++
c64.EXTCOL++
+1 -1
View File
@@ -285,7 +285,7 @@ branch_stmt : branchcondition EOL? (statement | statement_block) EOL? else_part?
branchcondition: 'if_cs' | 'if_cc' | 'if_eq' | 'if_z' | 'if_ne' | 'if_nz' | 'if_pl' | 'if_pos' | 'if_mi' | 'if_neg' | 'if_vs' | 'if_vc' ;
forloop : 'for' datatype? ZEROPAGE? (register | identifier) 'in' expression EOL? (statement | statement_block) ;
forloop : 'for' (register | identifier) 'in' expression EOL? (statement | statement_block) ;
whileloop: 'while' expression EOL? (statement | statement_block) ;
+290 -318
View File
@@ -4586,10 +4586,6 @@ public class prog8Parser extends Parser {
public Statement_blockContext statement_block() {
return getRuleContext(Statement_blockContext.class,0);
}
public DatatypeContext datatype() {
return getRuleContext(DatatypeContext.class,0);
}
public TerminalNode ZEROPAGE() { return getToken(prog8Parser.ZEROPAGE, 0); }
public TerminalNode EOL() { return getToken(prog8Parser.EOL, 0); }
public ForloopContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
@@ -4606,61 +4602,41 @@ public class prog8Parser extends Parser {
{
setState(715);
match(T__104);
setState(717);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__18) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24))) != 0)) {
{
setState(716);
datatype();
}
}
setState(720);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==ZEROPAGE) {
{
setState(719);
match(ZEROPAGE);
}
}
setState(724);
setState(718);
_errHandler.sync(this);
switch (_input.LA(1)) {
case T__71:
case T__72:
case T__73:
{
setState(722);
setState(716);
register();
}
break;
case NAME:
{
setState(723);
setState(717);
identifier();
}
break;
default:
throw new NoViableAltException(this);
}
setState(726);
setState(720);
match(T__105);
setState(727);
setState(721);
expression(0);
setState(729);
setState(723);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==EOL) {
{
setState(728);
setState(722);
match(EOL);
}
}
setState(733);
setState(727);
_errHandler.sync(this);
switch (_input.LA(1)) {
case T__1:
@@ -4713,13 +4689,13 @@ public class prog8Parser extends Parser {
case NAME:
case ADDRESS_OF:
{
setState(731);
setState(725);
statement();
}
break;
case T__16:
{
setState(732);
setState(726);
statement_block();
}
break;
@@ -4763,21 +4739,21 @@ public class prog8Parser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(735);
setState(729);
match(T__106);
setState(736);
setState(730);
expression(0);
setState(738);
setState(732);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==EOL) {
{
setState(737);
setState(731);
match(EOL);
}
}
setState(742);
setState(736);
_errHandler.sync(this);
switch (_input.LA(1)) {
case T__1:
@@ -4830,13 +4806,13 @@ public class prog8Parser extends Parser {
case NAME:
case ADDRESS_OF:
{
setState(740);
setState(734);
statement();
}
break;
case T__16:
{
setState(741);
setState(735);
statement_block();
}
break;
@@ -4880,9 +4856,9 @@ public class prog8Parser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(744);
setState(738);
match(T__107);
setState(747);
setState(741);
_errHandler.sync(this);
switch (_input.LA(1)) {
case T__1:
@@ -4935,32 +4911,32 @@ public class prog8Parser extends Parser {
case NAME:
case ADDRESS_OF:
{
setState(745);
setState(739);
statement();
}
break;
case T__16:
{
setState(746);
setState(740);
statement_block();
}
break;
default:
throw new NoViableAltException(this);
}
setState(750);
setState(744);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==EOL) {
{
setState(749);
setState(743);
match(EOL);
}
}
setState(752);
setState(746);
match(T__108);
setState(753);
setState(747);
expression(0);
}
}
@@ -5002,20 +4978,20 @@ public class prog8Parser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(755);
setState(749);
match(T__109);
setState(756);
setState(750);
expression(0);
setState(757);
setState(751);
match(T__16);
setState(758);
setState(752);
match(EOL);
setState(763);
setState(757);
_errHandler.sync(this);
_la = _input.LA(1);
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__25) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__62))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (T__63 - 64)) | (1L << (T__66 - 64)) | (1L << (T__71 - 64)) | (1L << (T__72 - 64)) | (1L << (T__73 - 64)) | (1L << (T__82 - 64)) | (1L << (T__83 - 64)) | (1L << (T__91 - 64)) | (1L << (EOL - 64)) | (1L << (NAME - 64)) | (1L << (DEC_INTEGER - 64)) | (1L << (HEX_INTEGER - 64)) | (1L << (BIN_INTEGER - 64)) | (1L << (ADDRESS_OF - 64)) | (1L << (FLOAT_NUMBER - 64)) | (1L << (STRING - 64)) | (1L << (SINGLECHAR - 64)))) != 0)) {
{
setState(761);
setState(755);
_errHandler.sync(this);
switch (_input.LA(1)) {
case T__16:
@@ -5041,13 +5017,13 @@ public class prog8Parser extends Parser {
case STRING:
case SINGLECHAR:
{
setState(759);
setState(753);
when_choice();
}
break;
case EOL:
{
setState(760);
setState(754);
match(EOL);
}
break;
@@ -5055,18 +5031,18 @@ public class prog8Parser extends Parser {
throw new NoViableAltException(this);
}
}
setState(765);
setState(759);
_errHandler.sync(this);
_la = _input.LA(1);
}
setState(766);
setState(760);
match(T__17);
setState(768);
setState(762);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,101,_ctx) ) {
switch ( getInterpreter().adaptivePredict(_input,99,_ctx) ) {
case 1:
{
setState(767);
setState(761);
match(EOL);
}
break;
@@ -5106,7 +5082,7 @@ public class prog8Parser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
setState(772);
setState(766);
_errHandler.sync(this);
switch (_input.LA(1)) {
case T__16:
@@ -5131,22 +5107,22 @@ public class prog8Parser extends Parser {
case STRING:
case SINGLECHAR:
{
setState(770);
setState(764);
expression_list();
}
break;
case T__91:
{
setState(771);
setState(765);
match(T__91);
}
break;
default:
throw new NoViableAltException(this);
}
setState(774);
setState(768);
match(T__86);
setState(777);
setState(771);
_errHandler.sync(this);
switch (_input.LA(1)) {
case T__1:
@@ -5199,13 +5175,13 @@ public class prog8Parser extends Parser {
case NAME:
case ADDRESS_OF:
{
setState(775);
setState(769);
statement();
}
break;
case T__16:
{
setState(776);
setState(770);
statement_block();
}
break;
@@ -5267,7 +5243,7 @@ public class prog8Parser extends Parser {
}
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\177\u030e\4\2\t\2"+
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\177\u0308\4\2\t\2"+
"\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
@@ -5319,252 +5295,249 @@ public class prog8Parser extends Parser {
"\5<\u0296\n<\3<\7<\u0299\n<\f<\16<\u029c\13<\3=\3=\3=\3=\3=\5=\u02a3\n"+
"=\3>\3>\3>\5>\u02a8\n>\3>\3>\5>\u02ac\n>\3>\5>\u02af\n>\3>\5>\u02b2\n"+
">\3?\3?\5?\u02b6\n?\3?\3?\5?\u02ba\n?\3@\3@\5@\u02be\n@\3@\3@\5@\u02c2"+
"\n@\3@\5@\u02c5\n@\3@\5@\u02c8\n@\3@\3@\3A\3A\3B\3B\5B\u02d0\nB\3B\5B"+
"\u02d3\nB\3B\3B\5B\u02d7\nB\3B\3B\3B\5B\u02dc\nB\3B\3B\5B\u02e0\nB\3C"+
"\3C\3C\5C\u02e5\nC\3C\3C\5C\u02e9\nC\3D\3D\3D\5D\u02ee\nD\3D\5D\u02f1"+
"\nD\3D\3D\3D\3E\3E\3E\3E\3E\3E\7E\u02fc\nE\fE\16E\u02ff\13E\3E\3E\5E\u0303"+
"\nE\3F\3F\5F\u0307\nF\3F\3F\3F\5F\u030c\nF\3F\2\3,G\2\4\6\b\n\f\16\20"+
"\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNPRTVXZ\\^`bdfhj"+
"lnprtvxz|~\u0080\u0082\u0084\u0086\u0088\u008a\2\22\3\2\5\16\3\2\25\33"+
"\3\2\36(\3\2)*\3\2+-\3\2/\61\3\2+,\3\2\62\63\3\2\64\67\3\289\3\2JL\3\2"+
"JO\3\2PS\3\2vx\3\2UV\3\2_j\2\u0367\2\u0090\3\2\2\2\4\u0097\3\2\2\2\6\u0099"+
"\3\2\2\2\b\u00ba\3\2\2\2\n\u00bc\3\2\2\2\f\u00bf\3\2\2\2\16\u00c4\3\2"+
"\2\2\20\u00d5\3\2\2\2\22\u00d7\3\2\2\2\24\u00e1\3\2\2\2\26\u00e4\3\2\2"+
"\2\30\u00e8\3\2\2\2\32\u00ec\3\2\2\2\34\u00ef\3\2\2\2\36\u00f2\3\2\2\2"+
" \u0104\3\2\2\2\"\u0106\3\2\2\2$\u010a\3\2\2\2&\u010e\3\2\2\2(\u0116\3"+
"\2\2\2*\u0118\3\2\2\2,\u012b\3\2\2\2.\u01a7\3\2\2\2\60\u01aa\3\2\2\2\62"+
"\u01ad\3\2\2\2\64\u01b2\3\2\2\2\66\u01b5\3\2\2\28\u01bc\3\2\2\2:\u01c3"+
"\3\2\2\2<\u01ce\3\2\2\2>\u01d2\3\2\2\2@\u01d4\3\2\2\2B\u01d6\3\2\2\2D"+
"\u01d8\3\2\2\2F\u01e0\3\2\2\2H\u01e2\3\2\2\2J\u01e4\3\2\2\2L\u01e6\3\2"+
"\2\2N\u01ea\3\2\2\2P\u01ec\3\2\2\2R\u01ee\3\2\2\2T\u0202\3\2\2\2V\u0216"+
"\3\2\2\2X\u0218\3\2\2\2Z\u021a\3\2\2\2\\\u0223\3\2\2\2^\u0225\3\2\2\2"+
"`\u0228\3\2\2\2b\u0235\3\2\2\2d\u0238\3\2\2\2f\u0243\3\2\2\2h\u024e\3"+
"\2\2\2j\u0259\3\2\2\2l\u026d\3\2\2\2n\u0270\3\2\2\2p\u027b\3\2\2\2r\u0282"+
"\3\2\2\2t\u0289\3\2\2\2v\u0291\3\2\2\2x\u029d\3\2\2\2z\u02a4\3\2\2\2|"+
"\u02b3\3\2\2\2~\u02bb\3\2\2\2\u0080\u02cb\3\2\2\2\u0082\u02cd\3\2\2\2"+
"\u0084\u02e1\3\2\2\2\u0086\u02ea\3\2\2\2\u0088\u02f5\3\2\2\2\u008a\u0306"+
"\3\2\2\2\u008c\u008f\5\4\3\2\u008d\u008f\7t\2\2\u008e\u008c\3\2\2\2\u008e"+
"\u008d\3\2\2\2\u008f\u0092\3\2\2\2\u0090\u008e\3\2\2\2\u0090\u0091\3\2"+
"\2\2\u0091\u0093\3\2\2\2\u0092\u0090\3\2\2\2\u0093\u0094\7\2\2\3\u0094"+
"\3\3\2\2\2\u0095\u0098\5\16\b\2\u0096\u0098\5\6\4\2\u0097\u0095\3\2\2"+
"\2\u0097\u0096\3\2\2\2\u0098\5\3\2\2\2\u0099\u009b\5B\"\2\u009a\u009c"+
"\5L\'\2\u009b\u009a\3\2\2\2\u009b\u009c\3\2\2\2\u009c\u009d\3\2\2\2\u009d"+
"\u009e\5d\63\2\u009e\u009f\7t\2\2\u009f\7\3\2\2\2\u00a0\u00bb\5\16\b\2"+
"\u00a1\u00bb\5\26\f\2\u00a2\u00bb\5\30\r\2\u00a3\u00bb\5\22\n\2\u00a4"+
"\u00bb\5\24\13\2\u00a5\u00bb\5\32\16\2\u00a6\u00bb\5\34\17\2\u00a7\u00bb"+
"\5\36\20\2\u00a8\u00bb\5$\23\2\u00a9\u00bb\5&\24\2\u00aa\u00bb\5\f\7\2"+
"\u00ab\u00bb\5*\26\2\u00ac\u00bb\58\35\2\u00ad\u00bb\5z>\2\u00ae\u00bb"+
"\5~@\2\u00af\u00bb\5`\61\2\u00b0\u00bb\5j\66\2\u00b1\u00bb\5^\60\2\u00b2"+
"\u00bb\5<\37\2\u00b3\u00bb\5\u0082B\2\u00b4\u00bb\5\u0084C\2\u00b5\u00bb"+
"\5\u0086D\2\u00b6\u00bb\5\u0088E\2\u00b7\u00bb\5> \2\u00b8\u00bb\5@!\2"+
"\u00b9\u00bb\5\n\6\2\u00ba\u00a0\3\2\2\2\u00ba\u00a1\3\2\2\2\u00ba\u00a2"+
"\3\2\2\2\u00ba\u00a3\3\2\2\2\u00ba\u00a4\3\2\2\2\u00ba\u00a5\3\2\2\2\u00ba"+
"\u00a6\3\2\2\2\u00ba\u00a7\3\2\2\2\u00ba\u00a8\3\2\2\2\u00ba\u00a9\3\2"+
"\2\2\u00ba\u00aa\3\2\2\2\u00ba\u00ab\3\2\2\2\u00ba\u00ac\3\2\2\2\u00ba"+
"\u00ad\3\2\2\2\u00ba\u00ae\3\2\2\2\u00ba\u00af\3\2\2\2\u00ba\u00b0\3\2"+
"\2\2\u00ba\u00b1\3\2\2\2\u00ba\u00b2\3\2\2\2\u00ba\u00b3\3\2\2\2\u00ba"+
"\u00b4\3\2\2\2\u00ba\u00b5\3\2\2\2\u00ba\u00b6\3\2\2\2\u00ba\u00b7\3\2"+
"\2\2\u00ba\u00b8\3\2\2\2\u00ba\u00b9\3\2\2\2\u00bb\t\3\2\2\2\u00bc\u00bd"+
"\5B\"\2\u00bd\u00be\7\3\2\2\u00be\13\3\2\2\2\u00bf\u00c2\7\4\2\2\u00c0"+
"\u00c3\5L\'\2\u00c1\u00c3\5D#\2\u00c2\u00c0\3\2\2\2\u00c2\u00c1\3\2\2"+
"\2\u00c3\r\3\2\2\2\u00c4\u00d0\t\2\2\2\u00c5\u00c7\5\20\t\2\u00c6\u00c5"+
"\3\2\2\2\u00c6\u00c7\3\2\2\2\u00c7\u00d1\3\2\2\2\u00c8\u00cd\5\20\t\2"+
"\u00c9\u00ca\7\17\2\2\u00ca\u00cc\5\20\t\2\u00cb\u00c9\3\2\2\2\u00cc\u00cf"+
"\3\2\2\2\u00cd\u00cb\3\2\2\2\u00cd\u00ce\3\2\2\2\u00ce\u00d1\3\2\2\2\u00cf"+
"\u00cd\3\2\2\2\u00d0\u00c6\3\2\2\2\u00d0\u00c8\3\2\2\2\u00d1\17\3\2\2"+
"\2\u00d2\u00d6\5V,\2\u00d3\u00d6\5B\"\2\u00d4\u00d6\5L\'\2\u00d5\u00d2"+
"\3\2\2\2\u00d5\u00d3\3\2\2\2\u00d5\u00d4\3\2\2\2\u00d6\21\3\2\2\2\u00d7"+
"\u00d9\5 \21\2\u00d8\u00da\7~\2\2\u00d9\u00d8\3\2\2\2\u00d9\u00da\3\2"+
"\2\2\u00da\u00dd\3\2\2\2\u00db\u00de\5\"\22\2\u00dc\u00de\7\177\2\2\u00dd"+
"\u00db\3\2\2\2\u00dd\u00dc\3\2\2\2\u00dd\u00de\3\2\2\2\u00de\u00df\3\2"+
"\2\2\u00df\u00e0\5B\"\2\u00e0\23\3\2\2\2\u00e1\u00e2\5B\"\2\u00e2\u00e3"+
"\5B\"\2\u00e3\25\3\2\2\2\u00e4\u00e5\5\22\n\2\u00e5\u00e6\7\20\2\2\u00e6"+
"\u00e7\5,\27\2\u00e7\27\3\2\2\2\u00e8\u00e9\5\24\13\2\u00e9\u00ea\7\20"+
"\2\2\u00ea\u00eb\5,\27\2\u00eb\31\3\2\2\2\u00ec\u00ed\7\21\2\2\u00ed\u00ee"+
"\5\26\f\2\u00ee\33\3\2\2\2\u00ef\u00f0\7y\2\2\u00f0\u00f1\5\26\f\2\u00f1"+
"\35\3\2\2\2\u00f2\u00f3\7\22\2\2\u00f3\u00f4\5B\"\2\u00f4\u00f5\7\23\2"+
"\2\u00f5\u00f6\7t\2\2\u00f6\u00fb\5\22\n\2\u00f7\u00f8\7t\2\2\u00f8\u00fa"+
"\5\22\n\2\u00f9\u00f7\3\2\2\2\u00fa\u00fd\3\2\2\2\u00fb\u00f9\3\2\2\2"+
"\u00fb\u00fc\3\2\2\2\u00fc\u00ff\3\2\2\2\u00fd\u00fb\3\2\2\2\u00fe\u0100"+
"\7t\2\2\u00ff\u00fe\3\2\2\2\u00ff\u0100\3\2\2\2\u0100\u0101\3\2\2\2\u0101"+
"\u0102\7\24\2\2\u0102\u0103\7t\2\2\u0103\37\3\2\2\2\u0104\u0105\t\3\2"+
"\2\u0105!\3\2\2\2\u0106\u0107\7\34\2\2\u0107\u0108\5,\27\2\u0108\u0109"+
"\7\35\2\2\u0109#\3\2\2\2\u010a\u010b\5(\25\2\u010b\u010c\7\20\2\2\u010c"+
"\u010d\5,\27\2\u010d%\3\2\2\2\u010e\u010f\5(\25\2\u010f\u0110\t\4\2\2"+
"\u0110\u0111\5,\27\2\u0111\'\3\2\2\2\u0112\u0117\5F$\2\u0113\u0117\5D"+
"#\2\u0114\u0117\5\60\31\2\u0115\u0117\5\62\32\2\u0116\u0112\3\2\2\2\u0116"+
"\u0113\3\2\2\2\u0116\u0114\3\2\2\2\u0116\u0115\3\2\2\2\u0117)\3\2\2\2"+
"\u0118\u0119\5(\25\2\u0119\u011a\t\5\2\2\u011a+\3\2\2\2\u011b\u011c\b"+
"\27\1\2\u011c\u012c\5\66\34\2\u011d\u011e\t\6\2\2\u011e\u012c\5,\27\31"+
"\u011f\u0120\7A\2\2\u0120\u012c\5,\27\13\u0121\u012c\5\\/\2\u0122\u012c"+
"\5F$\2\u0123\u012c\5D#\2\u0124\u012c\5\60\31\2\u0125\u012c\5\62\32\2\u0126"+
"\u012c\5\64\33\2\u0127\u0128\7B\2\2\u0128\u0129\5,\27\2\u0129\u012a\7"+
"C\2\2\u012a\u012c\3\2\2\2\u012b\u011b\3\2\2\2\u012b\u011d\3\2\2\2\u012b"+
"\u011f\3\2\2\2\u012b\u0121\3\2\2\2\u012b\u0122\3\2\2\2\u012b\u0123\3\2"+
"\2\2\u012b\u0124\3\2\2\2\u012b\u0125\3\2\2\2\u012b\u0126\3\2\2\2\u012b"+
"\u0127\3\2\2\2\u012c\u01a4\3\2\2\2\u012d\u012f\f\30\2\2\u012e\u0130\7"+
"t\2\2\u012f\u012e\3\2\2\2\u012f\u0130\3\2\2\2\u0130\u0131\3\2\2\2\u0131"+
"\u0133\7.\2\2\u0132\u0134\7t\2\2\u0133\u0132\3\2\2\2\u0133\u0134\3\2\2"+
"\2\u0134\u0135\3\2\2\2\u0135\u01a3\5,\27\31\u0136\u0138\f\27\2\2\u0137"+
"\u0139\7t\2\2\u0138\u0137\3\2\2\2\u0138\u0139\3\2\2\2\u0139\u013a\3\2"+
"\2\2\u013a\u013c\t\7\2\2\u013b\u013d\7t\2\2\u013c\u013b\3\2\2\2\u013c"+
"\u013d\3\2\2\2\u013d\u013e\3\2\2\2\u013e\u01a3\5,\27\30\u013f\u0141\f"+
"\26\2\2\u0140\u0142\7t\2\2\u0141\u0140\3\2\2\2\u0141\u0142\3\2\2\2\u0142"+
"\u0143\3\2\2\2\u0143\u0145\t\b\2\2\u0144\u0146\7t\2\2\u0145\u0144\3\2"+
"\2\2\u0145\u0146\3\2\2\2\u0146\u0147\3\2\2\2\u0147\u01a3\5,\27\27\u0148"+
"\u014a\f\25\2\2\u0149\u014b\7t\2\2\u014a\u0149\3\2\2\2\u014a\u014b\3\2"+
"\2\2\u014b\u014c\3\2\2\2\u014c\u014e\t\t\2\2\u014d\u014f\7t\2\2\u014e"+
"\u014d\3\2\2\2\u014e\u014f\3\2\2\2\u014f\u0150\3\2\2\2\u0150\u01a3\5,"+
"\27\26\u0151\u0153\f\24\2\2\u0152\u0154\7t\2\2\u0153\u0152\3\2\2\2\u0153"+
"\u0154\3\2\2\2\u0154\u0155\3\2\2\2\u0155\u0157\t\n\2\2\u0156\u0158\7t"+
"\2\2\u0157\u0156\3\2\2\2\u0157\u0158\3\2\2\2\u0158\u0159\3\2\2\2\u0159"+
"\u01a3\5,\27\25\u015a\u015c\f\23\2\2\u015b\u015d\7t\2\2\u015c\u015b\3"+
"\2\2\2\u015c\u015d\3\2\2\2\u015d\u015e\3\2\2\2\u015e\u0160\t\13\2\2\u015f"+
"\u0161\7t\2\2\u0160\u015f\3\2\2\2\u0160\u0161\3\2\2\2\u0161\u0162\3\2"+
"\2\2\u0162\u01a3\5,\27\24\u0163\u0165\f\22\2\2\u0164\u0166\7t\2\2\u0165"+
"\u0164\3\2\2\2\u0165\u0166\3\2\2\2\u0166\u0167\3\2\2\2\u0167\u0169\7y"+
"\2\2\u0168\u016a\7t\2\2\u0169\u0168\3\2\2\2\u0169\u016a\3\2\2\2\u016a"+
"\u016b\3\2\2\2\u016b\u01a3\5,\27\23\u016c\u016e\f\21\2\2\u016d\u016f\7"+
"t\2\2\u016e\u016d\3\2\2\2\u016e\u016f\3\2\2\2\u016f\u0170\3\2\2\2\u0170"+
"\u0172\7:\2\2\u0171\u0173\7t\2\2\u0172\u0171\3\2\2\2\u0172\u0173\3\2\2"+
"\2\u0173\u0174\3\2\2\2\u0174\u01a3\5,\27\22\u0175\u0177\f\20\2\2\u0176"+
"\u0178\7t\2\2\u0177\u0176\3\2\2\2\u0177\u0178\3\2\2\2\u0178\u0179\3\2"+
"\2\2\u0179\u017b\7;\2\2\u017a\u017c\7t\2\2\u017b\u017a\3\2\2\2\u017b\u017c"+
"\3\2\2\2\u017c\u017d\3\2\2\2\u017d\u01a3\5,\27\21\u017e\u0180\f\16\2\2"+
"\u017f\u0181\7t\2\2\u0180\u017f\3\2\2\2\u0180\u0181\3\2\2\2\u0181\u0182"+
"\3\2\2\2\u0182\u0184\7>\2\2\u0183\u0185\7t\2\2\u0184\u0183\3\2\2\2\u0184"+
"\u0185\3\2\2\2\u0185\u0186\3\2\2\2\u0186\u01a3\5,\27\17\u0187\u0189\f"+
"\r\2\2\u0188\u018a\7t\2\2\u0189\u0188\3\2\2\2\u0189\u018a\3\2\2\2\u018a"+
"\u018b\3\2\2\2\u018b\u018d\7?\2\2\u018c\u018e\7t\2\2\u018d\u018c\3\2\2"+
"\2\u018d\u018e\3\2\2\2\u018e\u018f\3\2\2\2\u018f\u01a3\5,\27\16\u0190"+
"\u0192\f\f\2\2\u0191\u0193\7t\2\2\u0192\u0191\3\2\2\2\u0192\u0193\3\2"+
"\2\2\u0193\u0194\3\2\2\2\u0194\u0196\7@\2\2\u0195\u0197\7t\2\2\u0196\u0195"+
"\3\2\2\2\u0196\u0197\3\2\2\2\u0197\u0198\3\2\2\2\u0198\u01a3\5,\27\r\u0199"+
"\u019a\f\17\2\2\u019a\u019b\7<\2\2\u019b\u019e\5,\27\2\u019c\u019d\7="+
"\2\2\u019d\u019f\5,\27\2\u019e\u019c\3\2\2\2\u019e\u019f\3\2\2\2\u019f"+
"\u01a3\3\2\2\2\u01a0\u01a1\f\4\2\2\u01a1\u01a3\5.\30\2\u01a2\u012d\3\2"+
"\2\2\u01a2\u0136\3\2\2\2\u01a2\u013f\3\2\2\2\u01a2\u0148\3\2\2\2\u01a2"+
"\u0151\3\2\2\2\u01a2\u015a\3\2\2\2\u01a2\u0163\3\2\2\2\u01a2\u016c\3\2"+
"\2\2\u01a2\u0175\3\2\2\2\u01a2\u017e\3\2\2\2\u01a2\u0187\3\2\2\2\u01a2"+
"\u0190\3\2\2\2\u01a2\u0199\3\2\2\2\u01a2\u01a0\3\2\2\2\u01a3\u01a6\3\2"+
"\2\2\u01a4\u01a2\3\2\2\2\u01a4\u01a5\3\2\2\2\u01a5-\3\2\2\2\u01a6\u01a4"+
"\3\2\2\2\u01a7\u01a8\7D\2\2\u01a8\u01a9\5 \21\2\u01a9/\3\2\2\2\u01aa\u01ab"+
"\5D#\2\u01ab\u01ac\5\"\22\2\u01ac\61\3\2\2\2\u01ad\u01ae\7E\2\2\u01ae"+
"\u01af\7B\2\2\u01af\u01b0\5,\27\2\u01b0\u01b1\7C\2\2\u01b1\63\3\2\2\2"+
"\u01b2\u01b3\7y\2\2\u01b3\u01b4\5D#\2\u01b4\65\3\2\2\2\u01b5\u01b6\5D"+
"#\2\u01b6\u01b8\7B\2\2\u01b7\u01b9\5:\36\2\u01b8\u01b7\3\2\2\2\u01b8\u01b9"+
"\3\2\2\2\u01b9\u01ba\3\2\2\2\u01ba\u01bb\7C\2\2\u01bb\67\3\2\2\2\u01bc"+
"\u01bd\5D#\2\u01bd\u01bf\7B\2\2\u01be\u01c0\5:\36\2\u01bf\u01be\3\2\2"+
"\2\u01bf\u01c0\3\2\2\2\u01c0\u01c1\3\2\2\2\u01c1\u01c2\7C\2\2\u01c29\3"+
"\2\2\2\u01c3\u01cb\5,\27\2\u01c4\u01c6\7\17\2\2\u01c5\u01c7\7t\2\2\u01c6"+
"\u01c5\3\2\2\2\u01c6\u01c7\3\2\2\2\u01c7\u01c8\3\2\2\2\u01c8\u01ca\5,"+
"\27\2\u01c9\u01c4\3\2\2\2\u01ca\u01cd\3\2\2\2\u01cb\u01c9\3\2\2\2\u01cb"+
"\u01cc\3\2\2\2\u01cc;\3\2\2\2\u01cd\u01cb\3\2\2\2\u01ce\u01d0\7F\2\2\u01cf"+
"\u01d1\5,\27\2\u01d0\u01cf\3\2\2\2\u01d0\u01d1\3\2\2\2\u01d1=\3\2\2\2"+
"\u01d2\u01d3\7G\2\2\u01d3?\3\2\2\2\u01d4\u01d5\7H\2\2\u01d5A\3\2\2\2\u01d6"+
"\u01d7\7u\2\2\u01d7C\3\2\2\2\u01d8\u01dd\7u\2\2\u01d9\u01da\7I\2\2\u01da"+
"\u01dc\7u\2\2\u01db\u01d9\3\2\2\2\u01dc\u01df\3\2\2\2\u01dd\u01db\3\2"+
"\2\2\u01dd\u01de\3\2\2\2\u01deE\3\2\2\2\u01df\u01dd\3\2\2\2\u01e0\u01e1"+
"\t\f\2\2\u01e1G\3\2\2\2\u01e2\u01e3\t\r\2\2\u01e3I\3\2\2\2\u01e4\u01e5"+
"\t\16\2\2\u01e5K\3\2\2\2\u01e6\u01e8\t\17\2\2\u01e7\u01e9\5N(\2\u01e8"+
"\u01e7\3\2\2\2\u01e8\u01e9\3\2\2\2\u01e9M\3\2\2\2\u01ea\u01eb\7T\2\2\u01eb"+
"O\3\2\2\2\u01ec\u01ed\t\20\2\2\u01edQ\3\2\2\2\u01ee\u01f0\7\34\2\2\u01ef"+
"\u01f1\7t\2\2\u01f0\u01ef\3\2\2\2\u01f0\u01f1\3\2\2\2\u01f1\u01f2\3\2"+
"\2\2\u01f2\u01fa\5,\27\2\u01f3\u01f5\7\17\2\2\u01f4\u01f6\7t\2\2\u01f5"+
"\u01f4\3\2\2\2\u01f5\u01f6\3\2\2\2\u01f6\u01f7\3\2\2\2\u01f7\u01f9\5,"+
"\27\2\u01f8\u01f3\3\2\2\2\u01f9\u01fc\3\2\2\2\u01fa\u01f8\3\2\2\2\u01fa"+
"\u01fb\3\2\2\2\u01fb\u01fe\3\2\2\2\u01fc\u01fa\3\2\2\2\u01fd\u01ff\7t"+
"\2\2\u01fe\u01fd\3\2\2\2\u01fe\u01ff\3\2\2\2\u01ff\u0200\3\2\2\2\u0200"+
"\u0201\7\35\2\2\u0201S\3\2\2\2\u0202\u0204\7\23\2\2\u0203\u0205\7t\2\2"+
"\u0204\u0203\3\2\2\2\u0204\u0205\3\2\2\2\u0205\u0206\3\2\2\2\u0206\u020e"+
"\5,\27\2\u0207\u0209\7\17\2\2\u0208\u020a\7t\2\2\u0209\u0208\3\2\2\2\u0209"+
"\u020a\3\2\2\2\u020a\u020b\3\2\2\2\u020b\u020d\5,\27\2\u020c\u0207\3\2"+
"\2\2\u020d\u0210\3\2\2\2\u020e\u020c\3\2\2\2\u020e\u020f\3\2\2\2\u020f"+
"\u0212\3\2\2\2\u0210\u020e\3\2\2\2\u0211\u0213\7t\2\2\u0212\u0211\3\2"+
"\2\2\u0212\u0213\3\2\2\2\u0213\u0214\3\2\2\2\u0214\u0215\7\24\2\2\u0215"+
"U\3\2\2\2\u0216\u0217\7{\2\2\u0217W\3\2\2\2\u0218\u0219\7}\2\2\u0219Y"+
"\3\2\2\2\u021a\u021b\7z\2\2\u021b[\3\2\2\2\u021c\u0224\5L\'\2\u021d\u0224"+
"\5P)\2\u021e\u0224\5R*\2\u021f\u0224\5V,\2\u0220\u0224\5X-\2\u0221\u0224"+
"\5Z.\2\u0222\u0224\5T+\2\u0223\u021c\3\2\2\2\u0223\u021d\3\2\2\2\u0223"+
"\u021e\3\2\2\2\u0223\u021f\3\2\2\2\u0223\u0220\3\2\2\2\u0223\u0221\3\2"+
"\2\2\u0223\u0222\3\2\2\2\u0224]\3\2\2\2\u0225\u0226\7W\2\2\u0226\u0227"+
"\7|\2\2\u0227_\3\2\2\2\u0228\u0229\7X\2\2\u0229\u022a\5B\"\2\u022a\u022c"+
"\7B\2\2\u022b\u022d\5f\64\2\u022c\u022b\3\2\2\2\u022c\u022d\3\2\2\2\u022d"+
"\u022e\3\2\2\2\u022e\u0230\7C\2\2\u022f\u0231\5b\62\2\u0230\u022f\3\2"+
"\2\2\u0230\u0231\3\2\2\2\u0231\u0232\3\2\2\2\u0232\u0233\5d\63\2\u0233"+
"\u0234\7t\2\2\u0234a\3\2\2\2\u0235\u0236\7Y\2\2\u0236\u0237\5h\65\2\u0237"+
"c\3\2\2\2\u0238\u0239\7\23\2\2\u0239\u023e\7t\2\2\u023a\u023d\5\b\5\2"+
"\u023b\u023d\7t\2\2\u023c\u023a\3\2\2\2\u023c\u023b\3\2\2\2\u023d\u0240"+
"\3\2\2\2\u023e\u023c\3\2\2\2\u023e\u023f\3\2\2\2\u023f\u0241\3\2\2\2\u0240"+
"\u023e\3\2\2\2\u0241\u0242\7\24\2\2\u0242e\3\2\2\2\u0243\u024b\5\22\n"+
"\2\u0244\u0246\7\17\2\2\u0245\u0247\7t\2\2\u0246\u0245\3\2\2\2\u0246\u0247"+
"\3\2\2\2\u0247\u0248\3\2\2\2\u0248\u024a\5\22\n\2\u0249\u0244\3\2\2\2"+
"\u024a\u024d\3\2\2\2\u024b\u0249\3\2\2\2\u024b\u024c\3\2\2\2\u024cg\3"+
"\2\2\2\u024d\u024b\3\2\2\2\u024e\u0256\5 \21\2\u024f\u0251\7\17\2\2\u0250"+
"\u0252\7t\2\2\u0251\u0250\3\2\2\2\u0251\u0252\3\2\2\2\u0252\u0253\3\2"+
"\2\2\u0253\u0255\5 \21\2\u0254\u024f\3\2\2\2\u0255\u0258\3\2\2\2\u0256"+
"\u0254\3\2\2\2\u0256\u0257\3\2\2\2\u0257i\3\2\2\2\u0258\u0256\3\2\2\2"+
"\u0259\u025a\7Z\2\2\u025a\u025b\5B\"\2\u025b\u025d\7B\2\2\u025c\u025e"+
"\5n8\2\u025d\u025c\3\2\2\2\u025d\u025e\3\2\2\2\u025e\u025f\3\2\2\2\u025f"+
"\u0261\7C\2\2\u0260\u0262\7t\2\2\u0261\u0260\3\2\2\2\u0261\u0262\3\2\2"+
"\2\u0262\u0264\3\2\2\2\u0263\u0265\5r:\2\u0264\u0263\3\2\2\2\u0264\u0265"+
"\3\2\2\2\u0265\u0267\3\2\2\2\u0266\u0268\5v<\2\u0267\u0266\3\2\2\2\u0267"+
"\u0268\3\2\2\2\u0268\u026b\3\2\2\2\u0269\u026c\5l\67\2\u026a\u026c\5d"+
"\63\2\u026b\u0269\3\2\2\2\u026b\u026a\3\2\2\2\u026ck\3\2\2\2\u026d\u026e"+
"\7\20\2\2\u026e\u026f\5L\'\2\u026fm\3\2\2\2\u0270\u0278\5p9\2\u0271\u0273"+
"\7\17\2\2\u0272\u0274\7t\2\2\u0273\u0272\3\2\2\2\u0273\u0274\3\2\2\2\u0274"+
"\u0275\3\2\2\2\u0275\u0277\5p9\2\u0276\u0271\3\2\2\2\u0277\u027a\3\2\2"+
"\2\u0278\u0276\3\2\2\2\u0278\u0279\3\2\2\2\u0279o\3\2\2\2\u027a\u0278"+
"\3\2\2\2\u027b\u027c\5\22\n\2\u027c\u0280\7E\2\2\u027d\u0281\5H%\2\u027e"+
"\u0281\5J&\2\u027f\u0281\7[\2\2\u0280\u027d\3\2\2\2\u0280\u027e\3\2\2"+
"\2\u0280\u027f\3\2\2\2\u0281q\3\2\2\2\u0282\u0283\7\\\2\2\u0283\u0285"+
"\7B\2\2\u0284\u0286\5t;\2\u0285\u0284\3\2\2\2\u0285\u0286\3\2\2\2\u0286"+
"\u0287\3\2\2\2\u0287\u0288\7C\2\2\u0288s\3\2\2\2\u0289\u028e\5F$\2\u028a"+
"\u028b\7\17\2\2\u028b\u028d\5F$\2\u028c\u028a\3\2\2\2\u028d\u0290\3\2"+
"\2\2\u028e\u028c\3\2\2\2\u028e\u028f\3\2\2\2\u028fu\3\2\2\2\u0290\u028e"+
"\3\2\2\2\u0291\u0292\7Y\2\2\u0292\u029a\5x=\2\u0293\u0295\7\17\2\2\u0294"+
"\u0296\7t\2\2\u0295\u0294\3\2\2\2\u0295\u0296\3\2\2\2\u0296\u0297\3\2"+
"\2\2\u0297\u0299\5x=\2\u0298\u0293\3\2\2\2\u0299\u029c\3\2\2\2\u029a\u0298"+
"\3\2\2\2\u029a\u029b\3\2\2\2\u029bw\3\2\2\2\u029c\u029a\3\2\2\2\u029d"+
"\u029e\5 \21\2\u029e\u02a2\7E\2\2\u029f\u02a3\5H%\2\u02a0\u02a3\5J&\2"+
"\u02a1\u02a3\7[\2\2\u02a2\u029f\3\2\2\2\u02a2\u02a0\3\2\2\2\u02a2\u02a1"+
"\3\2\2\2\u02a3y\3\2\2\2\u02a4\u02a5\7]\2\2\u02a5\u02a7\5,\27\2\u02a6\u02a8"+
"\7t\2\2\u02a7\u02a6\3\2\2\2\u02a7\u02a8\3\2\2\2\u02a8\u02ab\3\2\2\2\u02a9"+
"\u02ac\5\b\5\2\u02aa\u02ac\5d\63\2\u02ab\u02a9\3\2\2\2\u02ab\u02aa\3\2"+
"\2\2\u02ac\u02ae\3\2\2\2\u02ad\u02af\7t\2\2\u02ae\u02ad\3\2\2\2\u02ae"+
"\u02af\3\2\2\2\u02af\u02b1\3\2\2\2\u02b0\u02b2\5|?\2\u02b1\u02b0\3\2\2"+
"\2\u02b1\u02b2\3\2\2\2\u02b2{\3\2\2\2\u02b3\u02b5\7^\2\2\u02b4\u02b6\7"+
"t\2\2\u02b5\u02b4\3\2\2\2\u02b5\u02b6\3\2\2\2\u02b6\u02b9\3\2\2\2\u02b7"+
"\u02ba\5\b\5\2\u02b8\u02ba\5d\63\2\u02b9\u02b7\3\2\2\2\u02b9\u02b8\3\2"+
"\2\2\u02ba}\3\2\2\2\u02bb\u02bd\5\u0080A\2\u02bc\u02be\7t\2\2\u02bd\u02bc"+
"\3\2\2\2\u02bd\u02be\3\2\2\2\u02be\u02c1\3\2\2\2\u02bf\u02c2\5\b\5\2\u02c0"+
"\u02c2\5d\63\2\u02c1\u02bf\3\2\2\2\u02c1\u02c0\3\2\2\2\u02c2\u02c4\3\2"+
"\2\2\u02c3\u02c5\7t\2\2\u02c4\u02c3\3\2\2\2\u02c4\u02c5\3\2\2\2\u02c5"+
"\u02c7\3\2\2\2\u02c6\u02c8\5|?\2\u02c7\u02c6\3\2\2\2\u02c7\u02c8\3\2\2"+
"\2\u02c8\u02c9\3\2\2\2\u02c9\u02ca\7t\2\2\u02ca\177\3\2\2\2\u02cb\u02cc"+
"\t\21\2\2\u02cc\u0081\3\2\2\2\u02cd\u02cf\7k\2\2\u02ce\u02d0\5 \21\2\u02cf"+
"\u02ce\3\2\2\2\u02cf\u02d0\3\2\2\2\u02d0\u02d2\3\2\2\2\u02d1\u02d3\7~"+
"\2\2\u02d2\u02d1\3\2\2\2\u02d2\u02d3\3\2\2\2\u02d3\u02d6\3\2\2\2\u02d4"+
"\u02d7\5F$\2\u02d5\u02d7\5B\"\2\u02d6\u02d4\3\2\2\2\u02d6\u02d5\3\2\2"+
"\2\u02d7\u02d8\3\2\2\2\u02d8\u02d9\7l\2\2\u02d9\u02db\5,\27\2\u02da\u02dc"+
"\7t\2\2\u02db\u02da\3\2\2\2\u02db\u02dc\3\2\2\2\u02dc\u02df\3\2\2\2\u02dd"+
"\u02e0\5\b\5\2\u02de\u02e0\5d\63\2\u02df\u02dd\3\2\2\2\u02df\u02de\3\2"+
"\2\2\u02e0\u0083\3\2\2\2\u02e1\u02e2\7m\2\2\u02e2\u02e4\5,\27\2\u02e3"+
"\u02e5\7t\2\2\u02e4\u02e3\3\2\2\2\u02e4\u02e5\3\2\2\2\u02e5\u02e8\3\2"+
"\2\2\u02e6\u02e9\5\b\5\2\u02e7\u02e9\5d\63\2\u02e8\u02e6\3\2\2\2\u02e8"+
"\u02e7\3\2\2\2\u02e9\u0085\3\2\2\2\u02ea\u02ed\7n\2\2\u02eb\u02ee\5\b"+
"\5\2\u02ec\u02ee\5d\63\2\u02ed\u02eb\3\2\2\2\u02ed\u02ec\3\2\2\2\u02ee"+
"\u02f0\3\2\2\2\u02ef\u02f1\7t\2\2\u02f0\u02ef\3\2\2\2\u02f0\u02f1\3\2"+
"\2\2\u02f1\u02f2\3\2\2\2\u02f2\u02f3\7o\2\2\u02f3\u02f4\5,\27\2\u02f4"+
"\u0087\3\2\2\2\u02f5\u02f6\7p\2\2\u02f6\u02f7\5,\27\2\u02f7\u02f8\7\23"+
"\2\2\u02f8\u02fd\7t\2\2\u02f9\u02fc\5\u008aF\2\u02fa\u02fc\7t\2\2\u02fb"+
"\u02f9\3\2\2\2\u02fb\u02fa\3\2\2\2\u02fc\u02ff\3\2\2\2\u02fd\u02fb\3\2"+
"\2\2\u02fd\u02fe\3\2\2\2\u02fe\u0300\3\2\2\2\u02ff\u02fd\3\2\2\2\u0300"+
"\u0302\7\24\2\2\u0301\u0303\7t\2\2\u0302\u0301\3\2\2\2\u0302\u0303\3\2"+
"\2\2\u0303\u0089\3\2\2\2\u0304\u0307\5:\36\2\u0305\u0307\7^\2\2\u0306"+
"\u0304\3\2\2\2\u0306\u0305\3\2\2\2\u0307\u0308\3\2\2\2\u0308\u030b\7Y"+
"\2\2\u0309\u030c\5\b\5\2\u030a\u030c\5d\63\2\u030b\u0309\3\2\2\2\u030b"+
"\u030a\3\2\2\2\u030c\u008b\3\2\2\2j\u008e\u0090\u0097\u009b\u00ba\u00c2"+
"\n@\3@\5@\u02c5\n@\3@\5@\u02c8\n@\3@\3@\3A\3A\3B\3B\3B\5B\u02d1\nB\3B"+
"\3B\3B\5B\u02d6\nB\3B\3B\5B\u02da\nB\3C\3C\3C\5C\u02df\nC\3C\3C\5C\u02e3"+
"\nC\3D\3D\3D\5D\u02e8\nD\3D\5D\u02eb\nD\3D\3D\3D\3E\3E\3E\3E\3E\3E\7E"+
"\u02f6\nE\fE\16E\u02f9\13E\3E\3E\5E\u02fd\nE\3F\3F\5F\u0301\nF\3F\3F\3"+
"F\5F\u0306\nF\3F\2\3,G\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,"+
".\60\62\64\668:<>@BDFHJLNPRTVXZ\\^`bdfhjlnprtvxz|~\u0080\u0082\u0084\u0086"+
"\u0088\u008a\2\22\3\2\5\16\3\2\25\33\3\2\36(\3\2)*\3\2+-\3\2/\61\3\2+"+
",\3\2\62\63\3\2\64\67\3\289\3\2JL\3\2JO\3\2PS\3\2vx\3\2UV\3\2_j\2\u035f"+
"\2\u0090\3\2\2\2\4\u0097\3\2\2\2\6\u0099\3\2\2\2\b\u00ba\3\2\2\2\n\u00bc"+
"\3\2\2\2\f\u00bf\3\2\2\2\16\u00c4\3\2\2\2\20\u00d5\3\2\2\2\22\u00d7\3"+
"\2\2\2\24\u00e1\3\2\2\2\26\u00e4\3\2\2\2\30\u00e8\3\2\2\2\32\u00ec\3\2"+
"\2\2\34\u00ef\3\2\2\2\36\u00f2\3\2\2\2 \u0104\3\2\2\2\"\u0106\3\2\2\2"+
"$\u010a\3\2\2\2&\u010e\3\2\2\2(\u0116\3\2\2\2*\u0118\3\2\2\2,\u012b\3"+
"\2\2\2.\u01a7\3\2\2\2\60\u01aa\3\2\2\2\62\u01ad\3\2\2\2\64\u01b2\3\2\2"+
"\2\66\u01b5\3\2\2\28\u01bc\3\2\2\2:\u01c3\3\2\2\2<\u01ce\3\2\2\2>\u01d2"+
"\3\2\2\2@\u01d4\3\2\2\2B\u01d6\3\2\2\2D\u01d8\3\2\2\2F\u01e0\3\2\2\2H"+
"\u01e2\3\2\2\2J\u01e4\3\2\2\2L\u01e6\3\2\2\2N\u01ea\3\2\2\2P\u01ec\3\2"+
"\2\2R\u01ee\3\2\2\2T\u0202\3\2\2\2V\u0216\3\2\2\2X\u0218\3\2\2\2Z\u021a"+
"\3\2\2\2\\\u0223\3\2\2\2^\u0225\3\2\2\2`\u0228\3\2\2\2b\u0235\3\2\2\2"+
"d\u0238\3\2\2\2f\u0243\3\2\2\2h\u024e\3\2\2\2j\u0259\3\2\2\2l\u026d\3"+
"\2\2\2n\u0270\3\2\2\2p\u027b\3\2\2\2r\u0282\3\2\2\2t\u0289\3\2\2\2v\u0291"+
"\3\2\2\2x\u029d\3\2\2\2z\u02a4\3\2\2\2|\u02b3\3\2\2\2~\u02bb\3\2\2\2\u0080"+
"\u02cb\3\2\2\2\u0082\u02cd\3\2\2\2\u0084\u02db\3\2\2\2\u0086\u02e4\3\2"+
"\2\2\u0088\u02ef\3\2\2\2\u008a\u0300\3\2\2\2\u008c\u008f\5\4\3\2\u008d"+
"\u008f\7t\2\2\u008e\u008c\3\2\2\2\u008e\u008d\3\2\2\2\u008f\u0092\3\2"+
"\2\2\u0090\u008e\3\2\2\2\u0090\u0091\3\2\2\2\u0091\u0093\3\2\2\2\u0092"+
"\u0090\3\2\2\2\u0093\u0094\7\2\2\3\u0094\3\3\2\2\2\u0095\u0098\5\16\b"+
"\2\u0096\u0098\5\6\4\2\u0097\u0095\3\2\2\2\u0097\u0096\3\2\2\2\u0098\5"+
"\3\2\2\2\u0099\u009b\5B\"\2\u009a\u009c\5L\'\2\u009b\u009a\3\2\2\2\u009b"+
"\u009c\3\2\2\2\u009c\u009d\3\2\2\2\u009d\u009e\5d\63\2\u009e\u009f\7t"+
"\2\2\u009f\7\3\2\2\2\u00a0\u00bb\5\16\b\2\u00a1\u00bb\5\26\f\2\u00a2\u00bb"+
"\5\30\r\2\u00a3\u00bb\5\22\n\2\u00a4\u00bb\5\24\13\2\u00a5\u00bb\5\32"+
"\16\2\u00a6\u00bb\5\34\17\2\u00a7\u00bb\5\36\20\2\u00a8\u00bb\5$\23\2"+
"\u00a9\u00bb\5&\24\2\u00aa\u00bb\5\f\7\2\u00ab\u00bb\5*\26\2\u00ac\u00bb"+
"\58\35\2\u00ad\u00bb\5z>\2\u00ae\u00bb\5~@\2\u00af\u00bb\5`\61\2\u00b0"+
"\u00bb\5j\66\2\u00b1\u00bb\5^\60\2\u00b2\u00bb\5<\37\2\u00b3\u00bb\5\u0082"+
"B\2\u00b4\u00bb\5\u0084C\2\u00b5\u00bb\5\u0086D\2\u00b6\u00bb\5\u0088"+
"E\2\u00b7\u00bb\5> \2\u00b8\u00bb\5@!\2\u00b9\u00bb\5\n\6\2\u00ba\u00a0"+
"\3\2\2\2\u00ba\u00a1\3\2\2\2\u00ba\u00a2\3\2\2\2\u00ba\u00a3\3\2\2\2\u00ba"+
"\u00a4\3\2\2\2\u00ba\u00a5\3\2\2\2\u00ba\u00a6\3\2\2\2\u00ba\u00a7\3\2"+
"\2\2\u00ba\u00a8\3\2\2\2\u00ba\u00a9\3\2\2\2\u00ba\u00aa\3\2\2\2\u00ba"+
"\u00ab\3\2\2\2\u00ba\u00ac\3\2\2\2\u00ba\u00ad\3\2\2\2\u00ba\u00ae\3\2"+
"\2\2\u00ba\u00af\3\2\2\2\u00ba\u00b0\3\2\2\2\u00ba\u00b1\3\2\2\2\u00ba"+
"\u00b2\3\2\2\2\u00ba\u00b3\3\2\2\2\u00ba\u00b4\3\2\2\2\u00ba\u00b5\3\2"+
"\2\2\u00ba\u00b6\3\2\2\2\u00ba\u00b7\3\2\2\2\u00ba\u00b8\3\2\2\2\u00ba"+
"\u00b9\3\2\2\2\u00bb\t\3\2\2\2\u00bc\u00bd\5B\"\2\u00bd\u00be\7\3\2\2"+
"\u00be\13\3\2\2\2\u00bf\u00c2\7\4\2\2\u00c0\u00c3\5L\'\2\u00c1\u00c3\5"+
"D#\2\u00c2\u00c0\3\2\2\2\u00c2\u00c1\3\2\2\2\u00c3\r\3\2\2\2\u00c4\u00d0"+
"\t\2\2\2\u00c5\u00c7\5\20\t\2\u00c6\u00c5\3\2\2\2\u00c6\u00c7\3\2\2\2"+
"\u00c7\u00d1\3\2\2\2\u00c8\u00cd\5\20\t\2\u00c9\u00ca\7\17\2\2\u00ca\u00cc"+
"\5\20\t\2\u00cb\u00c9\3\2\2\2\u00cc\u00cf\3\2\2\2\u00cd\u00cb\3\2\2\2"+
"\u00cd\u00ce\3\2\2\2\u00ce\u00d1\3\2\2\2\u00cf\u00cd\3\2\2\2\u00d0\u00c6"+
"\3\2\2\2\u00d0\u00c8\3\2\2\2\u00d1\17\3\2\2\2\u00d2\u00d6\5V,\2\u00d3"+
"\u00d6\5B\"\2\u00d4\u00d6\5L\'\2\u00d5\u00d2\3\2\2\2\u00d5\u00d3\3\2\2"+
"\2\u00d5\u00d4\3\2\2\2\u00d6\21\3\2\2\2\u00d7\u00d9\5 \21\2\u00d8\u00da"+
"\7~\2\2\u00d9\u00d8\3\2\2\2\u00d9\u00da\3\2\2\2\u00da\u00dd\3\2\2\2\u00db"+
"\u00de\5\"\22\2\u00dc\u00de\7\177\2\2\u00dd\u00db\3\2\2\2\u00dd\u00dc"+
"\3\2\2\2\u00dd\u00de\3\2\2\2\u00de\u00df\3\2\2\2\u00df\u00e0\5B\"\2\u00e0"+
"\23\3\2\2\2\u00e1\u00e2\5B\"\2\u00e2\u00e3\5B\"\2\u00e3\25\3\2\2\2\u00e4"+
"\u00e5\5\22\n\2\u00e5\u00e6\7\20\2\2\u00e6\u00e7\5,\27\2\u00e7\27\3\2"+
"\2\2\u00e8\u00e9\5\24\13\2\u00e9\u00ea\7\20\2\2\u00ea\u00eb\5,\27\2\u00eb"+
"\31\3\2\2\2\u00ec\u00ed\7\21\2\2\u00ed\u00ee\5\26\f\2\u00ee\33\3\2\2\2"+
"\u00ef\u00f0\7y\2\2\u00f0\u00f1\5\26\f\2\u00f1\35\3\2\2\2\u00f2\u00f3"+
"\7\22\2\2\u00f3\u00f4\5B\"\2\u00f4\u00f5\7\23\2\2\u00f5\u00f6\7t\2\2\u00f6"+
"\u00fb\5\22\n\2\u00f7\u00f8\7t\2\2\u00f8\u00fa\5\22\n\2\u00f9\u00f7\3"+
"\2\2\2\u00fa\u00fd\3\2\2\2\u00fb\u00f9\3\2\2\2\u00fb\u00fc\3\2\2\2\u00fc"+
"\u00ff\3\2\2\2\u00fd\u00fb\3\2\2\2\u00fe\u0100\7t\2\2\u00ff\u00fe\3\2"+
"\2\2\u00ff\u0100\3\2\2\2\u0100\u0101\3\2\2\2\u0101\u0102\7\24\2\2\u0102"+
"\u0103\7t\2\2\u0103\37\3\2\2\2\u0104\u0105\t\3\2\2\u0105!\3\2\2\2\u0106"+
"\u0107\7\34\2\2\u0107\u0108\5,\27\2\u0108\u0109\7\35\2\2\u0109#\3\2\2"+
"\2\u010a\u010b\5(\25\2\u010b\u010c\7\20\2\2\u010c\u010d\5,\27\2\u010d"+
"%\3\2\2\2\u010e\u010f\5(\25\2\u010f\u0110\t\4\2\2\u0110\u0111\5,\27\2"+
"\u0111\'\3\2\2\2\u0112\u0117\5F$\2\u0113\u0117\5D#\2\u0114\u0117\5\60"+
"\31\2\u0115\u0117\5\62\32\2\u0116\u0112\3\2\2\2\u0116\u0113\3\2\2\2\u0116"+
"\u0114\3\2\2\2\u0116\u0115\3\2\2\2\u0117)\3\2\2\2\u0118\u0119\5(\25\2"+
"\u0119\u011a\t\5\2\2\u011a+\3\2\2\2\u011b\u011c\b\27\1\2\u011c\u012c\5"+
"\66\34\2\u011d\u011e\t\6\2\2\u011e\u012c\5,\27\31\u011f\u0120\7A\2\2\u0120"+
"\u012c\5,\27\13\u0121\u012c\5\\/\2\u0122\u012c\5F$\2\u0123\u012c\5D#\2"+
"\u0124\u012c\5\60\31\2\u0125\u012c\5\62\32\2\u0126\u012c\5\64\33\2\u0127"+
"\u0128\7B\2\2\u0128\u0129\5,\27\2\u0129\u012a\7C\2\2\u012a\u012c\3\2\2"+
"\2\u012b\u011b\3\2\2\2\u012b\u011d\3\2\2\2\u012b\u011f\3\2\2\2\u012b\u0121"+
"\3\2\2\2\u012b\u0122\3\2\2\2\u012b\u0123\3\2\2\2\u012b\u0124\3\2\2\2\u012b"+
"\u0125\3\2\2\2\u012b\u0126\3\2\2\2\u012b\u0127\3\2\2\2\u012c\u01a4\3\2"+
"\2\2\u012d\u012f\f\30\2\2\u012e\u0130\7t\2\2\u012f\u012e\3\2\2\2\u012f"+
"\u0130\3\2\2\2\u0130\u0131\3\2\2\2\u0131\u0133\7.\2\2\u0132\u0134\7t\2"+
"\2\u0133\u0132\3\2\2\2\u0133\u0134\3\2\2\2\u0134\u0135\3\2\2\2\u0135\u01a3"+
"\5,\27\31\u0136\u0138\f\27\2\2\u0137\u0139\7t\2\2\u0138\u0137\3\2\2\2"+
"\u0138\u0139\3\2\2\2\u0139\u013a\3\2\2\2\u013a\u013c\t\7\2\2\u013b\u013d"+
"\7t\2\2\u013c\u013b\3\2\2\2\u013c\u013d\3\2\2\2\u013d\u013e\3\2\2\2\u013e"+
"\u01a3\5,\27\30\u013f\u0141\f\26\2\2\u0140\u0142\7t\2\2\u0141\u0140\3"+
"\2\2\2\u0141\u0142\3\2\2\2\u0142\u0143\3\2\2\2\u0143\u0145\t\b\2\2\u0144"+
"\u0146\7t\2\2\u0145\u0144\3\2\2\2\u0145\u0146\3\2\2\2\u0146\u0147\3\2"+
"\2\2\u0147\u01a3\5,\27\27\u0148\u014a\f\25\2\2\u0149\u014b\7t\2\2\u014a"+
"\u0149\3\2\2\2\u014a\u014b\3\2\2\2\u014b\u014c\3\2\2\2\u014c\u014e\t\t"+
"\2\2\u014d\u014f\7t\2\2\u014e\u014d\3\2\2\2\u014e\u014f\3\2\2\2\u014f"+
"\u0150\3\2\2\2\u0150\u01a3\5,\27\26\u0151\u0153\f\24\2\2\u0152\u0154\7"+
"t\2\2\u0153\u0152\3\2\2\2\u0153\u0154\3\2\2\2\u0154\u0155\3\2\2\2\u0155"+
"\u0157\t\n\2\2\u0156\u0158\7t\2\2\u0157\u0156\3\2\2\2\u0157\u0158\3\2"+
"\2\2\u0158\u0159\3\2\2\2\u0159\u01a3\5,\27\25\u015a\u015c\f\23\2\2\u015b"+
"\u015d\7t\2\2\u015c\u015b\3\2\2\2\u015c\u015d\3\2\2\2\u015d\u015e\3\2"+
"\2\2\u015e\u0160\t\13\2\2\u015f\u0161\7t\2\2\u0160\u015f\3\2\2\2\u0160"+
"\u0161\3\2\2\2\u0161\u0162\3\2\2\2\u0162\u01a3\5,\27\24\u0163\u0165\f"+
"\22\2\2\u0164\u0166\7t\2\2\u0165\u0164\3\2\2\2\u0165\u0166\3\2\2\2\u0166"+
"\u0167\3\2\2\2\u0167\u0169\7y\2\2\u0168\u016a\7t\2\2\u0169\u0168\3\2\2"+
"\2\u0169\u016a\3\2\2\2\u016a\u016b\3\2\2\2\u016b\u01a3\5,\27\23\u016c"+
"\u016e\f\21\2\2\u016d\u016f\7t\2\2\u016e\u016d\3\2\2\2\u016e\u016f\3\2"+
"\2\2\u016f\u0170\3\2\2\2\u0170\u0172\7:\2\2\u0171\u0173\7t\2\2\u0172\u0171"+
"\3\2\2\2\u0172\u0173\3\2\2\2\u0173\u0174\3\2\2\2\u0174\u01a3\5,\27\22"+
"\u0175\u0177\f\20\2\2\u0176\u0178\7t\2\2\u0177\u0176\3\2\2\2\u0177\u0178"+
"\3\2\2\2\u0178\u0179\3\2\2\2\u0179\u017b\7;\2\2\u017a\u017c\7t\2\2\u017b"+
"\u017a\3\2\2\2\u017b\u017c\3\2\2\2\u017c\u017d\3\2\2\2\u017d\u01a3\5,"+
"\27\21\u017e\u0180\f\16\2\2\u017f\u0181\7t\2\2\u0180\u017f\3\2\2\2\u0180"+
"\u0181\3\2\2\2\u0181\u0182\3\2\2\2\u0182\u0184\7>\2\2\u0183\u0185\7t\2"+
"\2\u0184\u0183\3\2\2\2\u0184\u0185\3\2\2\2\u0185\u0186\3\2\2\2\u0186\u01a3"+
"\5,\27\17\u0187\u0189\f\r\2\2\u0188\u018a\7t\2\2\u0189\u0188\3\2\2\2\u0189"+
"\u018a\3\2\2\2\u018a\u018b\3\2\2\2\u018b\u018d\7?\2\2\u018c\u018e\7t\2"+
"\2\u018d\u018c\3\2\2\2\u018d\u018e\3\2\2\2\u018e\u018f\3\2\2\2\u018f\u01a3"+
"\5,\27\16\u0190\u0192\f\f\2\2\u0191\u0193\7t\2\2\u0192\u0191\3\2\2\2\u0192"+
"\u0193\3\2\2\2\u0193\u0194\3\2\2\2\u0194\u0196\7@\2\2\u0195\u0197\7t\2"+
"\2\u0196\u0195\3\2\2\2\u0196\u0197\3\2\2\2\u0197\u0198\3\2\2\2\u0198\u01a3"+
"\5,\27\r\u0199\u019a\f\17\2\2\u019a\u019b\7<\2\2\u019b\u019e\5,\27\2\u019c"+
"\u019d\7=\2\2\u019d\u019f\5,\27\2\u019e\u019c\3\2\2\2\u019e\u019f\3\2"+
"\2\2\u019f\u01a3\3\2\2\2\u01a0\u01a1\f\4\2\2\u01a1\u01a3\5.\30\2\u01a2"+
"\u012d\3\2\2\2\u01a2\u0136\3\2\2\2\u01a2\u013f\3\2\2\2\u01a2\u0148\3\2"+
"\2\2\u01a2\u0151\3\2\2\2\u01a2\u015a\3\2\2\2\u01a2\u0163\3\2\2\2\u01a2"+
"\u016c\3\2\2\2\u01a2\u0175\3\2\2\2\u01a2\u017e\3\2\2\2\u01a2\u0187\3\2"+
"\2\2\u01a2\u0190\3\2\2\2\u01a2\u0199\3\2\2\2\u01a2\u01a0\3\2\2\2\u01a3"+
"\u01a6\3\2\2\2\u01a4\u01a2\3\2\2\2\u01a4\u01a5\3\2\2\2\u01a5-\3\2\2\2"+
"\u01a6\u01a4\3\2\2\2\u01a7\u01a8\7D\2\2\u01a8\u01a9\5 \21\2\u01a9/\3\2"+
"\2\2\u01aa\u01ab\5D#\2\u01ab\u01ac\5\"\22\2\u01ac\61\3\2\2\2\u01ad\u01ae"+
"\7E\2\2\u01ae\u01af\7B\2\2\u01af\u01b0\5,\27\2\u01b0\u01b1\7C\2\2\u01b1"+
"\63\3\2\2\2\u01b2\u01b3\7y\2\2\u01b3\u01b4\5D#\2\u01b4\65\3\2\2\2\u01b5"+
"\u01b6\5D#\2\u01b6\u01b8\7B\2\2\u01b7\u01b9\5:\36\2\u01b8\u01b7\3\2\2"+
"\2\u01b8\u01b9\3\2\2\2\u01b9\u01ba\3\2\2\2\u01ba\u01bb\7C\2\2\u01bb\67"+
"\3\2\2\2\u01bc\u01bd\5D#\2\u01bd\u01bf\7B\2\2\u01be\u01c0\5:\36\2\u01bf"+
"\u01be\3\2\2\2\u01bf\u01c0\3\2\2\2\u01c0\u01c1\3\2\2\2\u01c1\u01c2\7C"+
"\2\2\u01c29\3\2\2\2\u01c3\u01cb\5,\27\2\u01c4\u01c6\7\17\2\2\u01c5\u01c7"+
"\7t\2\2\u01c6\u01c5\3\2\2\2\u01c6\u01c7\3\2\2\2\u01c7\u01c8\3\2\2\2\u01c8"+
"\u01ca\5,\27\2\u01c9\u01c4\3\2\2\2\u01ca\u01cd\3\2\2\2\u01cb\u01c9\3\2"+
"\2\2\u01cb\u01cc\3\2\2\2\u01cc;\3\2\2\2\u01cd\u01cb\3\2\2\2\u01ce\u01d0"+
"\7F\2\2\u01cf\u01d1\5,\27\2\u01d0\u01cf\3\2\2\2\u01d0\u01d1\3\2\2\2\u01d1"+
"=\3\2\2\2\u01d2\u01d3\7G\2\2\u01d3?\3\2\2\2\u01d4\u01d5\7H\2\2\u01d5A"+
"\3\2\2\2\u01d6\u01d7\7u\2\2\u01d7C\3\2\2\2\u01d8\u01dd\7u\2\2\u01d9\u01da"+
"\7I\2\2\u01da\u01dc\7u\2\2\u01db\u01d9\3\2\2\2\u01dc\u01df\3\2\2\2\u01dd"+
"\u01db\3\2\2\2\u01dd\u01de\3\2\2\2\u01deE\3\2\2\2\u01df\u01dd\3\2\2\2"+
"\u01e0\u01e1\t\f\2\2\u01e1G\3\2\2\2\u01e2\u01e3\t\r\2\2\u01e3I\3\2\2\2"+
"\u01e4\u01e5\t\16\2\2\u01e5K\3\2\2\2\u01e6\u01e8\t\17\2\2\u01e7\u01e9"+
"\5N(\2\u01e8\u01e7\3\2\2\2\u01e8\u01e9\3\2\2\2\u01e9M\3\2\2\2\u01ea\u01eb"+
"\7T\2\2\u01ebO\3\2\2\2\u01ec\u01ed\t\20\2\2\u01edQ\3\2\2\2\u01ee\u01f0"+
"\7\34\2\2\u01ef\u01f1\7t\2\2\u01f0\u01ef\3\2\2\2\u01f0\u01f1\3\2\2\2\u01f1"+
"\u01f2\3\2\2\2\u01f2\u01fa\5,\27\2\u01f3\u01f5\7\17\2\2\u01f4\u01f6\7"+
"t\2\2\u01f5\u01f4\3\2\2\2\u01f5\u01f6\3\2\2\2\u01f6\u01f7\3\2\2\2\u01f7"+
"\u01f9\5,\27\2\u01f8\u01f3\3\2\2\2\u01f9\u01fc\3\2\2\2\u01fa\u01f8\3\2"+
"\2\2\u01fa\u01fb\3\2\2\2\u01fb\u01fe\3\2\2\2\u01fc\u01fa\3\2\2\2\u01fd"+
"\u01ff\7t\2\2\u01fe\u01fd\3\2\2\2\u01fe\u01ff\3\2\2\2\u01ff\u0200\3\2"+
"\2\2\u0200\u0201\7\35\2\2\u0201S\3\2\2\2\u0202\u0204\7\23\2\2\u0203\u0205"+
"\7t\2\2\u0204\u0203\3\2\2\2\u0204\u0205\3\2\2\2\u0205\u0206\3\2\2\2\u0206"+
"\u020e\5,\27\2\u0207\u0209\7\17\2\2\u0208\u020a\7t\2\2\u0209\u0208\3\2"+
"\2\2\u0209\u020a\3\2\2\2\u020a\u020b\3\2\2\2\u020b\u020d\5,\27\2\u020c"+
"\u0207\3\2\2\2\u020d\u0210\3\2\2\2\u020e\u020c\3\2\2\2\u020e\u020f\3\2"+
"\2\2\u020f\u0212\3\2\2\2\u0210\u020e\3\2\2\2\u0211\u0213\7t\2\2\u0212"+
"\u0211\3\2\2\2\u0212\u0213\3\2\2\2\u0213\u0214\3\2\2\2\u0214\u0215\7\24"+
"\2\2\u0215U\3\2\2\2\u0216\u0217\7{\2\2\u0217W\3\2\2\2\u0218\u0219\7}\2"+
"\2\u0219Y\3\2\2\2\u021a\u021b\7z\2\2\u021b[\3\2\2\2\u021c\u0224\5L\'\2"+
"\u021d\u0224\5P)\2\u021e\u0224\5R*\2\u021f\u0224\5V,\2\u0220\u0224\5X"+
"-\2\u0221\u0224\5Z.\2\u0222\u0224\5T+\2\u0223\u021c\3\2\2\2\u0223\u021d"+
"\3\2\2\2\u0223\u021e\3\2\2\2\u0223\u021f\3\2\2\2\u0223\u0220\3\2\2\2\u0223"+
"\u0221\3\2\2\2\u0223\u0222\3\2\2\2\u0224]\3\2\2\2\u0225\u0226\7W\2\2\u0226"+
"\u0227\7|\2\2\u0227_\3\2\2\2\u0228\u0229\7X\2\2\u0229\u022a\5B\"\2\u022a"+
"\u022c\7B\2\2\u022b\u022d\5f\64\2\u022c\u022b\3\2\2\2\u022c\u022d\3\2"+
"\2\2\u022d\u022e\3\2\2\2\u022e\u0230\7C\2\2\u022f\u0231\5b\62\2\u0230"+
"\u022f\3\2\2\2\u0230\u0231\3\2\2\2\u0231\u0232\3\2\2\2\u0232\u0233\5d"+
"\63\2\u0233\u0234\7t\2\2\u0234a\3\2\2\2\u0235\u0236\7Y\2\2\u0236\u0237"+
"\5h\65\2\u0237c\3\2\2\2\u0238\u0239\7\23\2\2\u0239\u023e\7t\2\2\u023a"+
"\u023d\5\b\5\2\u023b\u023d\7t\2\2\u023c\u023a\3\2\2\2\u023c\u023b\3\2"+
"\2\2\u023d\u0240\3\2\2\2\u023e\u023c\3\2\2\2\u023e\u023f\3\2\2\2\u023f"+
"\u0241\3\2\2\2\u0240\u023e\3\2\2\2\u0241\u0242\7\24\2\2\u0242e\3\2\2\2"+
"\u0243\u024b\5\22\n\2\u0244\u0246\7\17\2\2\u0245\u0247\7t\2\2\u0246\u0245"+
"\3\2\2\2\u0246\u0247\3\2\2\2\u0247\u0248\3\2\2\2\u0248\u024a\5\22\n\2"+
"\u0249\u0244\3\2\2\2\u024a\u024d\3\2\2\2\u024b\u0249\3\2\2\2\u024b\u024c"+
"\3\2\2\2\u024cg\3\2\2\2\u024d\u024b\3\2\2\2\u024e\u0256\5 \21\2\u024f"+
"\u0251\7\17\2\2\u0250\u0252\7t\2\2\u0251\u0250\3\2\2\2\u0251\u0252\3\2"+
"\2\2\u0252\u0253\3\2\2\2\u0253\u0255\5 \21\2\u0254\u024f\3\2\2\2\u0255"+
"\u0258\3\2\2\2\u0256\u0254\3\2\2\2\u0256\u0257\3\2\2\2\u0257i\3\2\2\2"+
"\u0258\u0256\3\2\2\2\u0259\u025a\7Z\2\2\u025a\u025b\5B\"\2\u025b\u025d"+
"\7B\2\2\u025c\u025e\5n8\2\u025d\u025c\3\2\2\2\u025d\u025e\3\2\2\2\u025e"+
"\u025f\3\2\2\2\u025f\u0261\7C\2\2\u0260\u0262\7t\2\2\u0261\u0260\3\2\2"+
"\2\u0261\u0262\3\2\2\2\u0262\u0264\3\2\2\2\u0263\u0265\5r:\2\u0264\u0263"+
"\3\2\2\2\u0264\u0265\3\2\2\2\u0265\u0267\3\2\2\2\u0266\u0268\5v<\2\u0267"+
"\u0266\3\2\2\2\u0267\u0268\3\2\2\2\u0268\u026b\3\2\2\2\u0269\u026c\5l"+
"\67\2\u026a\u026c\5d\63\2\u026b\u0269\3\2\2\2\u026b\u026a\3\2\2\2\u026c"+
"k\3\2\2\2\u026d\u026e\7\20\2\2\u026e\u026f\5L\'\2\u026fm\3\2\2\2\u0270"+
"\u0278\5p9\2\u0271\u0273\7\17\2\2\u0272\u0274\7t\2\2\u0273\u0272\3\2\2"+
"\2\u0273\u0274\3\2\2\2\u0274\u0275\3\2\2\2\u0275\u0277\5p9\2\u0276\u0271"+
"\3\2\2\2\u0277\u027a\3\2\2\2\u0278\u0276\3\2\2\2\u0278\u0279\3\2\2\2\u0279"+
"o\3\2\2\2\u027a\u0278\3\2\2\2\u027b\u027c\5\22\n\2\u027c\u0280\7E\2\2"+
"\u027d\u0281\5H%\2\u027e\u0281\5J&\2\u027f\u0281\7[\2\2\u0280\u027d\3"+
"\2\2\2\u0280\u027e\3\2\2\2\u0280\u027f\3\2\2\2\u0281q\3\2\2\2\u0282\u0283"+
"\7\\\2\2\u0283\u0285\7B\2\2\u0284\u0286\5t;\2\u0285\u0284\3\2\2\2\u0285"+
"\u0286\3\2\2\2\u0286\u0287\3\2\2\2\u0287\u0288\7C\2\2\u0288s\3\2\2\2\u0289"+
"\u028e\5F$\2\u028a\u028b\7\17\2\2\u028b\u028d\5F$\2\u028c\u028a\3\2\2"+
"\2\u028d\u0290\3\2\2\2\u028e\u028c\3\2\2\2\u028e\u028f\3\2\2\2\u028fu"+
"\3\2\2\2\u0290\u028e\3\2\2\2\u0291\u0292\7Y\2\2\u0292\u029a\5x=\2\u0293"+
"\u0295\7\17\2\2\u0294\u0296\7t\2\2\u0295\u0294\3\2\2\2\u0295\u0296\3\2"+
"\2\2\u0296\u0297\3\2\2\2\u0297\u0299\5x=\2\u0298\u0293\3\2\2\2\u0299\u029c"+
"\3\2\2\2\u029a\u0298\3\2\2\2\u029a\u029b\3\2\2\2\u029bw\3\2\2\2\u029c"+
"\u029a\3\2\2\2\u029d\u029e\5 \21\2\u029e\u02a2\7E\2\2\u029f\u02a3\5H%"+
"\2\u02a0\u02a3\5J&\2\u02a1\u02a3\7[\2\2\u02a2\u029f\3\2\2\2\u02a2\u02a0"+
"\3\2\2\2\u02a2\u02a1\3\2\2\2\u02a3y\3\2\2\2\u02a4\u02a5\7]\2\2\u02a5\u02a7"+
"\5,\27\2\u02a6\u02a8\7t\2\2\u02a7\u02a6\3\2\2\2\u02a7\u02a8\3\2\2\2\u02a8"+
"\u02ab\3\2\2\2\u02a9\u02ac\5\b\5\2\u02aa\u02ac\5d\63\2\u02ab\u02a9\3\2"+
"\2\2\u02ab\u02aa\3\2\2\2\u02ac\u02ae\3\2\2\2\u02ad\u02af\7t\2\2\u02ae"+
"\u02ad\3\2\2\2\u02ae\u02af\3\2\2\2\u02af\u02b1\3\2\2\2\u02b0\u02b2\5|"+
"?\2\u02b1\u02b0\3\2\2\2\u02b1\u02b2\3\2\2\2\u02b2{\3\2\2\2\u02b3\u02b5"+
"\7^\2\2\u02b4\u02b6\7t\2\2\u02b5\u02b4\3\2\2\2\u02b5\u02b6\3\2\2\2\u02b6"+
"\u02b9\3\2\2\2\u02b7\u02ba\5\b\5\2\u02b8\u02ba\5d\63\2\u02b9\u02b7\3\2"+
"\2\2\u02b9\u02b8\3\2\2\2\u02ba}\3\2\2\2\u02bb\u02bd\5\u0080A\2\u02bc\u02be"+
"\7t\2\2\u02bd\u02bc\3\2\2\2\u02bd\u02be\3\2\2\2\u02be\u02c1\3\2\2\2\u02bf"+
"\u02c2\5\b\5\2\u02c0\u02c2\5d\63\2\u02c1\u02bf\3\2\2\2\u02c1\u02c0\3\2"+
"\2\2\u02c2\u02c4\3\2\2\2\u02c3\u02c5\7t\2\2\u02c4\u02c3\3\2\2\2\u02c4"+
"\u02c5\3\2\2\2\u02c5\u02c7\3\2\2\2\u02c6\u02c8\5|?\2\u02c7\u02c6\3\2\2"+
"\2\u02c7\u02c8\3\2\2\2\u02c8\u02c9\3\2\2\2\u02c9\u02ca\7t\2\2\u02ca\177"+
"\3\2\2\2\u02cb\u02cc\t\21\2\2\u02cc\u0081\3\2\2\2\u02cd\u02d0\7k\2\2\u02ce"+
"\u02d1\5F$\2\u02cf\u02d1\5B\"\2\u02d0\u02ce\3\2\2\2\u02d0\u02cf\3\2\2"+
"\2\u02d1\u02d2\3\2\2\2\u02d2\u02d3\7l\2\2\u02d3\u02d5\5,\27\2\u02d4\u02d6"+
"\7t\2\2\u02d5\u02d4\3\2\2\2\u02d5\u02d6\3\2\2\2\u02d6\u02d9\3\2\2\2\u02d7"+
"\u02da\5\b\5\2\u02d8\u02da\5d\63\2\u02d9\u02d7\3\2\2\2\u02d9\u02d8\3\2"+
"\2\2\u02da\u0083\3\2\2\2\u02db\u02dc\7m\2\2\u02dc\u02de\5,\27\2\u02dd"+
"\u02df\7t\2\2\u02de\u02dd\3\2\2\2\u02de\u02df\3\2\2\2\u02df\u02e2\3\2"+
"\2\2\u02e0\u02e3\5\b\5\2\u02e1\u02e3\5d\63\2\u02e2\u02e0\3\2\2\2\u02e2"+
"\u02e1\3\2\2\2\u02e3\u0085\3\2\2\2\u02e4\u02e7\7n\2\2\u02e5\u02e8\5\b"+
"\5\2\u02e6\u02e8\5d\63\2\u02e7\u02e5\3\2\2\2\u02e7\u02e6\3\2\2\2\u02e8"+
"\u02ea\3\2\2\2\u02e9\u02eb\7t\2\2\u02ea\u02e9\3\2\2\2\u02ea\u02eb\3\2"+
"\2\2\u02eb\u02ec\3\2\2\2\u02ec\u02ed\7o\2\2\u02ed\u02ee\5,\27\2\u02ee"+
"\u0087\3\2\2\2\u02ef\u02f0\7p\2\2\u02f0\u02f1\5,\27\2\u02f1\u02f2\7\23"+
"\2\2\u02f2\u02f7\7t\2\2\u02f3\u02f6\5\u008aF\2\u02f4\u02f6\7t\2\2\u02f5"+
"\u02f3\3\2\2\2\u02f5\u02f4\3\2\2\2\u02f6\u02f9\3\2\2\2\u02f7\u02f5\3\2"+
"\2\2\u02f7\u02f8\3\2\2\2\u02f8\u02fa\3\2\2\2\u02f9\u02f7\3\2\2\2\u02fa"+
"\u02fc\7\24\2\2\u02fb\u02fd\7t\2\2\u02fc\u02fb\3\2\2\2\u02fc\u02fd\3\2"+
"\2\2\u02fd\u0089\3\2\2\2\u02fe\u0301\5:\36\2\u02ff\u0301\7^\2\2\u0300"+
"\u02fe\3\2\2\2\u0300\u02ff\3\2\2\2\u0301\u0302\3\2\2\2\u0302\u0305\7Y"+
"\2\2\u0303\u0306\5\b\5\2\u0304\u0306\5d\63\2\u0305\u0303\3\2\2\2\u0305"+
"\u0304\3\2\2\2\u0306\u008b\3\2\2\2h\u008e\u0090\u0097\u009b\u00ba\u00c2"+
"\u00c6\u00cd\u00d0\u00d5\u00d9\u00dd\u00fb\u00ff\u0116\u012b\u012f\u0133"+
"\u0138\u013c\u0141\u0145\u014a\u014e\u0153\u0157\u015c\u0160\u0165\u0169"+
"\u016e\u0172\u0177\u017b\u0180\u0184\u0189\u018d\u0192\u0196\u019e\u01a2"+
@@ -5572,8 +5545,7 @@ public class prog8Parser extends Parser {
"\u0204\u0209\u020e\u0212\u0223\u022c\u0230\u023c\u023e\u0246\u024b\u0251"+
"\u0256\u025d\u0261\u0264\u0267\u026b\u0273\u0278\u0280\u0285\u028e\u0295"+
"\u029a\u02a2\u02a7\u02ab\u02ae\u02b1\u02b5\u02b9\u02bd\u02c1\u02c4\u02c7"+
"\u02cf\u02d2\u02d6\u02db\u02df\u02e4\u02e8\u02ed\u02f0\u02fb\u02fd\u0302"+
"\u0306\u030b";
"\u02d0\u02d5\u02d9\u02de\u02e2\u02e7\u02ea\u02f5\u02f7\u02fc\u0300\u0305";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env sh
rm *.jar *.asm *.prg *.vm.txt *.vice-mon-list
rm -f *.jar *.asm *.prg *.vm.txt *.vice-mon-list
rm -rf build out