changed subroutine syntax and fixed array/matrix initalizer values

This commit is contained in:
Irmen de Jong 2018-09-30 18:49:58 +02:00
parent 505de87f27
commit 02075f2cf2
12 changed files with 1132 additions and 1378 deletions

View File

@ -162,8 +162,6 @@ scoped_identifier : NAME ('.' NAME)+ ;
register : 'A' | 'X' | 'Y' | 'AX' | 'AY' | 'XY' ;
statusflag : 'Pc' | 'Pz' | 'Pn' | 'Pv' ;
integerliteral : intpart=(DEC_INTEGER | HEX_INTEGER | BIN_INTEGER) wordsuffix? ;
wordsuffix : '.w' ;
@ -188,9 +186,11 @@ inlineasm : '%asm' INLINEASMBLOCK;
subroutine :
'sub' identifier '(' sub_params? ')' '->' '(' sub_returns? ')' (sub_address | (statement_block EOL))
'sub' identifier '(' sub_params? ')' sub_return_part? (sub_address | (statement_block EOL))
;
sub_return_part : '->' sub_returns ;
statement_block :
'{' EOL
(statement | EOL) *
@ -201,11 +201,9 @@ sub_address : '=' integerliteral ;
sub_params : sub_param (',' sub_param)* ;
sub_param: identifier ':' (register | statusflag);
sub_param: identifier ':' datatype;
sub_returns : '?' | ( sub_return (',' sub_return)* ) ;
sub_return: (register | statusflag) '?'? ;
sub_returns : datatype (',' datatype)* ;
if_stmt : 'if' expression EOL? (statement | statement_block) EOL? else_part? EOL ; // statement is constrained later

View File

@ -2,7 +2,7 @@
~ main {
sub start() -> () {
sub start() {
const word width = 320 // 2
const word height = 256 // 2
@ -60,7 +60,7 @@
memory byte jiffyclockMid = $a1
memory byte jiffyclockLo = $a2
sub irq() -> () {
sub irq() {
_vm_gfx_pixel(jiffyclockLo,190,jiffyclockHi)
_vm_gfx_pixel(jiffyclockLo,191,jiffyclockMid)
_vm_gfx_pixel(jiffyclockLo,192,jiffyclockLo)

View File

@ -1,33 +1,20 @@
%option enable_floats
~ main {
sub start() -> () {
str msg1 = "abc"
str msg2 = "abc"
str msg3 = "abc123"
str_p msg4 = "abc"
byte[5] array1 = 0
byte[5] array2 = 222
byte[6] array3 = [1,2,3,4,5,66]
word[5] array4 = 333
word[5] array5 = [1,2,3,4,59999]
word[5] array6 = [1,2,3,4,5]
word[5] array7 = [1,2,3,4,999+22/33]
byte[2,3] matrix1 = [1,2, 3,4, 5,6]
byte[2,3] matrix2 = [1,2, 3,4, 5,6]
byte[2,3] matrix3 = [11,22, 33,44, 55,66]
byte num1 = sin(2.0)
word num2 = rndw()
float num3 = 98.555
sub start() {
byte bvar
word wvar
float fvar
str svar = "svar"
str_p spvar = "spvar"
str_s ssvar = "ssvar"
str_ps spsvar = "spsvar"
byte[2,3] matrixvar1
byte[2,3] matrixvar2 = 2
byte[5] barrayvar
byte[5] barrayvar1 = 44
word[5] warrayvar
word[5] warrayvar1 = 22
num1=rnd()
num1=thing()
return
sub thing() -> (X) {
return 99
}
}
}

View File

@ -864,9 +864,8 @@ class LiteralValue(val type: DataType,
DataType.FLOAT -> if(floatvalue==null) throw FatalAstException("literal value missing floatvalue")
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS ->
if(strvalue==null && heapId==null) throw FatalAstException("literal value missing strvalue/heapId")
DataType.ARRAY, DataType.ARRAY_W ->
DataType.ARRAY, DataType.ARRAY_W, DataType.MATRIX ->
if(arrayvalue==null && heapId==null) throw FatalAstException("literal value missing arrayvalue/heapId")
DataType.MATRIX -> TODO("matrix literalvalue? for now, arrays are good enough for this")
}
if(bytevalue==null && wordvalue==null && floatvalue==null && arrayvalue==null && strvalue==null && heapId==null)
throw FatalAstException("literal value without actual value")
@ -1196,20 +1195,10 @@ class FunctionCall(override var target: IdentifierReference,
return builtinFunctionReturnType(target.nameInSource[0], this.arglist, namespace, heap)
}
is Subroutine -> {
if(stmt.returnvalues.isEmpty()) {
if(stmt.returnvalues.isEmpty())
return null // no return value
}
if(stmt.returnvalues.size==1) {
if(stmt.returnvalues[0].register!=null) {
return when(stmt.returnvalues[0].register!!) {
Register.A, Register.X, Register.Y -> DataType.BYTE
Register.AX, Register.AY, Register.XY -> DataType.WORD
}
} else if(stmt.returnvalues[0].statusflag!=null) {
val flag = stmt.returnvalues[0].statusflag!!
TODO("return value in status flag $flag")
}
}
if(stmt.returnvalues.size==1)
return stmt.returnvalues[0]
TODO("return type for subroutine with multiple return values $stmt")
}
is Label -> return null
@ -1253,7 +1242,7 @@ class InlineAssembly(val assembly: String, override val position: Position) : IS
class Subroutine(override val name: String,
val parameters: List<SubroutineParameter>,
val returnvalues: List<SubroutineReturnvalue>,
val returnvalues: List<DataType>,
val address: Int?,
override var statements: MutableList<IStatement>,
override val position: Position) : IStatement, INameScope {
@ -1264,7 +1253,6 @@ class Subroutine(override val name: String,
override fun linkParents(parent: Node) {
this.parent = parent
parameters.forEach { it.linkParents(this) }
returnvalues.forEach { it.linkParents(this) }
statements.forEach { it.linkParents(this) }
}
@ -1279,32 +1267,13 @@ class Subroutine(override val name: String,
data class SubroutineParameter(val name: String,
val register: Register?,
val statusflag: Statusflag?,
val type: DataType,
override val position: Position) : Node {
override lateinit var parent: Node
override fun linkParents(parent: Node) {
this.parent = parent
}
val type = when(register) {
Register.A, Register.X, Register.Y -> DataType.BYTE
Register.AX, Register.AY, Register.XY -> DataType.WORD
null -> DataType.BYTE
}
}
data class SubroutineReturnvalue(val register: Register?,
val statusflag: Statusflag?,
val clobbered: Boolean,
override val position: Position) : Node {
override lateinit var parent: Node
override fun linkParents(parent: Node) {
this.parent = parent
}
}
@ -1580,23 +1549,21 @@ private fun prog8Parser.LabeldefContext.toAst(): IStatement =
private fun prog8Parser.SubroutineContext.toAst() : Subroutine {
return Subroutine(identifier().text,
if(sub_params() ==null) emptyList() else sub_params().toAst(),
if(sub_returns() ==null) emptyList() else sub_returns().toAst(),
if(sub_return_part() == null) emptyList() else sub_return_part().toAst(),
sub_address()?.integerliteral()?.toAst()?.number?.toInt(),
if(statement_block() ==null) mutableListOf() else statement_block().toAst(),
toPosition())
}
private fun prog8Parser.Sub_return_partContext.toAst(): List<DataType> {
val returns = sub_returns() ?: return emptyList()
return returns.datatype().map { it.toAst() }
}
private fun prog8Parser.Sub_paramsContext.toAst(): List<SubroutineParameter> =
sub_param().map {
SubroutineParameter(it.identifier().text, it.register()?.toAst(), it.statusflag()?.toAst(), it.toPosition())
}
private fun prog8Parser.Sub_returnsContext.toAst(): List<SubroutineReturnvalue> =
sub_return().map {
val isClobber = it.childCount==2 && it.children[1].text == "?"
SubroutineReturnvalue(it.register()?.toAst(), it.statusflag()?.toAst(), isClobber, it.toPosition())
SubroutineParameter(it.identifier().text, it.datatype().toAst(), it.toPosition())
}
@ -1612,8 +1579,6 @@ private fun prog8Parser.Assign_targetContext.toAst() : AssignTarget {
private fun prog8Parser.RegisterContext.toAst() = Register.valueOf(text.toUpperCase())
private fun prog8Parser.StatusflagContext.toAst() = Statusflag.valueOf(text)
private fun prog8Parser.DatatypeContext.toAst() = DataType.valueOf(text.toUpperCase())

View File

@ -185,13 +185,6 @@ class AstChecker(private val namespace: INameScope,
val uniqueNames = subroutine.parameters.asSequence().map { it.name }.toSet()
if(uniqueNames.size!=subroutine.parameters.size)
err("parameter names must be unique")
val uniqueParamRegs = subroutine.parameters.asSequence().map {it.register}.toSet()
if(uniqueParamRegs.size!=subroutine.parameters.size)
err("parameter registers must be unique")
val uniqueResultRegisters = subroutine.returnvalues.asSequence().filter{it.register!=null}.map {it.register.toString()}.toMutableSet()
uniqueResultRegisters.addAll(subroutine.returnvalues.asSequence().filter{it.statusflag!=null}.map{it.statusflag.toString()}.toList())
if(uniqueResultRegisters.size!=subroutine.returnvalues.size)
err("return registers must be unique")
super.process(subroutine)
checkSubroutinesPrecededByReturnOrJumpAndFollowedByLabelOrSub(subroutine.statements)
@ -330,13 +323,14 @@ class AstChecker(private val namespace: INameScope,
when(decl.type) {
VarDeclType.VAR, VarDeclType.CONST -> {
if (decl.value == null) {
if(decl.datatype == DataType.BYTE || decl.datatype==DataType.WORD || decl.datatype==DataType.FLOAT) {
// initialize numeric var with value zero by default.
val litVal = LiteralValue(DataType.BYTE, 0, position = decl.position)
litVal.parent = decl
decl.value = litVal
} else {
err("var/const declaration needs a compile-time constant initializer value for this type")
when {
decl.datatype == DataType.BYTE || decl.datatype==DataType.WORD || decl.datatype==DataType.FLOAT -> {
// initialize numeric var with value zero by default.
val litVal = LiteralValue(DataType.BYTE, 0, position = decl.position)
litVal.parent = decl
decl.value = litVal
}
else -> err("var/const declaration needs a compile-time constant initializer value for this type")
}
return super.process(decl)
}
@ -688,7 +682,7 @@ class AstChecker(private val namespace: INameScope,
}
DataType.MATRIX -> {
// value can only be a single byte, or a byte array (which represents the matrix)
if(value.type==DataType.ARRAY) {
if(value.type==DataType.ARRAY || value.type==DataType.MATRIX) {
val constX = arrayspec!!.x.constValue(namespace, heap)
val constY = arrayspec.y!!.constValue(namespace, heap)
if(constX?.asIntegerValue==null || constY?.asIntegerValue==null)

View File

@ -505,17 +505,8 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
}
fun translateSubroutineCall(subroutine: Subroutine, arguments: List<IExpression>, parent: Node) {
// setup the arguments: simply put them into the register vars
// @todo support other types of parameters beside just registers
for(param in arguments.zip(subroutine.parameters)) {
val assign = Assignment(
AssignTarget(param.second.register, null, param.first.position),
null,
param.first,
param.first.position
)
assign.linkParents(parent)
translate(assign)
// @todo push params onto stack in correct order
}
stackvmProg.instr(Opcode.CALL, callLabel=subroutine.scopedname)
}
@ -677,16 +668,7 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
private fun translate(stmt: Return) {
val returnvalues = (stmt.definingScope() as? Subroutine)?.returnvalues ?: emptyList()
for(value in stmt.values.zip(returnvalues)) {
// assign the return values to the proper result registers
// @todo support other things than just result registers
val assign = Assignment(
AssignTarget(value.second.register, null, stmt.position),
null,
value.first,
stmt.position
)
assign.linkParents(stmt.parent)
translate(assign)
// @todo assign the return values to the proper return variables
}
stackvmProg.line(stmt.position)
stackvmProg.instr(Opcode.RETURN)

View File

@ -7,14 +7,15 @@ import kotlin.math.log2
class FunctionSignature(val pure: Boolean, // does it have side effects?
val parameters: List<SubroutineParameter>,
val returnvalues: List<SubroutineReturnvalue>,
val paramTypesVariable: Boolean,
val returnvalues: List<DataType>,
val type: DataType?,
val expressionFunc: ((args: List<IExpression>, position: Position, namespace: INameScope, heap: HeapValues) -> LiteralValue)?) {
companion object {
private val dummyPos = Position("dummy", 0, 0, 0)
fun sig(pure: Boolean,
args: List<String>,
args: List<Pair<String, DataType?>>,
hasReturnValue: Boolean,
type: DataType?,
expressionFunc: ((args: List<IExpression>, position: Position, namespace: INameScope, heap: HeapValues) -> LiteralValue)? = null
@ -22,9 +23,10 @@ class FunctionSignature(val pure: Boolean, // does it have side effects?
if(!hasReturnValue && expressionFunc!=null)
throw IllegalArgumentException("can't have expression func when hasReturnValue is false")
return FunctionSignature(pure,
args.map { SubroutineParameter(it, null, null, dummyPos) },
if(hasReturnValue)
listOf(SubroutineReturnvalue(null, null, false, dummyPos))
args.map { SubroutineParameter(it.first, it.second ?: DataType.BYTE, dummyPos) },
args.any { it.second==null },
if(hasReturnValue && type!=null)
listOf(type)
else
emptyList(),
type,
@ -40,41 +42,41 @@ val BuiltinFunctions = mapOf(
"clear_carry" to FunctionSignature.sig(false, emptyList(), false, null),
"set_irqd" to FunctionSignature.sig(false, emptyList(), false, null),
"clear_irqd" to FunctionSignature.sig(false, emptyList(), false, null),
"rol" to FunctionSignature.sig(false, listOf("item"), false, null),
"ror" to FunctionSignature.sig(false, listOf("item"), false, null),
"rol2" to FunctionSignature.sig(false, listOf("item"), false, null),
"ror2" to FunctionSignature.sig(false, listOf("item"), false, null),
"lsl" to FunctionSignature.sig(false, listOf("item"), false, null),
"lsr" to FunctionSignature.sig(false, listOf("item"), false, null),
"sin" to FunctionSignature.sig(true, listOf("rads"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sin) },
"cos" to FunctionSignature.sig(true, listOf("rads"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::cos) },
"acos" to FunctionSignature.sig(true, listOf("rads"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::acos) },
"asin" to FunctionSignature.sig(true, listOf("rads"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::asin) },
"tan" to FunctionSignature.sig(true, listOf("rads"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::tan) },
"atan" to FunctionSignature.sig(true, listOf("rads"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::atan) },
"rol" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
"ror" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
"rol2" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
"ror2" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
"lsl" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
"lsr" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
"sin" to FunctionSignature.sig(true, listOf(Pair("rads", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sin) },
"cos" to FunctionSignature.sig(true, listOf(Pair("rads", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::cos) },
"acos" to FunctionSignature.sig(true, listOf(Pair("rads", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::acos) },
"asin" to FunctionSignature.sig(true, listOf(Pair("rads", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::asin) },
"tan" to FunctionSignature.sig(true, listOf(Pair("rads", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::tan) },
"atan" to FunctionSignature.sig(true, listOf(Pair("rads", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::atan) },
"rnd" to FunctionSignature.sig(true, emptyList(), true, DataType.BYTE),
"rndw" to FunctionSignature.sig(true, emptyList(), true, DataType.WORD),
"rndf" to FunctionSignature.sig(true, emptyList(), true, DataType.FLOAT),
"ln" to FunctionSignature.sig(true, listOf("value"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log) },
"log2" to FunctionSignature.sig(true, listOf("value"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, ::log2) },
"log10" to FunctionSignature.sig(true, listOf("value"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log10) },
"sqrt" to FunctionSignature.sig(true, listOf("value"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sqrt) },
"rad" to FunctionSignature.sig(true, listOf("value"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toRadians) },
"deg" to FunctionSignature.sig(true, listOf("value"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toDegrees) },
"avg" to FunctionSignature.sig(true, listOf("values"), true, DataType.FLOAT, ::builtinAvg),
"abs" to FunctionSignature.sig(true, listOf("value"), true, null, ::builtinAbs), // type depends on arg
"round" to FunctionSignature.sig(true, listOf("value"), true, null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::round) }, // type depends on arg
"floor" to FunctionSignature.sig(true, listOf("value"), true, null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::floor) }, // type depends on arg
"ceil" to FunctionSignature.sig(true, listOf("value"), true, null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::ceil) }, // type depends on arg
"max" to FunctionSignature.sig(true, listOf("values"), true, null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.max()!! }}, // type depends on args
"min" to FunctionSignature.sig(true, listOf("values"), true, null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.min()!! }}, // type depends on args
"sum" to FunctionSignature.sig(true, listOf("values"), true, null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.sum() }}, // type depends on args
"len" to FunctionSignature.sig(true, listOf("values"), true, null, ::builtinLen), // type depends on args
"any" to FunctionSignature.sig(true, listOf("values"), true, DataType.BYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.any { v -> v != 0.0} }},
"all" to FunctionSignature.sig(true, listOf("values"), true, DataType.BYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.all { v -> v != 0.0} }},
"lsb" to FunctionSignature.sig(true, listOf("value"), true, DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x and 255 }},
"msb" to FunctionSignature.sig(true, listOf("value"), true, DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x ushr 8 and 255}},
"flt" to FunctionSignature.sig(true, listOf("value"), true, DataType.FLOAT, ::builtinFlt),
"ln" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log) },
"log2" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, ::log2) },
"log10" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log10) },
"sqrt" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sqrt) },
"rad" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toRadians) },
"deg" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toDegrees) },
"avg" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, DataType.FLOAT, ::builtinAvg),
"abs" to FunctionSignature.sig(true, listOf(Pair("value", null)), true, null, ::builtinAbs), // type depends on arg
"round" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::round) }, // type depends on arg
"floor" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::floor) }, // type depends on arg
"ceil" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::ceil) }, // type depends on arg
"max" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.max()!! }}, // type depends on args
"min" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.min()!! }}, // type depends on args
"sum" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.sum() }}, // type depends on args
"len" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, null, ::builtinLen), // type depends on args
"any" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, DataType.BYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.any { v -> v != 0.0} }},
"all" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, DataType.BYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.all { v -> v != 0.0} }},
"lsb" to FunctionSignature.sig(true, listOf(Pair("value", DataType.WORD)), true, DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x and 255 }},
"msb" to FunctionSignature.sig(true, listOf(Pair("value", DataType.WORD)), true, DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x ushr 8 and 255}},
"flt" to FunctionSignature.sig(true, listOf(Pair("value", null)), true, DataType.FLOAT, ::builtinFlt),
"_vm_write_memchr" to FunctionSignature.sig(false, emptyList(), false, null),
"_vm_write_memstr" to FunctionSignature.sig(false, emptyList(), false, null),
"_vm_write_num" to FunctionSignature.sig(false, emptyList(), false, null),

View File

@ -49,39 +49,15 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
decl.value = newValue
}
}
DataType.MATRIX -> {
(decl.value as? LiteralValue)?.let {
val intvalue = it.asIntegerValue
if(intvalue!=null) {
// replace the single int value by a properly sized array to fill the matrix.
val size = decl.arrayspec!!.size()
if(size!=null) {
val newArray = Array<IExpression>(size) { _ -> LiteralValue(DataType.BYTE, bytevalue = intvalue.toShort(), position = it.position) }
decl.value = LiteralValue(DataType.ARRAY, arrayvalue = newArray, position = it.position)
} else {
addError(SyntaxError("matrix size spec must be constant integer values", it.position))
}
}
}
}
DataType.ARRAY, DataType.ARRAY_W -> {
(decl.value as? LiteralValue)?.let {
val intvalue = it.asIntegerValue
if(intvalue!=null) {
// replace the single int value by a properly sized array to fill the array with.
val size = decl.arrayspec!!.size()
if(size!=null) {
val newArray = Array<IExpression>(size) { _ ->
if (decl.datatype == DataType.ARRAY)
LiteralValue(DataType.BYTE, bytevalue = intvalue.toShort(), position = it.position)
else
LiteralValue(DataType.WORD, wordvalue = intvalue, position = it.position)
}
decl.value = LiteralValue(decl.datatype, arrayvalue = newArray, position=it.position)
} else {
addError(SyntaxError("array size must be a constant integer value", it.position))
}
}
DataType.ARRAY, DataType.ARRAY_W, DataType.MATRIX -> {
val litval = decl.value as? LiteralValue
val size = decl.arrayspec!!.size()
if (size != null) {
val fillvalue = if (litval == null) 0 else litval.asIntegerValue ?: 0
val fillArray = IntArray(size) { _ -> fillvalue }
val heapId = heap.add(decl.datatype, fillArray)
val valType = if(decl.datatype==DataType.MATRIX) DataType.ARRAY else decl.datatype
decl.value = LiteralValue(valType, heapId = heapId, position = litval?.position ?: decl.position)
}
}
else -> return result
@ -90,6 +66,21 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
return result
}
private fun createArrayInitValue(decl: VarDecl, intvalue: Int, position: Position) {
val size = decl.arrayspec!!.size()
if (size != null) {
val newArray = Array<IExpression>(size) { _ ->
if (decl.datatype == DataType.ARRAY)
LiteralValue(DataType.BYTE, bytevalue = intvalue.toShort(), position = position)
else
LiteralValue(DataType.WORD, wordvalue = intvalue, position = position)
}
decl.value = LiteralValue(decl.datatype, arrayvalue = newArray, position = position)
} else {
addError(SyntaxError("array size must be a constant integer value", position))
}
}
/**
* replace identifiers that refer to const value, with the value itself
*/

View File

@ -1,12 +1,13 @@
// Generated from /home/irmen/Projects/prog8/compiler/antlr/prog8.g4 by ANTLR 4.7
package prog8.parser;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.atn.ATNDeserializer;
import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.atn.PredictionContextCache;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class prog8Lexer extends Lexer {
@ -29,9 +30,9 @@ public class prog8Lexer extends Lexer {
T__73=74, T__74=75, T__75=76, T__76=77, T__77=78, T__78=79, T__79=80,
T__80=81, T__81=82, T__82=83, T__83=84, T__84=85, T__85=86, T__86=87,
T__87=88, T__88=89, T__89=90, T__90=91, T__91=92, T__92=93, T__93=94,
T__94=95, T__95=96, T__96=97, T__97=98, T__98=99, T__99=100, T__100=101,
T__101=102, LINECOMMENT=103, COMMENT=104, WS=105, EOL=106, NAME=107, DEC_INTEGER=108,
HEX_INTEGER=109, BIN_INTEGER=110, FLOAT_NUMBER=111, STRING=112, INLINEASMBLOCK=113;
T__94=95, T__95=96, T__96=97, LINECOMMENT=98, COMMENT=99, WS=100, EOL=101,
NAME=102, DEC_INTEGER=103, HEX_INTEGER=104, BIN_INTEGER=105, FLOAT_NUMBER=106,
STRING=107, INLINEASMBLOCK=108;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
@ -53,9 +54,9 @@ public class prog8Lexer extends Lexer {
"T__73", "T__74", "T__75", "T__76", "T__77", "T__78", "T__79", "T__80",
"T__81", "T__82", "T__83", "T__84", "T__85", "T__86", "T__87", "T__88",
"T__89", "T__90", "T__91", "T__92", "T__93", "T__94", "T__95", "T__96",
"T__97", "T__98", "T__99", "T__100", "T__101", "LINECOMMENT", "COMMENT",
"WS", "EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER", "BIN_INTEGER", "FLOAT_NUMBER",
"FNUMBER", "STRING_ESCAPE_SEQ", "STRING", "INLINEASMBLOCK"
"LINECOMMENT", "COMMENT", "WS", "EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER",
"BIN_INTEGER", "FLOAT_NUMBER", "FNUMBER", "STRING_ESCAPE_SEQ", "STRING",
"INLINEASMBLOCK"
};
private static final String[] _LITERAL_NAMES = {
@ -67,11 +68,11 @@ public class prog8Lexer extends Lexer {
"'--'", "'('", "')'", "'+'", "'-'", "'**'", "'*'", "'/'", "'//'", "'%'",
"'<'", "'>'", "'<='", "'>='", "'=='", "'!='", "'&'", "'^'", "'|'", "'to'",
"'step'", "'and'", "'or'", "'xor'", "'not'", "'return'", "'break'", "'continue'",
"'.'", "'A'", "'X'", "'Y'", "'AX'", "'AY'", "'XY'", "'Pc'", "'Pz'", "'Pn'",
"'Pv'", "'.w'", "'true'", "'false'", "'%asm'", "'sub'", "'->'", "'{'",
"'}'", "'?'", "'if'", "'else'", "'if_cs'", "'if_cc'", "'if_eq'", "'if_z'",
"'if_ne'", "'if_nz'", "'if_pl'", "'if_pos'", "'if_mi'", "'if_neg'", "'if_vs'",
"'if_vc'", "'for'", "'in'", "'while'", "'repeat'", "'until'"
"'.'", "'A'", "'X'", "'Y'", "'AX'", "'AY'", "'XY'", "'.w'", "'true'",
"'false'", "'%asm'", "'sub'", "'->'", "'{'", "'}'", "'if'", "'else'",
"'if_cs'", "'if_cc'", "'if_eq'", "'if_z'", "'if_ne'", "'if_nz'", "'if_pl'",
"'if_pos'", "'if_mi'", "'if_neg'", "'if_vs'", "'if_vc'", "'for'", "'in'",
"'while'", "'repeat'", "'until'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, null, null, null, null, null, null, null, null,
@ -82,9 +83,8 @@ public class prog8Lexer extends Lexer {
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, "LINECOMMENT", "COMMENT", "WS",
"EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER", "BIN_INTEGER", "FLOAT_NUMBER",
"STRING", "INLINEASMBLOCK"
null, null, "LINECOMMENT", "COMMENT", "WS", "EOL", "NAME", "DEC_INTEGER",
"HEX_INTEGER", "BIN_INTEGER", "FLOAT_NUMBER", "STRING", "INLINEASMBLOCK"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
@ -146,10 +146,10 @@ public class prog8Lexer extends Lexer {
@Override
public void action(RuleContext _localctx, int ruleIndex, int actionIndex) {
switch (ruleIndex) {
case 113:
case 108:
STRING_action((RuleContext)_localctx, actionIndex);
break;
case 114:
case 109:
INLINEASMBLOCK_action((RuleContext)_localctx, actionIndex);
break;
}
@ -178,7 +178,7 @@ public class prog8Lexer extends Lexer {
}
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2s\u0314\b\1\4\2\t"+
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2n\u02fc\b\1\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"+
@ -190,255 +190,247 @@ public class prog8Lexer extends Lexer {
"\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+
"\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_\4"+
"`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k\t"+
"k\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\3\2\3\2\3\3\3"+
"\3\3\4\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6"+
"\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3"+
"\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n"+
"\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13"+
"\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f"+
"\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\20"+
"\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22"+
"\3\22\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25"+
"\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27"+
"\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\32\3\32\3\33\3\33\3\33"+
"\3\34\3\34\3\34\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3 \3"+
" \3 \3 \3!\3!\3!\3\"\3\"\3\"\3#\3#\3#\3$\3$\3$\3%\3%\3%\3&\3&\3\'\3\'"+
"\3(\3(\3)\3)\3*\3*\3*\3+\3+\3,\3,\3-\3-\3-\3.\3.\3/\3/\3\60\3\60\3\61"+
"\3\61\3\61\3\62\3\62\3\62\3\63\3\63\3\63\3\64\3\64\3\64\3\65\3\65\3\66"+
"\3\66\3\67\3\67\38\38\38\39\39\39\39\39\3:\3:\3:\3:\3;\3;\3;\3<\3<\3<"+
"\3<\3=\3=\3=\3=\3>\3>\3>\3>\3>\3>\3>\3?\3?\3?\3?\3?\3?\3@\3@\3@\3@\3@"+
"\3@\3@\3@\3@\3A\3A\3B\3B\3C\3C\3D\3D\3E\3E\3E\3F\3F\3F\3G\3G\3G\3H\3H"+
"\3H\3I\3I\3I\3J\3J\3J\3K\3K\3K\3L\3L\3L\3M\3M\3M\3M\3M\3N\3N\3N\3N\3N"+
"\3N\3O\3O\3O\3O\3O\3P\3P\3P\3P\3Q\3Q\3Q\3R\3R\3S\3S\3T\3T\3U\3U\3U\3V"+
"\3V\3V\3V\3V\3W\3W\3W\3W\3W\3W\3X\3X\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Y\3Z"+
"\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3[\3[\3\\\3\\\3\\\3\\\3\\\3\\\3]\3]\3]\3]\3]"+
"\3]\3^\3^\3^\3^\3^\3^\3^\3_\3_\3_\3_\3_\3_\3`\3`\3`\3`\3`\3`\3`\3a\3a"+
"\3a\3a\3a\3a\3b\3b\3b\3b\3b\3b\3c\3c\3c\3c\3d\3d\3d\3e\3e\3e\3e\3e\3e"+
"\3f\3f\3f\3f\3f\3f\3f\3g\3g\3g\3g\3g\3g\3h\3h\7h\u02ab\nh\fh\16h\u02ae"+
"\13h\3h\3h\3h\3h\3i\3i\7i\u02b6\ni\fi\16i\u02b9\13i\3i\3i\3j\3j\3j\3j"+
"\3k\6k\u02c2\nk\rk\16k\u02c3\3l\3l\7l\u02c8\nl\fl\16l\u02cb\13l\3m\3m"+
"\3m\6m\u02d0\nm\rm\16m\u02d1\5m\u02d4\nm\3n\3n\6n\u02d8\nn\rn\16n\u02d9"+
"\3o\3o\6o\u02de\no\ro\16o\u02df\3p\3p\3p\5p\u02e5\np\3p\5p\u02e8\np\3"+
"q\6q\u02eb\nq\rq\16q\u02ec\3q\3q\6q\u02f1\nq\rq\16q\u02f2\5q\u02f5\nq"+
"\3r\3r\3r\3r\5r\u02fb\nr\3s\3s\3s\7s\u0300\ns\fs\16s\u0303\13s\3s\3s\3"+
"s\3t\3t\3t\3t\6t\u030c\nt\rt\16t\u030d\3t\3t\3t\3t\3t\3\u030d\2u\3\3\5"+
"\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21"+
"!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!"+
"A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s"+
";u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008f"+
"I\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3"+
"S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7"+
"]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cb"+
"g\u00cdh\u00cfi\u00d1j\u00d3k\u00d5l\u00d7m\u00d9n\u00dbo\u00ddp\u00df"+
"q\u00e1\2\u00e3\2\u00e5r\u00e7s\3\2\n\4\2\f\f\17\17\4\2\13\13\"\"\5\2"+
"C\\aac|\6\2\62;C\\aac|\5\2\62;CHch\4\2GGgg\4\2--//\6\2\f\f\16\17$$^^\2"+
"\u0322\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2"+
"\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3"+
"\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2"+
"\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2"+
"/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2"+
"\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2"+
"G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3"+
"\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2"+
"\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2"+
"m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3"+
"\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2"+
"\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2"+
"\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095"+
"\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2"+
"\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7"+
"\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2"+
"\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9"+
"\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf\3\2\2\2\2\u00c1\3\2\2"+
"\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb"+
"\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1\3\2\2\2\2\u00d3\3\2\2"+
"\2\2\u00d5\3\2\2\2\2\u00d7\3\2\2\2\2\u00d9\3\2\2\2\2\u00db\3\2\2\2\2\u00dd"+
"\3\2\2\2\2\u00df\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\3\u00e9\3\2\2"+
"\2\5\u00eb\3\2\2\2\7\u00ed\3\2\2\2\t\u00f2\3\2\2\2\13\u00fa\3\2\2\2\r"+
"\u0104\3\2\2\2\17\u010e\3\2\2\2\21\u0117\3\2\2\2\23\u011f\3\2\2\2\25\u012b"+
"\3\2\2\2\27\u0137\3\2\2\2\31\u0142\3\2\2\2\33\u014a\3\2\2\2\35\u014c\3"+
"\2\2\2\37\u014e\3\2\2\2!\u0154\3\2\2\2#\u015b\3\2\2\2%\u0160\3\2\2\2\'"+
"\u0165\3\2\2\2)\u016b\3\2\2\2+\u016f\3\2\2\2-\u0175\3\2\2\2/\u017b\3\2"+
"\2\2\61\u0182\3\2\2\2\63\u0184\3\2\2\2\65\u0186\3\2\2\2\67\u0189\3\2\2"+
"\29\u018c\3\2\2\2;\u018f\3\2\2\2=\u0193\3\2\2\2?\u0196\3\2\2\2A\u019a"+
"\3\2\2\2C\u019d\3\2\2\2E\u01a0\3\2\2\2G\u01a3\3\2\2\2I\u01a6\3\2\2\2K"+
"\u01a9\3\2\2\2M\u01ab\3\2\2\2O\u01ad\3\2\2\2Q\u01af\3\2\2\2S\u01b1\3\2"+
"\2\2U\u01b4\3\2\2\2W\u01b6\3\2\2\2Y\u01b8\3\2\2\2[\u01bb\3\2\2\2]\u01bd"+
"\3\2\2\2_\u01bf\3\2\2\2a\u01c1\3\2\2\2c\u01c4\3\2\2\2e\u01c7\3\2\2\2g"+
"\u01ca\3\2\2\2i\u01cd\3\2\2\2k\u01cf\3\2\2\2m\u01d1\3\2\2\2o\u01d3\3\2"+
"\2\2q\u01d6\3\2\2\2s\u01db\3\2\2\2u\u01df\3\2\2\2w\u01e2\3\2\2\2y\u01e6"+
"\3\2\2\2{\u01ea\3\2\2\2}\u01f1\3\2\2\2\177\u01f7\3\2\2\2\u0081\u0200\3"+
"\2\2\2\u0083\u0202\3\2\2\2\u0085\u0204\3\2\2\2\u0087\u0206\3\2\2\2\u0089"+
"\u0208\3\2\2\2\u008b\u020b\3\2\2\2\u008d\u020e\3\2\2\2\u008f\u0211\3\2"+
"\2\2\u0091\u0214\3\2\2\2\u0093\u0217\3\2\2\2\u0095\u021a\3\2\2\2\u0097"+
"\u021d\3\2\2\2\u0099\u0220\3\2\2\2\u009b\u0225\3\2\2\2\u009d\u022b\3\2"+
"\2\2\u009f\u0230\3\2\2\2\u00a1\u0234\3\2\2\2\u00a3\u0237\3\2\2\2\u00a5"+
"\u0239\3\2\2\2\u00a7\u023b\3\2\2\2\u00a9\u023d\3\2\2\2\u00ab\u0240\3\2"+
"\2\2\u00ad\u0245\3\2\2\2\u00af\u024b\3\2\2\2\u00b1\u0251\3\2\2\2\u00b3"+
"\u0257\3\2\2\2\u00b5\u025c\3\2\2\2\u00b7\u0262\3\2\2\2\u00b9\u0268\3\2"+
"\2\2\u00bb\u026e\3\2\2\2\u00bd\u0275\3\2\2\2\u00bf\u027b\3\2\2\2\u00c1"+
"\u0282\3\2\2\2\u00c3\u0288\3\2\2\2\u00c5\u028e\3\2\2\2\u00c7\u0292\3\2"+
"\2\2\u00c9\u0295\3\2\2\2\u00cb\u029b\3\2\2\2\u00cd\u02a2\3\2\2\2\u00cf"+
"\u02a8\3\2\2\2\u00d1\u02b3\3\2\2\2\u00d3\u02bc\3\2\2\2\u00d5\u02c1\3\2"+
"\2\2\u00d7\u02c5\3\2\2\2\u00d9\u02d3\3\2\2\2\u00db\u02d5\3\2\2\2\u00dd"+
"\u02db\3\2\2\2\u00df\u02e1\3\2\2\2\u00e1\u02ea\3\2\2\2\u00e3\u02fa\3\2"+
"\2\2\u00e5\u02fc\3\2\2\2\u00e7\u0307\3\2\2\2\u00e9\u00ea\7\u0080\2\2\u00ea"+
"\4\3\2\2\2\u00eb\u00ec\7<\2\2\u00ec\6\3\2\2\2\u00ed\u00ee\7i\2\2\u00ee"+
"\u00ef\7q\2\2\u00ef\u00f0\7v\2\2\u00f0\u00f1\7q\2\2\u00f1\b\3\2\2\2\u00f2"+
"\u00f3\7\'\2\2\u00f3\u00f4\7q\2\2\u00f4\u00f5\7w\2\2\u00f5\u00f6\7v\2"+
"\2\u00f6\u00f7\7r\2\2\u00f7\u00f8\7w\2\2\u00f8\u00f9\7v\2\2\u00f9\n\3"+
"\2\2\2\u00fa\u00fb\7\'\2\2\u00fb\u00fc\7n\2\2\u00fc\u00fd\7c\2\2\u00fd"+
"\u00fe\7w\2\2\u00fe\u00ff\7p\2\2\u00ff\u0100\7e\2\2\u0100\u0101\7j\2\2"+
"\u0101\u0102\7g\2\2\u0102\u0103\7t\2\2\u0103\f\3\2\2\2\u0104\u0105\7\'"+
"\2\2\u0105\u0106\7|\2\2\u0106\u0107\7g\2\2\u0107\u0108\7t\2\2\u0108\u0109"+
"\7q\2\2\u0109\u010a\7r\2\2\u010a\u010b\7c\2\2\u010b\u010c\7i\2\2\u010c"+
"\u010d\7g\2\2\u010d\16\3\2\2\2\u010e\u010f\7\'\2\2\u010f\u0110\7c\2\2"+
"\u0110\u0111\7f\2\2\u0111\u0112\7f\2\2\u0112\u0113\7t\2\2\u0113\u0114"+
"\7g\2\2\u0114\u0115\7u\2\2\u0115\u0116\7u\2\2\u0116\20\3\2\2\2\u0117\u0118"+
"\7\'\2\2\u0118\u0119\7k\2\2\u0119\u011a\7o\2\2\u011a\u011b\7r\2\2\u011b"+
"\u011c\7q\2\2\u011c\u011d\7t\2\2\u011d\u011e\7v\2\2\u011e\22\3\2\2\2\u011f"+
"\u0120\7\'\2\2\u0120\u0121\7d\2\2\u0121\u0122\7t\2\2\u0122\u0123\7g\2"+
"\2\u0123\u0124\7c\2\2\u0124\u0125\7m\2\2\u0125\u0126\7r\2\2\u0126\u0127"+
"\7q\2\2\u0127\u0128\7k\2\2\u0128\u0129\7p\2\2\u0129\u012a\7v\2\2\u012a"+
"\24\3\2\2\2\u012b\u012c\7\'\2\2\u012c\u012d\7c\2\2\u012d\u012e\7u\2\2"+
"\u012e\u012f\7o\2\2\u012f\u0130\7k\2\2\u0130\u0131\7p\2\2\u0131\u0132"+
"\7e\2\2\u0132\u0133\7n\2\2\u0133\u0134\7w\2\2\u0134\u0135\7f\2\2\u0135"+
"\u0136\7g\2\2\u0136\26\3\2\2\2\u0137\u0138\7\'\2\2\u0138\u0139\7c\2\2"+
"\u0139\u013a\7u\2\2\u013a\u013b\7o\2\2\u013b\u013c\7d\2\2\u013c\u013d"+
"\7k\2\2\u013d\u013e\7p\2\2\u013e\u013f\7c\2\2\u013f\u0140\7t\2\2\u0140"+
"\u0141\7{\2\2\u0141\30\3\2\2\2\u0142\u0143\7\'\2\2\u0143\u0144\7q\2\2"+
"\u0144\u0145\7r\2\2\u0145\u0146\7v\2\2\u0146\u0147\7k\2\2\u0147\u0148"+
"\7q\2\2\u0148\u0149\7p\2\2\u0149\32\3\2\2\2\u014a\u014b\7.\2\2\u014b\34"+
"\3\2\2\2\u014c\u014d\7?\2\2\u014d\36\3\2\2\2\u014e\u014f\7e\2\2\u014f"+
"\u0150\7q\2\2\u0150\u0151\7p\2\2\u0151\u0152\7u\2\2\u0152\u0153\7v\2\2"+
"\u0153 \3\2\2\2\u0154\u0155\7o\2\2\u0155\u0156\7g\2\2\u0156\u0157\7o\2"+
"\2\u0157\u0158\7q\2\2\u0158\u0159\7t\2\2\u0159\u015a\7{\2\2\u015a\"\3"+
"\2\2\2\u015b\u015c\7d\2\2\u015c\u015d\7{\2\2\u015d\u015e\7v\2\2\u015e"+
"\u015f\7g\2\2\u015f$\3\2\2\2\u0160\u0161\7y\2\2\u0161\u0162\7q\2\2\u0162"+
"\u0163\7t\2\2\u0163\u0164\7f\2\2\u0164&\3\2\2\2\u0165\u0166\7h\2\2\u0166"+
"\u0167\7n\2\2\u0167\u0168\7q\2\2\u0168\u0169\7c\2\2\u0169\u016a\7v\2\2"+
"\u016a(\3\2\2\2\u016b\u016c\7u\2\2\u016c\u016d\7v\2\2\u016d\u016e\7t\2"+
"\2\u016e*\3\2\2\2\u016f\u0170\7u\2\2\u0170\u0171\7v\2\2\u0171\u0172\7"+
"t\2\2\u0172\u0173\7a\2\2\u0173\u0174\7r\2\2\u0174,\3\2\2\2\u0175\u0176"+
"\7u\2\2\u0176\u0177\7v\2\2\u0177\u0178\7t\2\2\u0178\u0179\7a\2\2\u0179"+
"\u017a\7u\2\2\u017a.\3\2\2\2\u017b\u017c\7u\2\2\u017c\u017d\7v\2\2\u017d"+
"\u017e\7t\2\2\u017e\u017f\7a\2\2\u017f\u0180\7r\2\2\u0180\u0181\7u\2\2"+
"\u0181\60\3\2\2\2\u0182\u0183\7]\2\2\u0183\62\3\2\2\2\u0184\u0185\7_\2"+
"\2\u0185\64\3\2\2\2\u0186\u0187\7-\2\2\u0187\u0188\7?\2\2\u0188\66\3\2"+
"\2\2\u0189\u018a\7/\2\2\u018a\u018b\7?\2\2\u018b8\3\2\2\2\u018c\u018d"+
"\7\61\2\2\u018d\u018e\7?\2\2\u018e:\3\2\2\2\u018f\u0190\7\61\2\2\u0190"+
"\u0191\7\61\2\2\u0191\u0192\7?\2\2\u0192<\3\2\2\2\u0193\u0194\7,\2\2\u0194"+
"\u0195\7?\2\2\u0195>\3\2\2\2\u0196\u0197\7,\2\2\u0197\u0198\7,\2\2\u0198"+
"\u0199\7?\2\2\u0199@\3\2\2\2\u019a\u019b\7(\2\2\u019b\u019c\7?\2\2\u019c"+
"B\3\2\2\2\u019d\u019e\7~\2\2\u019e\u019f\7?\2\2\u019fD\3\2\2\2\u01a0\u01a1"+
"\7`\2\2\u01a1\u01a2\7?\2\2\u01a2F\3\2\2\2\u01a3\u01a4\7-\2\2\u01a4\u01a5"+
"\7-\2\2\u01a5H\3\2\2\2\u01a6\u01a7\7/\2\2\u01a7\u01a8\7/\2\2\u01a8J\3"+
"\2\2\2\u01a9\u01aa\7*\2\2\u01aaL\3\2\2\2\u01ab\u01ac\7+\2\2\u01acN\3\2"+
"\2\2\u01ad\u01ae\7-\2\2\u01aeP\3\2\2\2\u01af\u01b0\7/\2\2\u01b0R\3\2\2"+
"\2\u01b1\u01b2\7,\2\2\u01b2\u01b3\7,\2\2\u01b3T\3\2\2\2\u01b4\u01b5\7"+
",\2\2\u01b5V\3\2\2\2\u01b6\u01b7\7\61\2\2\u01b7X\3\2\2\2\u01b8\u01b9\7"+
"\61\2\2\u01b9\u01ba\7\61\2\2\u01baZ\3\2\2\2\u01bb\u01bc\7\'\2\2\u01bc"+
"\\\3\2\2\2\u01bd\u01be\7>\2\2\u01be^\3\2\2\2\u01bf\u01c0\7@\2\2\u01c0"+
"`\3\2\2\2\u01c1\u01c2\7>\2\2\u01c2\u01c3\7?\2\2\u01c3b\3\2\2\2\u01c4\u01c5"+
"\7@\2\2\u01c5\u01c6\7?\2\2\u01c6d\3\2\2\2\u01c7\u01c8\7?\2\2\u01c8\u01c9"+
"\7?\2\2\u01c9f\3\2\2\2\u01ca\u01cb\7#\2\2\u01cb\u01cc\7?\2\2\u01cch\3"+
"\2\2\2\u01cd\u01ce\7(\2\2\u01cej\3\2\2\2\u01cf\u01d0\7`\2\2\u01d0l\3\2"+
"\2\2\u01d1\u01d2\7~\2\2\u01d2n\3\2\2\2\u01d3\u01d4\7v\2\2\u01d4\u01d5"+
"\7q\2\2\u01d5p\3\2\2\2\u01d6\u01d7\7u\2\2\u01d7\u01d8\7v\2\2\u01d8\u01d9"+
"\7g\2\2\u01d9\u01da\7r\2\2\u01dar\3\2\2\2\u01db\u01dc\7c\2\2\u01dc\u01dd"+
"\7p\2\2\u01dd\u01de\7f\2\2\u01det\3\2\2\2\u01df\u01e0\7q\2\2\u01e0\u01e1"+
"\7t\2\2\u01e1v\3\2\2\2\u01e2\u01e3\7z\2\2\u01e3\u01e4\7q\2\2\u01e4\u01e5"+
"\7t\2\2\u01e5x\3\2\2\2\u01e6\u01e7\7p\2\2\u01e7\u01e8\7q\2\2\u01e8\u01e9"+
"\7v\2\2\u01e9z\3\2\2\2\u01ea\u01eb\7t\2\2\u01eb\u01ec\7g\2\2\u01ec\u01ed"+
"\7v\2\2\u01ed\u01ee\7w\2\2\u01ee\u01ef\7t\2\2\u01ef\u01f0\7p\2\2\u01f0"+
"|\3\2\2\2\u01f1\u01f2\7d\2\2\u01f2\u01f3\7t\2\2\u01f3\u01f4\7g\2\2\u01f4"+
"\u01f5\7c\2\2\u01f5\u01f6\7m\2\2\u01f6~\3\2\2\2\u01f7\u01f8\7e\2\2\u01f8"+
"\u01f9\7q\2\2\u01f9\u01fa\7p\2\2\u01fa\u01fb\7v\2\2\u01fb\u01fc\7k\2\2"+
"\u01fc\u01fd\7p\2\2\u01fd\u01fe\7w\2\2\u01fe\u01ff\7g\2\2\u01ff\u0080"+
"\3\2\2\2\u0200\u0201\7\60\2\2\u0201\u0082\3\2\2\2\u0202\u0203\7C\2\2\u0203"+
"\u0084\3\2\2\2\u0204\u0205\7Z\2\2\u0205\u0086\3\2\2\2\u0206\u0207\7[\2"+
"\2\u0207\u0088\3\2\2\2\u0208\u0209\7C\2\2\u0209\u020a\7Z\2\2\u020a\u008a"+
"\3\2\2\2\u020b\u020c\7C\2\2\u020c\u020d\7[\2\2\u020d\u008c\3\2\2\2\u020e"+
"\u020f\7Z\2\2\u020f\u0210\7[\2\2\u0210\u008e\3\2\2\2\u0211\u0212\7R\2"+
"\2\u0212\u0213\7e\2\2\u0213\u0090\3\2\2\2\u0214\u0215\7R\2\2\u0215\u0216"+
"\7|\2\2\u0216\u0092\3\2\2\2\u0217\u0218\7R\2\2\u0218\u0219\7p\2\2\u0219"+
"\u0094\3\2\2\2\u021a\u021b\7R\2\2\u021b\u021c\7x\2\2\u021c\u0096\3\2\2"+
"\2\u021d\u021e\7\60\2\2\u021e\u021f\7y\2\2\u021f\u0098\3\2\2\2\u0220\u0221"+
"\7v\2\2\u0221\u0222\7t\2\2\u0222\u0223\7w\2\2\u0223\u0224\7g\2\2\u0224"+
"\u009a\3\2\2\2\u0225\u0226\7h\2\2\u0226\u0227\7c\2\2\u0227\u0228\7n\2"+
"\2\u0228\u0229\7u\2\2\u0229\u022a\7g\2\2\u022a\u009c\3\2\2\2\u022b\u022c"+
"\7\'\2\2\u022c\u022d\7c\2\2\u022d\u022e\7u\2\2\u022e\u022f\7o\2\2\u022f"+
"\u009e\3\2\2\2\u0230\u0231\7u\2\2\u0231\u0232\7w\2\2\u0232\u0233\7d\2"+
"\2\u0233\u00a0\3\2\2\2\u0234\u0235\7/\2\2\u0235\u0236\7@\2\2\u0236\u00a2"+
"\3\2\2\2\u0237\u0238\7}\2\2\u0238\u00a4\3\2\2\2\u0239\u023a\7\177\2\2"+
"\u023a\u00a6\3\2\2\2\u023b\u023c\7A\2\2\u023c\u00a8\3\2\2\2\u023d\u023e"+
"\7k\2\2\u023e\u023f\7h\2\2\u023f\u00aa\3\2\2\2\u0240\u0241\7g\2\2\u0241"+
"\u0242\7n\2\2\u0242\u0243\7u\2\2\u0243\u0244\7g\2\2\u0244\u00ac\3\2\2"+
"\2\u0245\u0246\7k\2\2\u0246\u0247\7h\2\2\u0247\u0248\7a\2\2\u0248\u0249"+
"\7e\2\2\u0249\u024a\7u\2\2\u024a\u00ae\3\2\2\2\u024b\u024c\7k\2\2\u024c"+
"\u024d\7h\2\2\u024d\u024e\7a\2\2\u024e\u024f\7e\2\2\u024f\u0250\7e\2\2"+
"\u0250\u00b0\3\2\2\2\u0251\u0252\7k\2\2\u0252\u0253\7h\2\2\u0253\u0254"+
"\7a\2\2\u0254\u0255\7g\2\2\u0255\u0256\7s\2\2\u0256\u00b2\3\2\2\2\u0257"+
"\u0258\7k\2\2\u0258\u0259\7h\2\2\u0259\u025a\7a\2\2\u025a\u025b\7|\2\2"+
"\u025b\u00b4\3\2\2\2\u025c\u025d\7k\2\2\u025d\u025e\7h\2\2\u025e\u025f"+
"\7a\2\2\u025f\u0260\7p\2\2\u0260\u0261\7g\2\2\u0261\u00b6\3\2\2\2\u0262"+
"\u0263\7k\2\2\u0263\u0264\7h\2\2\u0264\u0265\7a\2\2\u0265\u0266\7p\2\2"+
"\u0266\u0267\7|\2\2\u0267\u00b8\3\2\2\2\u0268\u0269\7k\2\2\u0269\u026a"+
"\7h\2\2\u026a\u026b\7a\2\2\u026b\u026c\7r\2\2\u026c\u026d\7n\2\2\u026d"+
"\u00ba\3\2\2\2\u026e\u026f\7k\2\2\u026f\u0270\7h\2\2\u0270\u0271\7a\2"+
"\2\u0271\u0272\7r\2\2\u0272\u0273\7q\2\2\u0273\u0274\7u\2\2\u0274\u00bc"+
"\3\2\2\2\u0275\u0276\7k\2\2\u0276\u0277\7h\2\2\u0277\u0278\7a\2\2\u0278"+
"\u0279\7o\2\2\u0279\u027a\7k\2\2\u027a\u00be\3\2\2\2\u027b\u027c\7k\2"+
"\2\u027c\u027d\7h\2\2\u027d\u027e\7a\2\2\u027e\u027f\7p\2\2\u027f\u0280"+
"\7g\2\2\u0280\u0281\7i\2\2\u0281\u00c0\3\2\2\2\u0282\u0283\7k\2\2\u0283"+
"\u0284\7h\2\2\u0284\u0285\7a\2\2\u0285\u0286\7x\2\2\u0286\u0287\7u\2\2"+
"\u0287\u00c2\3\2\2\2\u0288\u0289\7k\2\2\u0289\u028a\7h\2\2\u028a\u028b"+
"\7a\2\2\u028b\u028c\7x\2\2\u028c\u028d\7e\2\2\u028d\u00c4\3\2\2\2\u028e"+
"\u028f\7h\2\2\u028f\u0290\7q\2\2\u0290\u0291\7t\2\2\u0291\u00c6\3\2\2"+
"\2\u0292\u0293\7k\2\2\u0293\u0294\7p\2\2\u0294\u00c8\3\2\2\2\u0295\u0296"+
"\7y\2\2\u0296\u0297\7j\2\2\u0297\u0298\7k\2\2\u0298\u0299\7n\2\2\u0299"+
"\u029a\7g\2\2\u029a\u00ca\3\2\2\2\u029b\u029c\7t\2\2\u029c\u029d\7g\2"+
"\2\u029d\u029e\7r\2\2\u029e\u029f\7g\2\2\u029f\u02a0\7c\2\2\u02a0\u02a1"+
"\7v\2\2\u02a1\u00cc\3\2\2\2\u02a2\u02a3\7w\2\2\u02a3\u02a4\7p\2\2\u02a4"+
"\u02a5\7v\2\2\u02a5\u02a6\7k\2\2\u02a6\u02a7\7n\2\2\u02a7\u00ce\3\2\2"+
"\2\u02a8\u02ac\t\2\2\2\u02a9\u02ab\t\3\2\2\u02aa\u02a9\3\2\2\2\u02ab\u02ae"+
"\3\2\2\2\u02ac\u02aa\3\2\2\2\u02ac\u02ad\3\2\2\2\u02ad\u02af\3\2\2\2\u02ae"+
"\u02ac\3\2\2\2\u02af\u02b0\5\u00d1i\2\u02b0\u02b1\3\2\2\2\u02b1\u02b2"+
"\bh\2\2\u02b2\u00d0\3\2\2\2\u02b3\u02b7\7=\2\2\u02b4\u02b6\n\2\2\2\u02b5"+
"\u02b4\3\2\2\2\u02b6\u02b9\3\2\2\2\u02b7\u02b5\3\2\2\2\u02b7\u02b8\3\2"+
"\2\2\u02b8\u02ba\3\2\2\2\u02b9\u02b7\3\2\2\2\u02ba\u02bb\bi\2\2\u02bb"+
"\u00d2\3\2\2\2\u02bc\u02bd\t\3\2\2\u02bd\u02be\3\2\2\2\u02be\u02bf\bj"+
"\3\2\u02bf\u00d4\3\2\2\2\u02c0\u02c2\t\2\2\2\u02c1\u02c0\3\2\2\2\u02c2"+
"\u02c3\3\2\2\2\u02c3\u02c1\3\2\2\2\u02c3\u02c4\3\2\2\2\u02c4\u00d6\3\2"+
"\2\2\u02c5\u02c9\t\4\2\2\u02c6\u02c8\t\5\2\2\u02c7\u02c6\3\2\2\2\u02c8"+
"\u02cb\3\2\2\2\u02c9\u02c7\3\2\2\2\u02c9\u02ca\3\2\2\2\u02ca\u00d8\3\2"+
"\2\2\u02cb\u02c9\3\2\2\2\u02cc\u02d4\4\62;\2\u02cd\u02cf\4\63;\2\u02ce"+
"\u02d0\4\62;\2\u02cf\u02ce\3\2\2\2\u02d0\u02d1\3\2\2\2\u02d1\u02cf\3\2"+
"\2\2\u02d1\u02d2\3\2\2\2\u02d2\u02d4\3\2\2\2\u02d3\u02cc\3\2\2\2\u02d3"+
"\u02cd\3\2\2\2\u02d4\u00da\3\2\2\2\u02d5\u02d7\7&\2\2\u02d6\u02d8\t\6"+
"\2\2\u02d7\u02d6\3\2\2\2\u02d8\u02d9\3\2\2\2\u02d9\u02d7\3\2\2\2\u02d9"+
"\u02da\3\2\2\2\u02da\u00dc\3\2\2\2\u02db\u02dd\7\'\2\2\u02dc\u02de\4\62"+
"\63\2\u02dd\u02dc\3\2\2\2\u02de\u02df\3\2\2\2\u02df\u02dd\3\2\2\2\u02df"+
"\u02e0\3\2\2\2\u02e0\u00de\3\2\2\2\u02e1\u02e7\5\u00e1q\2\u02e2\u02e4"+
"\t\7\2\2\u02e3\u02e5\t\b\2\2\u02e4\u02e3\3\2\2\2\u02e4\u02e5\3\2\2\2\u02e5"+
"\u02e6\3\2\2\2\u02e6\u02e8\5\u00e1q\2\u02e7\u02e2\3\2\2\2\u02e7\u02e8"+
"\3\2\2\2\u02e8\u00e0\3\2\2\2\u02e9\u02eb\4\62;\2\u02ea\u02e9\3\2\2\2\u02eb"+
"\u02ec\3\2\2\2\u02ec\u02ea\3\2\2\2\u02ec\u02ed\3\2\2\2\u02ed\u02f4\3\2"+
"\2\2\u02ee\u02f0\7\60\2\2\u02ef\u02f1\4\62;\2\u02f0\u02ef\3\2\2\2\u02f1"+
"\u02f2\3\2\2\2\u02f2\u02f0\3\2\2\2\u02f2\u02f3\3\2\2\2\u02f3\u02f5\3\2"+
"\2\2\u02f4\u02ee\3\2\2\2\u02f4\u02f5\3\2\2\2\u02f5\u00e2\3\2\2\2\u02f6"+
"\u02f7\7^\2\2\u02f7\u02fb\13\2\2\2\u02f8\u02f9\7^\2\2\u02f9\u02fb\5\u00d5"+
"k\2\u02fa\u02f6\3\2\2\2\u02fa\u02f8\3\2\2\2\u02fb\u00e4\3\2\2\2\u02fc"+
"\u0301\7$\2\2\u02fd\u0300\5\u00e3r\2\u02fe\u0300\n\t\2\2\u02ff\u02fd\3"+
"\2\2\2\u02ff\u02fe\3\2\2\2\u0300\u0303\3\2\2\2\u0301\u02ff\3\2\2\2\u0301"+
"\u0302\3\2\2\2\u0302\u0304\3\2\2\2\u0303\u0301\3\2\2\2\u0304\u0305\7$"+
"\2\2\u0305\u0306\bs\4\2\u0306\u00e6\3\2\2\2\u0307\u0308\7}\2\2\u0308\u0309"+
"\7}\2\2\u0309\u030b\3\2\2\2\u030a\u030c\13\2\2\2\u030b\u030a\3\2\2\2\u030c"+
"\u030d\3\2\2\2\u030d\u030e\3\2\2\2\u030d\u030b\3\2\2\2\u030e\u030f\3\2"+
"\2\2\u030f\u0310\7\177\2\2\u0310\u0311\7\177\2\2\u0311\u0312\3\2\2\2\u0312"+
"\u0313\bt\5\2\u0313\u00e8\3\2\2\2\25\2\u02ac\u02b7\u02c3\u02c9\u02d1\u02d3"+
"\u02d7\u02d9\u02df\u02e4\u02e7\u02ec\u02f2\u02f4\u02fa\u02ff\u0301\u030d"+
"\6\2\3\2\b\2\2\3s\2\3t\3";
"k\4l\tl\4m\tm\4n\tn\4o\to\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\5\3\5"+
"\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3"+
"\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b"+
"\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3"+
"\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13"+
"\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3"+
"\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21"+
"\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23"+
"\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26"+
"\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30"+
"\3\30\3\31\3\31\3\32\3\32\3\33\3\33\3\33\3\34\3\34\3\34\3\35\3\35\3\35"+
"\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3 \3 \3 \3 \3!\3!\3!\3\"\3\"\3\"\3"+
"#\3#\3#\3$\3$\3$\3%\3%\3%\3&\3&\3\'\3\'\3(\3(\3)\3)\3*\3*\3*\3+\3+\3,"+
"\3,\3-\3-\3-\3.\3.\3/\3/\3\60\3\60\3\61\3\61\3\61\3\62\3\62\3\62\3\63"+
"\3\63\3\63\3\64\3\64\3\64\3\65\3\65\3\66\3\66\3\67\3\67\38\38\38\39\3"+
"9\39\39\39\3:\3:\3:\3:\3;\3;\3;\3<\3<\3<\3<\3=\3=\3=\3=\3>\3>\3>\3>\3"+
">\3>\3>\3?\3?\3?\3?\3?\3?\3@\3@\3@\3@\3@\3@\3@\3@\3@\3A\3A\3B\3B\3C\3"+
"C\3D\3D\3E\3E\3E\3F\3F\3F\3G\3G\3G\3H\3H\3H\3I\3I\3I\3I\3I\3J\3J\3J\3"+
"J\3J\3J\3K\3K\3K\3K\3K\3L\3L\3L\3L\3M\3M\3M\3N\3N\3O\3O\3P\3P\3P\3Q\3"+
"Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3S\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3"+
"U\3U\3U\3U\3V\3V\3V\3V\3V\3V\3W\3W\3W\3W\3W\3W\3X\3X\3X\3X\3X\3X\3Y\3"+
"Y\3Y\3Y\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3[\3[\3[\3\\\3\\\3\\\3"+
"\\\3\\\3\\\3]\3]\3]\3]\3]\3]\3^\3^\3^\3^\3_\3_\3_\3`\3`\3`\3`\3`\3`\3"+
"a\3a\3a\3a\3a\3a\3a\3b\3b\3b\3b\3b\3b\3c\3c\7c\u0293\nc\fc\16c\u0296\13"+
"c\3c\3c\3c\3c\3d\3d\7d\u029e\nd\fd\16d\u02a1\13d\3d\3d\3e\3e\3e\3e\3f"+
"\6f\u02aa\nf\rf\16f\u02ab\3g\3g\7g\u02b0\ng\fg\16g\u02b3\13g\3h\3h\3h"+
"\6h\u02b8\nh\rh\16h\u02b9\5h\u02bc\nh\3i\3i\6i\u02c0\ni\ri\16i\u02c1\3"+
"j\3j\6j\u02c6\nj\rj\16j\u02c7\3k\3k\3k\5k\u02cd\nk\3k\5k\u02d0\nk\3l\6"+
"l\u02d3\nl\rl\16l\u02d4\3l\3l\6l\u02d9\nl\rl\16l\u02da\5l\u02dd\nl\3m"+
"\3m\3m\3m\5m\u02e3\nm\3n\3n\3n\7n\u02e8\nn\fn\16n\u02eb\13n\3n\3n\3n\3"+
"o\3o\3o\3o\6o\u02f4\no\ro\16o\u02f5\3o\3o\3o\3o\3o\3\u02f5\2p\3\3\5\4"+
"\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22"+
"#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C"+
"#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u<w"+
"=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091"+
"J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3S\u00a5"+
"T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9"+
"^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cbg\u00cd"+
"h\u00cfi\u00d1j\u00d3k\u00d5l\u00d7\2\u00d9\2\u00dbm\u00ddn\3\2\n\4\2"+
"\f\f\17\17\4\2\13\13\"\"\5\2C\\aac|\6\2\62;C\\aac|\5\2\62;CHch\4\2GGg"+
"g\4\2--//\6\2\f\f\16\17$$^^\2\u030a\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2"+
"\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23"+
"\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2"+
"\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2"+
"\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3"+
"\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2"+
"\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2"+
"\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2["+
"\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2"+
"\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2"+
"\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2"+
"\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089"+
"\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2"+
"\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b"+
"\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2"+
"\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad"+
"\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2"+
"\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf"+
"\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2"+
"\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1"+
"\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2\2\2\u00db\3\2\2\2\2\u00dd\3\2\2"+
"\2\3\u00df\3\2\2\2\5\u00e1\3\2\2\2\7\u00e3\3\2\2\2\t\u00e8\3\2\2\2\13"+
"\u00f0\3\2\2\2\r\u00fa\3\2\2\2\17\u0104\3\2\2\2\21\u010d\3\2\2\2\23\u0115"+
"\3\2\2\2\25\u0121\3\2\2\2\27\u012d\3\2\2\2\31\u0138\3\2\2\2\33\u0140\3"+
"\2\2\2\35\u0142\3\2\2\2\37\u0144\3\2\2\2!\u014a\3\2\2\2#\u0151\3\2\2\2"+
"%\u0156\3\2\2\2\'\u015b\3\2\2\2)\u0161\3\2\2\2+\u0165\3\2\2\2-\u016b\3"+
"\2\2\2/\u0171\3\2\2\2\61\u0178\3\2\2\2\63\u017a\3\2\2\2\65\u017c\3\2\2"+
"\2\67\u017f\3\2\2\29\u0182\3\2\2\2;\u0185\3\2\2\2=\u0189\3\2\2\2?\u018c"+
"\3\2\2\2A\u0190\3\2\2\2C\u0193\3\2\2\2E\u0196\3\2\2\2G\u0199\3\2\2\2I"+
"\u019c\3\2\2\2K\u019f\3\2\2\2M\u01a1\3\2\2\2O\u01a3\3\2\2\2Q\u01a5\3\2"+
"\2\2S\u01a7\3\2\2\2U\u01aa\3\2\2\2W\u01ac\3\2\2\2Y\u01ae\3\2\2\2[\u01b1"+
"\3\2\2\2]\u01b3\3\2\2\2_\u01b5\3\2\2\2a\u01b7\3\2\2\2c\u01ba\3\2\2\2e"+
"\u01bd\3\2\2\2g\u01c0\3\2\2\2i\u01c3\3\2\2\2k\u01c5\3\2\2\2m\u01c7\3\2"+
"\2\2o\u01c9\3\2\2\2q\u01cc\3\2\2\2s\u01d1\3\2\2\2u\u01d5\3\2\2\2w\u01d8"+
"\3\2\2\2y\u01dc\3\2\2\2{\u01e0\3\2\2\2}\u01e7\3\2\2\2\177\u01ed\3\2\2"+
"\2\u0081\u01f6\3\2\2\2\u0083\u01f8\3\2\2\2\u0085\u01fa\3\2\2\2\u0087\u01fc"+
"\3\2\2\2\u0089\u01fe\3\2\2\2\u008b\u0201\3\2\2\2\u008d\u0204\3\2\2\2\u008f"+
"\u0207\3\2\2\2\u0091\u020a\3\2\2\2\u0093\u020f\3\2\2\2\u0095\u0215\3\2"+
"\2\2\u0097\u021a\3\2\2\2\u0099\u021e\3\2\2\2\u009b\u0221\3\2\2\2\u009d"+
"\u0223\3\2\2\2\u009f\u0225\3\2\2\2\u00a1\u0228\3\2\2\2\u00a3\u022d\3\2"+
"\2\2\u00a5\u0233\3\2\2\2\u00a7\u0239\3\2\2\2\u00a9\u023f\3\2\2\2\u00ab"+
"\u0244\3\2\2\2\u00ad\u024a\3\2\2\2\u00af\u0250\3\2\2\2\u00b1\u0256\3\2"+
"\2\2\u00b3\u025d\3\2\2\2\u00b5\u0263\3\2\2\2\u00b7\u026a\3\2\2\2\u00b9"+
"\u0270\3\2\2\2\u00bb\u0276\3\2\2\2\u00bd\u027a\3\2\2\2\u00bf\u027d\3\2"+
"\2\2\u00c1\u0283\3\2\2\2\u00c3\u028a\3\2\2\2\u00c5\u0290\3\2\2\2\u00c7"+
"\u029b\3\2\2\2\u00c9\u02a4\3\2\2\2\u00cb\u02a9\3\2\2\2\u00cd\u02ad\3\2"+
"\2\2\u00cf\u02bb\3\2\2\2\u00d1\u02bd\3\2\2\2\u00d3\u02c3\3\2\2\2\u00d5"+
"\u02c9\3\2\2\2\u00d7\u02d2\3\2\2\2\u00d9\u02e2\3\2\2\2\u00db\u02e4\3\2"+
"\2\2\u00dd\u02ef\3\2\2\2\u00df\u00e0\7\u0080\2\2\u00e0\4\3\2\2\2\u00e1"+
"\u00e2\7<\2\2\u00e2\6\3\2\2\2\u00e3\u00e4\7i\2\2\u00e4\u00e5\7q\2\2\u00e5"+
"\u00e6\7v\2\2\u00e6\u00e7\7q\2\2\u00e7\b\3\2\2\2\u00e8\u00e9\7\'\2\2\u00e9"+
"\u00ea\7q\2\2\u00ea\u00eb\7w\2\2\u00eb\u00ec\7v\2\2\u00ec\u00ed\7r\2\2"+
"\u00ed\u00ee\7w\2\2\u00ee\u00ef\7v\2\2\u00ef\n\3\2\2\2\u00f0\u00f1\7\'"+
"\2\2\u00f1\u00f2\7n\2\2\u00f2\u00f3\7c\2\2\u00f3\u00f4\7w\2\2\u00f4\u00f5"+
"\7p\2\2\u00f5\u00f6\7e\2\2\u00f6\u00f7\7j\2\2\u00f7\u00f8\7g\2\2\u00f8"+
"\u00f9\7t\2\2\u00f9\f\3\2\2\2\u00fa\u00fb\7\'\2\2\u00fb\u00fc\7|\2\2\u00fc"+
"\u00fd\7g\2\2\u00fd\u00fe\7t\2\2\u00fe\u00ff\7q\2\2\u00ff\u0100\7r\2\2"+
"\u0100\u0101\7c\2\2\u0101\u0102\7i\2\2\u0102\u0103\7g\2\2\u0103\16\3\2"+
"\2\2\u0104\u0105\7\'\2\2\u0105\u0106\7c\2\2\u0106\u0107\7f\2\2\u0107\u0108"+
"\7f\2\2\u0108\u0109\7t\2\2\u0109\u010a\7g\2\2\u010a\u010b\7u\2\2\u010b"+
"\u010c\7u\2\2\u010c\20\3\2\2\2\u010d\u010e\7\'\2\2\u010e\u010f\7k\2\2"+
"\u010f\u0110\7o\2\2\u0110\u0111\7r\2\2\u0111\u0112\7q\2\2\u0112\u0113"+
"\7t\2\2\u0113\u0114\7v\2\2\u0114\22\3\2\2\2\u0115\u0116\7\'\2\2\u0116"+
"\u0117\7d\2\2\u0117\u0118\7t\2\2\u0118\u0119\7g\2\2\u0119\u011a\7c\2\2"+
"\u011a\u011b\7m\2\2\u011b\u011c\7r\2\2\u011c\u011d\7q\2\2\u011d\u011e"+
"\7k\2\2\u011e\u011f\7p\2\2\u011f\u0120\7v\2\2\u0120\24\3\2\2\2\u0121\u0122"+
"\7\'\2\2\u0122\u0123\7c\2\2\u0123\u0124\7u\2\2\u0124\u0125\7o\2\2\u0125"+
"\u0126\7k\2\2\u0126\u0127\7p\2\2\u0127\u0128\7e\2\2\u0128\u0129\7n\2\2"+
"\u0129\u012a\7w\2\2\u012a\u012b\7f\2\2\u012b\u012c\7g\2\2\u012c\26\3\2"+
"\2\2\u012d\u012e\7\'\2\2\u012e\u012f\7c\2\2\u012f\u0130\7u\2\2\u0130\u0131"+
"\7o\2\2\u0131\u0132\7d\2\2\u0132\u0133\7k\2\2\u0133\u0134\7p\2\2\u0134"+
"\u0135\7c\2\2\u0135\u0136\7t\2\2\u0136\u0137\7{\2\2\u0137\30\3\2\2\2\u0138"+
"\u0139\7\'\2\2\u0139\u013a\7q\2\2\u013a\u013b\7r\2\2\u013b\u013c\7v\2"+
"\2\u013c\u013d\7k\2\2\u013d\u013e\7q\2\2\u013e\u013f\7p\2\2\u013f\32\3"+
"\2\2\2\u0140\u0141\7.\2\2\u0141\34\3\2\2\2\u0142\u0143\7?\2\2\u0143\36"+
"\3\2\2\2\u0144\u0145\7e\2\2\u0145\u0146\7q\2\2\u0146\u0147\7p\2\2\u0147"+
"\u0148\7u\2\2\u0148\u0149\7v\2\2\u0149 \3\2\2\2\u014a\u014b\7o\2\2\u014b"+
"\u014c\7g\2\2\u014c\u014d\7o\2\2\u014d\u014e\7q\2\2\u014e\u014f\7t\2\2"+
"\u014f\u0150\7{\2\2\u0150\"\3\2\2\2\u0151\u0152\7d\2\2\u0152\u0153\7{"+
"\2\2\u0153\u0154\7v\2\2\u0154\u0155\7g\2\2\u0155$\3\2\2\2\u0156\u0157"+
"\7y\2\2\u0157\u0158\7q\2\2\u0158\u0159\7t\2\2\u0159\u015a\7f\2\2\u015a"+
"&\3\2\2\2\u015b\u015c\7h\2\2\u015c\u015d\7n\2\2\u015d\u015e\7q\2\2\u015e"+
"\u015f\7c\2\2\u015f\u0160\7v\2\2\u0160(\3\2\2\2\u0161\u0162\7u\2\2\u0162"+
"\u0163\7v\2\2\u0163\u0164\7t\2\2\u0164*\3\2\2\2\u0165\u0166\7u\2\2\u0166"+
"\u0167\7v\2\2\u0167\u0168\7t\2\2\u0168\u0169\7a\2\2\u0169\u016a\7r\2\2"+
"\u016a,\3\2\2\2\u016b\u016c\7u\2\2\u016c\u016d\7v\2\2\u016d\u016e\7t\2"+
"\2\u016e\u016f\7a\2\2\u016f\u0170\7u\2\2\u0170.\3\2\2\2\u0171\u0172\7"+
"u\2\2\u0172\u0173\7v\2\2\u0173\u0174\7t\2\2\u0174\u0175\7a\2\2\u0175\u0176"+
"\7r\2\2\u0176\u0177\7u\2\2\u0177\60\3\2\2\2\u0178\u0179\7]\2\2\u0179\62"+
"\3\2\2\2\u017a\u017b\7_\2\2\u017b\64\3\2\2\2\u017c\u017d\7-\2\2\u017d"+
"\u017e\7?\2\2\u017e\66\3\2\2\2\u017f\u0180\7/\2\2\u0180\u0181\7?\2\2\u0181"+
"8\3\2\2\2\u0182\u0183\7\61\2\2\u0183\u0184\7?\2\2\u0184:\3\2\2\2\u0185"+
"\u0186\7\61\2\2\u0186\u0187\7\61\2\2\u0187\u0188\7?\2\2\u0188<\3\2\2\2"+
"\u0189\u018a\7,\2\2\u018a\u018b\7?\2\2\u018b>\3\2\2\2\u018c\u018d\7,\2"+
"\2\u018d\u018e\7,\2\2\u018e\u018f\7?\2\2\u018f@\3\2\2\2\u0190\u0191\7"+
"(\2\2\u0191\u0192\7?\2\2\u0192B\3\2\2\2\u0193\u0194\7~\2\2\u0194\u0195"+
"\7?\2\2\u0195D\3\2\2\2\u0196\u0197\7`\2\2\u0197\u0198\7?\2\2\u0198F\3"+
"\2\2\2\u0199\u019a\7-\2\2\u019a\u019b\7-\2\2\u019bH\3\2\2\2\u019c\u019d"+
"\7/\2\2\u019d\u019e\7/\2\2\u019eJ\3\2\2\2\u019f\u01a0\7*\2\2\u01a0L\3"+
"\2\2\2\u01a1\u01a2\7+\2\2\u01a2N\3\2\2\2\u01a3\u01a4\7-\2\2\u01a4P\3\2"+
"\2\2\u01a5\u01a6\7/\2\2\u01a6R\3\2\2\2\u01a7\u01a8\7,\2\2\u01a8\u01a9"+
"\7,\2\2\u01a9T\3\2\2\2\u01aa\u01ab\7,\2\2\u01abV\3\2\2\2\u01ac\u01ad\7"+
"\61\2\2\u01adX\3\2\2\2\u01ae\u01af\7\61\2\2\u01af\u01b0\7\61\2\2\u01b0"+
"Z\3\2\2\2\u01b1\u01b2\7\'\2\2\u01b2\\\3\2\2\2\u01b3\u01b4\7>\2\2\u01b4"+
"^\3\2\2\2\u01b5\u01b6\7@\2\2\u01b6`\3\2\2\2\u01b7\u01b8\7>\2\2\u01b8\u01b9"+
"\7?\2\2\u01b9b\3\2\2\2\u01ba\u01bb\7@\2\2\u01bb\u01bc\7?\2\2\u01bcd\3"+
"\2\2\2\u01bd\u01be\7?\2\2\u01be\u01bf\7?\2\2\u01bff\3\2\2\2\u01c0\u01c1"+
"\7#\2\2\u01c1\u01c2\7?\2\2\u01c2h\3\2\2\2\u01c3\u01c4\7(\2\2\u01c4j\3"+
"\2\2\2\u01c5\u01c6\7`\2\2\u01c6l\3\2\2\2\u01c7\u01c8\7~\2\2\u01c8n\3\2"+
"\2\2\u01c9\u01ca\7v\2\2\u01ca\u01cb\7q\2\2\u01cbp\3\2\2\2\u01cc\u01cd"+
"\7u\2\2\u01cd\u01ce\7v\2\2\u01ce\u01cf\7g\2\2\u01cf\u01d0\7r\2\2\u01d0"+
"r\3\2\2\2\u01d1\u01d2\7c\2\2\u01d2\u01d3\7p\2\2\u01d3\u01d4\7f\2\2\u01d4"+
"t\3\2\2\2\u01d5\u01d6\7q\2\2\u01d6\u01d7\7t\2\2\u01d7v\3\2\2\2\u01d8\u01d9"+
"\7z\2\2\u01d9\u01da\7q\2\2\u01da\u01db\7t\2\2\u01dbx\3\2\2\2\u01dc\u01dd"+
"\7p\2\2\u01dd\u01de\7q\2\2\u01de\u01df\7v\2\2\u01dfz\3\2\2\2\u01e0\u01e1"+
"\7t\2\2\u01e1\u01e2\7g\2\2\u01e2\u01e3\7v\2\2\u01e3\u01e4\7w\2\2\u01e4"+
"\u01e5\7t\2\2\u01e5\u01e6\7p\2\2\u01e6|\3\2\2\2\u01e7\u01e8\7d\2\2\u01e8"+
"\u01e9\7t\2\2\u01e9\u01ea\7g\2\2\u01ea\u01eb\7c\2\2\u01eb\u01ec\7m\2\2"+
"\u01ec~\3\2\2\2\u01ed\u01ee\7e\2\2\u01ee\u01ef\7q\2\2\u01ef\u01f0\7p\2"+
"\2\u01f0\u01f1\7v\2\2\u01f1\u01f2\7k\2\2\u01f2\u01f3\7p\2\2\u01f3\u01f4"+
"\7w\2\2\u01f4\u01f5\7g\2\2\u01f5\u0080\3\2\2\2\u01f6\u01f7\7\60\2\2\u01f7"+
"\u0082\3\2\2\2\u01f8\u01f9\7C\2\2\u01f9\u0084\3\2\2\2\u01fa\u01fb\7Z\2"+
"\2\u01fb\u0086\3\2\2\2\u01fc\u01fd\7[\2\2\u01fd\u0088\3\2\2\2\u01fe\u01ff"+
"\7C\2\2\u01ff\u0200\7Z\2\2\u0200\u008a\3\2\2\2\u0201\u0202\7C\2\2\u0202"+
"\u0203\7[\2\2\u0203\u008c\3\2\2\2\u0204\u0205\7Z\2\2\u0205\u0206\7[\2"+
"\2\u0206\u008e\3\2\2\2\u0207\u0208\7\60\2\2\u0208\u0209\7y\2\2\u0209\u0090"+
"\3\2\2\2\u020a\u020b\7v\2\2\u020b\u020c\7t\2\2\u020c\u020d\7w\2\2\u020d"+
"\u020e\7g\2\2\u020e\u0092\3\2\2\2\u020f\u0210\7h\2\2\u0210\u0211\7c\2"+
"\2\u0211\u0212\7n\2\2\u0212\u0213\7u\2\2\u0213\u0214\7g\2\2\u0214\u0094"+
"\3\2\2\2\u0215\u0216\7\'\2\2\u0216\u0217\7c\2\2\u0217\u0218\7u\2\2\u0218"+
"\u0219\7o\2\2\u0219\u0096\3\2\2\2\u021a\u021b\7u\2\2\u021b\u021c\7w\2"+
"\2\u021c\u021d\7d\2\2\u021d\u0098\3\2\2\2\u021e\u021f\7/\2\2\u021f\u0220"+
"\7@\2\2\u0220\u009a\3\2\2\2\u0221\u0222\7}\2\2\u0222\u009c\3\2\2\2\u0223"+
"\u0224\7\177\2\2\u0224\u009e\3\2\2\2\u0225\u0226\7k\2\2\u0226\u0227\7"+
"h\2\2\u0227\u00a0\3\2\2\2\u0228\u0229\7g\2\2\u0229\u022a\7n\2\2\u022a"+
"\u022b\7u\2\2\u022b\u022c\7g\2\2\u022c\u00a2\3\2\2\2\u022d\u022e\7k\2"+
"\2\u022e\u022f\7h\2\2\u022f\u0230\7a\2\2\u0230\u0231\7e\2\2\u0231\u0232"+
"\7u\2\2\u0232\u00a4\3\2\2\2\u0233\u0234\7k\2\2\u0234\u0235\7h\2\2\u0235"+
"\u0236\7a\2\2\u0236\u0237\7e\2\2\u0237\u0238\7e\2\2\u0238\u00a6\3\2\2"+
"\2\u0239\u023a\7k\2\2\u023a\u023b\7h\2\2\u023b\u023c\7a\2\2\u023c\u023d"+
"\7g\2\2\u023d\u023e\7s\2\2\u023e\u00a8\3\2\2\2\u023f\u0240\7k\2\2\u0240"+
"\u0241\7h\2\2\u0241\u0242\7a\2\2\u0242\u0243\7|\2\2\u0243\u00aa\3\2\2"+
"\2\u0244\u0245\7k\2\2\u0245\u0246\7h\2\2\u0246\u0247\7a\2\2\u0247\u0248"+
"\7p\2\2\u0248\u0249\7g\2\2\u0249\u00ac\3\2\2\2\u024a\u024b\7k\2\2\u024b"+
"\u024c\7h\2\2\u024c\u024d\7a\2\2\u024d\u024e\7p\2\2\u024e\u024f\7|\2\2"+
"\u024f\u00ae\3\2\2\2\u0250\u0251\7k\2\2\u0251\u0252\7h\2\2\u0252\u0253"+
"\7a\2\2\u0253\u0254\7r\2\2\u0254\u0255\7n\2\2\u0255\u00b0\3\2\2\2\u0256"+
"\u0257\7k\2\2\u0257\u0258\7h\2\2\u0258\u0259\7a\2\2\u0259\u025a\7r\2\2"+
"\u025a\u025b\7q\2\2\u025b\u025c\7u\2\2\u025c\u00b2\3\2\2\2\u025d\u025e"+
"\7k\2\2\u025e\u025f\7h\2\2\u025f\u0260\7a\2\2\u0260\u0261\7o\2\2\u0261"+
"\u0262\7k\2\2\u0262\u00b4\3\2\2\2\u0263\u0264\7k\2\2\u0264\u0265\7h\2"+
"\2\u0265\u0266\7a\2\2\u0266\u0267\7p\2\2\u0267\u0268\7g\2\2\u0268\u0269"+
"\7i\2\2\u0269\u00b6\3\2\2\2\u026a\u026b\7k\2\2\u026b\u026c\7h\2\2\u026c"+
"\u026d\7a\2\2\u026d\u026e\7x\2\2\u026e\u026f\7u\2\2\u026f\u00b8\3\2\2"+
"\2\u0270\u0271\7k\2\2\u0271\u0272\7h\2\2\u0272\u0273\7a\2\2\u0273\u0274"+
"\7x\2\2\u0274\u0275\7e\2\2\u0275\u00ba\3\2\2\2\u0276\u0277\7h\2\2\u0277"+
"\u0278\7q\2\2\u0278\u0279\7t\2\2\u0279\u00bc\3\2\2\2\u027a\u027b\7k\2"+
"\2\u027b\u027c\7p\2\2\u027c\u00be\3\2\2\2\u027d\u027e\7y\2\2\u027e\u027f"+
"\7j\2\2\u027f\u0280\7k\2\2\u0280\u0281\7n\2\2\u0281\u0282\7g\2\2\u0282"+
"\u00c0\3\2\2\2\u0283\u0284\7t\2\2\u0284\u0285\7g\2\2\u0285\u0286\7r\2"+
"\2\u0286\u0287\7g\2\2\u0287\u0288\7c\2\2\u0288\u0289\7v\2\2\u0289\u00c2"+
"\3\2\2\2\u028a\u028b\7w\2\2\u028b\u028c\7p\2\2\u028c\u028d\7v\2\2\u028d"+
"\u028e\7k\2\2\u028e\u028f\7n\2\2\u028f\u00c4\3\2\2\2\u0290\u0294\t\2\2"+
"\2\u0291\u0293\t\3\2\2\u0292\u0291\3\2\2\2\u0293\u0296\3\2\2\2\u0294\u0292"+
"\3\2\2\2\u0294\u0295\3\2\2\2\u0295\u0297\3\2\2\2\u0296\u0294\3\2\2\2\u0297"+
"\u0298\5\u00c7d\2\u0298\u0299\3\2\2\2\u0299\u029a\bc\2\2\u029a\u00c6\3"+
"\2\2\2\u029b\u029f\7=\2\2\u029c\u029e\n\2\2\2\u029d\u029c\3\2\2\2\u029e"+
"\u02a1\3\2\2\2\u029f\u029d\3\2\2\2\u029f\u02a0\3\2\2\2\u02a0\u02a2\3\2"+
"\2\2\u02a1\u029f\3\2\2\2\u02a2\u02a3\bd\2\2\u02a3\u00c8\3\2\2\2\u02a4"+
"\u02a5\t\3\2\2\u02a5\u02a6\3\2\2\2\u02a6\u02a7\be\3\2\u02a7\u00ca\3\2"+
"\2\2\u02a8\u02aa\t\2\2\2\u02a9\u02a8\3\2\2\2\u02aa\u02ab\3\2\2\2\u02ab"+
"\u02a9\3\2\2\2\u02ab\u02ac\3\2\2\2\u02ac\u00cc\3\2\2\2\u02ad\u02b1\t\4"+
"\2\2\u02ae\u02b0\t\5\2\2\u02af\u02ae\3\2\2\2\u02b0\u02b3\3\2\2\2\u02b1"+
"\u02af\3\2\2\2\u02b1\u02b2\3\2\2\2\u02b2\u00ce\3\2\2\2\u02b3\u02b1\3\2"+
"\2\2\u02b4\u02bc\4\62;\2\u02b5\u02b7\4\63;\2\u02b6\u02b8\4\62;\2\u02b7"+
"\u02b6\3\2\2\2\u02b8\u02b9\3\2\2\2\u02b9\u02b7\3\2\2\2\u02b9\u02ba\3\2"+
"\2\2\u02ba\u02bc\3\2\2\2\u02bb\u02b4\3\2\2\2\u02bb\u02b5\3\2\2\2\u02bc"+
"\u00d0\3\2\2\2\u02bd\u02bf\7&\2\2\u02be\u02c0\t\6\2\2\u02bf\u02be\3\2"+
"\2\2\u02c0\u02c1\3\2\2\2\u02c1\u02bf\3\2\2\2\u02c1\u02c2\3\2\2\2\u02c2"+
"\u00d2\3\2\2\2\u02c3\u02c5\7\'\2\2\u02c4\u02c6\4\62\63\2\u02c5\u02c4\3"+
"\2\2\2\u02c6\u02c7\3\2\2\2\u02c7\u02c5\3\2\2\2\u02c7\u02c8\3\2\2\2\u02c8"+
"\u00d4\3\2\2\2\u02c9\u02cf\5\u00d7l\2\u02ca\u02cc\t\7\2\2\u02cb\u02cd"+
"\t\b\2\2\u02cc\u02cb\3\2\2\2\u02cc\u02cd\3\2\2\2\u02cd\u02ce\3\2\2\2\u02ce"+
"\u02d0\5\u00d7l\2\u02cf\u02ca\3\2\2\2\u02cf\u02d0\3\2\2\2\u02d0\u00d6"+
"\3\2\2\2\u02d1\u02d3\4\62;\2\u02d2\u02d1\3\2\2\2\u02d3\u02d4\3\2\2\2\u02d4"+
"\u02d2\3\2\2\2\u02d4\u02d5\3\2\2\2\u02d5\u02dc\3\2\2\2\u02d6\u02d8\7\60"+
"\2\2\u02d7\u02d9\4\62;\2\u02d8\u02d7\3\2\2\2\u02d9\u02da\3\2\2\2\u02da"+
"\u02d8\3\2\2\2\u02da\u02db\3\2\2\2\u02db\u02dd\3\2\2\2\u02dc\u02d6\3\2"+
"\2\2\u02dc\u02dd\3\2\2\2\u02dd\u00d8\3\2\2\2\u02de\u02df\7^\2\2\u02df"+
"\u02e3\13\2\2\2\u02e0\u02e1\7^\2\2\u02e1\u02e3\5\u00cbf\2\u02e2\u02de"+
"\3\2\2\2\u02e2\u02e0\3\2\2\2\u02e3\u00da\3\2\2\2\u02e4\u02e9\7$\2\2\u02e5"+
"\u02e8\5\u00d9m\2\u02e6\u02e8\n\t\2\2\u02e7\u02e5\3\2\2\2\u02e7\u02e6"+
"\3\2\2\2\u02e8\u02eb\3\2\2\2\u02e9\u02e7\3\2\2\2\u02e9\u02ea\3\2\2\2\u02ea"+
"\u02ec\3\2\2\2\u02eb\u02e9\3\2\2\2\u02ec\u02ed\7$\2\2\u02ed\u02ee\bn\4"+
"\2\u02ee\u00dc\3\2\2\2\u02ef\u02f0\7}\2\2\u02f0\u02f1\7}\2\2\u02f1\u02f3"+
"\3\2\2\2\u02f2\u02f4\13\2\2\2\u02f3\u02f2\3\2\2\2\u02f4\u02f5\3\2\2\2"+
"\u02f5\u02f6\3\2\2\2\u02f5\u02f3\3\2\2\2\u02f6\u02f7\3\2\2\2\u02f7\u02f8"+
"\7\177\2\2\u02f8\u02f9\7\177\2\2\u02f9\u02fa\3\2\2\2\u02fa\u02fb\bo\5"+
"\2\u02fb\u00de\3\2\2\2\25\2\u0294\u029f\u02ab\u02b1\u02b9\u02bb\u02bf"+
"\u02c1\u02c7\u02cc\u02cf\u02d4\u02da\u02dc\u02e2\u02e7\u02e9\u02f5\6\2"+
"\3\2\b\2\2\3n\2\3o\3";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {

File diff suppressed because it is too large Load Diff

View File

@ -146,7 +146,7 @@ taking no parameters and having no return value.
As any subroutine, it has to end with a ``return`` statement (or a ``goto`` call)::
~ main {
sub start () -> () {
sub start () {
; program entrypoint code here
return
}
@ -438,36 +438,23 @@ Defining a subroutine
^^^^^^^^^^^^^^^^^^^^^
Subroutines are parts of the code that can be repeatedly invoked using a subroutine call from elsewhere.
Their definition, using the sub statement, includes the specification of the required input- and output parameters.
For now, only register based parameters are supported (A, X, Y and paired registers AX, AY and XY,
and various flags of the status register P: Pc (carry), Pz (zero), Pn (negative), Pv (overflow).
For subroutine return values, it is the same (registers, status flags).
Their definition, using the ``sub`` statement, includes the specification of the required input- and output parameters.
Subroutines can be defined in a Block, but also nested inside another subroutine. Everything is scoped accordingly.
.. todo::
re-introduce register based params and return values.
For now, only register based parameters are supported (A, X, Y and paired registers AX, AY and XY,
and various flags of the status register P: Pc (carry), Pz (zero), Pn (negative), Pv (overflow).
For subroutine return values, it is the same (registers, status flags).
Calling a subroutine
^^^^^^^^^^^^^^^^^^^^
The output variables must occur in the correct sequence of return registers as specified
in the subroutine's definiton. It is possible to not specify any of them but the compiler
will issue a warning then if the result values of a subroutine call are discarded.
If you don't have a variable to store the output register in, it's then required
to list the register itself instead as output variable.
Arguments should match the subroutine definition. You are allowed to omit the parameter names.
If no definition is available (because you're directly calling memory or a label or something else),
you can freely add arguments (but in this case they all have to be named).
To jump to a subroutine (without returning), prefix the subroutine call with the word 'goto'.
Unlike gotos in other languages, here it take arguments as well, because it
essentially is the same as calling a subroutine and only doing something different when it's finished.
**Register preserving calls:** use the ``!`` followed by a combination of A, X and Y (or followed
by nothing, which is the same as AXY) to tell the compiler you want to preserve the origial
value of the given registers after the subroutine call. Otherwise, the subroutine may just
as well clobber all three registers. Preserving the original values does result in some
stack manipulation code to be inserted for every call like this, which can be quite slow.
The arguments in parentheses after the function name, should match the parameters in the subroutine definition.
The output variables must occur in the correct sequence of return values as specified
in the subroutine's definiton. It is possible to not store the return values but the compiler
will issue a warning then telling you the result values of a subroutine call are discarded.
.. caution::
Note that *recursive* subroutine calls are not supported at this time.

View File

@ -411,42 +411,39 @@ Subroutine definitions
The syntax is::
sub <identifier> ([proc_parameters]) -> ([proc_results]) {
sub <identifier> ( [parameters] ) [ -> returnvalues ] {
... statements ...
}
; example:
sub triple_something (amount: X) -> A {
sub triple_something (amount: word) -> word {
return X * 3
}
The open curly brace must immediately follow the subroutine result specification on the same line,
and can have nothing following it. The close curly brace must be on its own line as well.
Pre-defined subroutines that are available on specific memory addresses
(in system ROM for instance) can be defined by assigning the routine's memory address to the sub,
and not specifying a code block::
.. todo::
Pre-defined subroutines that are available on specific memory addresses
(in system ROM for instance) can be defined by assigning the routine's memory address to the sub,
and not specifying a code block::
sub <identifier> ([proc_parameters]) -> ([proc_results]) = <address>
sub <identifier> ([proc_parameters]) -> [proc_results] = <address>
; example:
sub CLOSE (logical: A) -> (A?, X?, Y?) = $FFC3
; example:
sub CLOSE (logical: A) -> (A?, X?, Y?) = $FFC3
.. data:: proc_parameters
.. data:: parameters
comma separated list of "<parametername>:<register>" pairs specifying the input parameters.
You can omit these parameter names in subroutine calls, as long as the arguments "line up".
Comma separated list of "<parametername>:<datatype>" pairs specifying the input parameters.
Can be empty.
.. data:: proc_results
comma separated list of <register> names specifying in which register(s) the output is returned.
If the register name ends with a '?', that means the register doesn't contain a real return value but
is clobbered in the process so the original value it had before calling the sub is no longer valid.
This is not immediately useful for your own code, but the compiler needs this information to
emit the correct assembly code to preserve the cpu registers if needed when the call is made.
For convenience: a single '?' als the result spec is shorthand for ``A?, X?, Y?`` ("I don't know
what the changed registers are, assume the worst")
Comma separated list of result value datatypes.
A subroutine without return values must omit the whole part with the arrow
after the parameter list.
Loops