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

View File

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

View File

@ -1,33 +1,20 @@
%option enable_floats %option enable_floats
~ main { ~ main {
sub start() -> () { sub start() {
str msg1 = "abc" byte bvar
str msg2 = "abc" word wvar
str msg3 = "abc123" float fvar
str_p msg4 = "abc" str svar = "svar"
byte[5] array1 = 0 str_p spvar = "spvar"
byte[5] array2 = 222 str_s ssvar = "ssvar"
byte[6] array3 = [1,2,3,4,5,66] str_ps spsvar = "spsvar"
word[5] array4 = 333 byte[2,3] matrixvar1
word[5] array5 = [1,2,3,4,59999] byte[2,3] matrixvar2 = 2
word[5] array6 = [1,2,3,4,5] byte[5] barrayvar
word[5] array7 = [1,2,3,4,999+22/33] byte[5] barrayvar1 = 44
byte[2,3] matrix1 = [1,2, 3,4, 5,6] word[5] warrayvar
byte[2,3] matrix2 = [1,2, 3,4, 5,6] word[5] warrayvar1 = 22
byte[2,3] matrix3 = [11,22, 33,44, 55,66]
byte num1 = sin(2.0)
word num2 = rndw()
float num3 = 98.555
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.FLOAT -> if(floatvalue==null) throw FatalAstException("literal value missing floatvalue")
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS ->
if(strvalue==null && heapId==null) throw FatalAstException("literal value missing strvalue/heapId") 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") 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) if(bytevalue==null && wordvalue==null && floatvalue==null && arrayvalue==null && strvalue==null && heapId==null)
throw FatalAstException("literal value without actual value") 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) return builtinFunctionReturnType(target.nameInSource[0], this.arglist, namespace, heap)
} }
is Subroutine -> { is Subroutine -> {
if(stmt.returnvalues.isEmpty()) { if(stmt.returnvalues.isEmpty())
return null // no return value return null // no return value
} if(stmt.returnvalues.size==1)
if(stmt.returnvalues.size==1) { return stmt.returnvalues[0]
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")
}
}
TODO("return type for subroutine with multiple return values $stmt") TODO("return type for subroutine with multiple return values $stmt")
} }
is Label -> return null is Label -> return null
@ -1253,7 +1242,7 @@ class InlineAssembly(val assembly: String, override val position: Position) : IS
class Subroutine(override val name: String, class Subroutine(override val name: String,
val parameters: List<SubroutineParameter>, val parameters: List<SubroutineParameter>,
val returnvalues: List<SubroutineReturnvalue>, val returnvalues: List<DataType>,
val address: Int?, val address: Int?,
override var statements: MutableList<IStatement>, override var statements: MutableList<IStatement>,
override val position: Position) : IStatement, INameScope { override val position: Position) : IStatement, INameScope {
@ -1264,7 +1253,6 @@ class Subroutine(override val name: String,
override fun linkParents(parent: Node) { override fun linkParents(parent: Node) {
this.parent = parent this.parent = parent
parameters.forEach { it.linkParents(this) } parameters.forEach { it.linkParents(this) }
returnvalues.forEach { it.linkParents(this) }
statements.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, data class SubroutineParameter(val name: String,
val register: Register?, val type: DataType,
val statusflag: Statusflag?,
override val position: Position) : Node { override val position: Position) : Node {
override lateinit var parent: Node override lateinit var parent: Node
override fun linkParents(parent: Node) { override fun linkParents(parent: Node) {
this.parent = parent 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 { private fun prog8Parser.SubroutineContext.toAst() : Subroutine {
return Subroutine(identifier().text, return Subroutine(identifier().text,
if(sub_params() ==null) emptyList() else sub_params().toAst(), 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(), sub_address()?.integerliteral()?.toAst()?.number?.toInt(),
if(statement_block() ==null) mutableListOf() else statement_block().toAst(), if(statement_block() ==null) mutableListOf() else statement_block().toAst(),
toPosition()) 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> = private fun prog8Parser.Sub_paramsContext.toAst(): List<SubroutineParameter> =
sub_param().map { sub_param().map {
SubroutineParameter(it.identifier().text, it.register()?.toAst(), it.statusflag()?.toAst(), it.toPosition()) SubroutineParameter(it.identifier().text, it.datatype().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())
} }
@ -1612,8 +1579,6 @@ private fun prog8Parser.Assign_targetContext.toAst() : AssignTarget {
private fun prog8Parser.RegisterContext.toAst() = Register.valueOf(text.toUpperCase()) 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()) 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() val uniqueNames = subroutine.parameters.asSequence().map { it.name }.toSet()
if(uniqueNames.size!=subroutine.parameters.size) if(uniqueNames.size!=subroutine.parameters.size)
err("parameter names must be unique") 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) super.process(subroutine)
checkSubroutinesPrecededByReturnOrJumpAndFollowedByLabelOrSub(subroutine.statements) checkSubroutinesPrecededByReturnOrJumpAndFollowedByLabelOrSub(subroutine.statements)
@ -330,13 +323,14 @@ class AstChecker(private val namespace: INameScope,
when(decl.type) { when(decl.type) {
VarDeclType.VAR, VarDeclType.CONST -> { VarDeclType.VAR, VarDeclType.CONST -> {
if (decl.value == null) { if (decl.value == null) {
if(decl.datatype == DataType.BYTE || decl.datatype==DataType.WORD || decl.datatype==DataType.FLOAT) { when {
// initialize numeric var with value zero by default. decl.datatype == DataType.BYTE || decl.datatype==DataType.WORD || decl.datatype==DataType.FLOAT -> {
val litVal = LiteralValue(DataType.BYTE, 0, position = decl.position) // initialize numeric var with value zero by default.
litVal.parent = decl val litVal = LiteralValue(DataType.BYTE, 0, position = decl.position)
decl.value = litVal litVal.parent = decl
} else { decl.value = litVal
err("var/const declaration needs a compile-time constant initializer value for this type") }
else -> err("var/const declaration needs a compile-time constant initializer value for this type")
} }
return super.process(decl) return super.process(decl)
} }
@ -688,7 +682,7 @@ class AstChecker(private val namespace: INameScope,
} }
DataType.MATRIX -> { DataType.MATRIX -> {
// value can only be a single byte, or a byte array (which represents the 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 constX = arrayspec!!.x.constValue(namespace, heap)
val constY = arrayspec.y!!.constValue(namespace, heap) val constY = arrayspec.y!!.constValue(namespace, heap)
if(constX?.asIntegerValue==null || constY?.asIntegerValue==null) 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) { 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)) { for(param in arguments.zip(subroutine.parameters)) {
val assign = Assignment( // @todo push params onto stack in correct order
AssignTarget(param.second.register, null, param.first.position),
null,
param.first,
param.first.position
)
assign.linkParents(parent)
translate(assign)
} }
stackvmProg.instr(Opcode.CALL, callLabel=subroutine.scopedname) stackvmProg.instr(Opcode.CALL, callLabel=subroutine.scopedname)
} }
@ -677,16 +668,7 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
private fun translate(stmt: Return) { private fun translate(stmt: Return) {
val returnvalues = (stmt.definingScope() as? Subroutine)?.returnvalues ?: emptyList() val returnvalues = (stmt.definingScope() as? Subroutine)?.returnvalues ?: emptyList()
for(value in stmt.values.zip(returnvalues)) { for(value in stmt.values.zip(returnvalues)) {
// assign the return values to the proper result registers // @todo assign the return values to the proper return variables
// @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)
} }
stackvmProg.line(stmt.position) stackvmProg.line(stmt.position)
stackvmProg.instr(Opcode.RETURN) stackvmProg.instr(Opcode.RETURN)

View File

@ -7,14 +7,15 @@ import kotlin.math.log2
class FunctionSignature(val pure: Boolean, // does it have side effects? class FunctionSignature(val pure: Boolean, // does it have side effects?
val parameters: List<SubroutineParameter>, val parameters: List<SubroutineParameter>,
val returnvalues: List<SubroutineReturnvalue>, val paramTypesVariable: Boolean,
val returnvalues: List<DataType>,
val type: DataType?, val type: DataType?,
val expressionFunc: ((args: List<IExpression>, position: Position, namespace: INameScope, heap: HeapValues) -> LiteralValue)?) { val expressionFunc: ((args: List<IExpression>, position: Position, namespace: INameScope, heap: HeapValues) -> LiteralValue)?) {
companion object { companion object {
private val dummyPos = Position("dummy", 0, 0, 0) private val dummyPos = Position("dummy", 0, 0, 0)
fun sig(pure: Boolean, fun sig(pure: Boolean,
args: List<String>, args: List<Pair<String, DataType?>>,
hasReturnValue: Boolean, hasReturnValue: Boolean,
type: DataType?, type: DataType?,
expressionFunc: ((args: List<IExpression>, position: Position, namespace: INameScope, heap: HeapValues) -> LiteralValue)? = null 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) if(!hasReturnValue && expressionFunc!=null)
throw IllegalArgumentException("can't have expression func when hasReturnValue is false") throw IllegalArgumentException("can't have expression func when hasReturnValue is false")
return FunctionSignature(pure, return FunctionSignature(pure,
args.map { SubroutineParameter(it, null, null, dummyPos) }, args.map { SubroutineParameter(it.first, it.second ?: DataType.BYTE, dummyPos) },
if(hasReturnValue) args.any { it.second==null },
listOf(SubroutineReturnvalue(null, null, false, dummyPos)) if(hasReturnValue && type!=null)
listOf(type)
else else
emptyList(), emptyList(),
type, type,
@ -40,41 +42,41 @@ val BuiltinFunctions = mapOf(
"clear_carry" to FunctionSignature.sig(false, emptyList(), false, null), "clear_carry" to FunctionSignature.sig(false, emptyList(), false, null),
"set_irqd" 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), "clear_irqd" to FunctionSignature.sig(false, emptyList(), false, null),
"rol" to FunctionSignature.sig(false, listOf("item"), false, null), "rol" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
"ror" to FunctionSignature.sig(false, listOf("item"), false, null), "ror" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
"rol2" to FunctionSignature.sig(false, listOf("item"), false, null), "rol2" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
"ror2" to FunctionSignature.sig(false, listOf("item"), false, null), "ror2" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
"lsl" to FunctionSignature.sig(false, listOf("item"), false, null), "lsl" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
"lsr" to FunctionSignature.sig(false, listOf("item"), false, null), "lsr" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
"sin" to FunctionSignature.sig(true, listOf("rads"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sin) }, "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("rads"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::cos) }, "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("rads"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::acos) }, "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("rads"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::asin) }, "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("rads"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::tan) }, "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("rads"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::atan) }, "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), "rnd" to FunctionSignature.sig(true, emptyList(), true, DataType.BYTE),
"rndw" to FunctionSignature.sig(true, emptyList(), true, DataType.WORD), "rndw" to FunctionSignature.sig(true, emptyList(), true, DataType.WORD),
"rndf" to FunctionSignature.sig(true, emptyList(), true, DataType.FLOAT), "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) }, "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("value"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, ::log2) }, "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("value"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log10) }, "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("value"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sqrt) }, "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("value"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toRadians) }, "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("value"), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toDegrees) }, "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("values"), true, DataType.FLOAT, ::builtinAvg), "avg" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, DataType.FLOAT, ::builtinAvg),
"abs" to FunctionSignature.sig(true, listOf("value"), true, null, ::builtinAbs), // type depends on arg "abs" to FunctionSignature.sig(true, listOf(Pair("value", null)), 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 "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("value"), true, null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::floor) }, // 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("value"), true, null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::ceil) }, // 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("values"), true, null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.max()!! }}, // type depends on args "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("values"), true, null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.min()!! }}, // 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("values"), true, null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.sum() }}, // 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("values"), true, null, ::builtinLen), // 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("values"), true, DataType.BYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.any { v -> v != 0.0} }}, "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("values"), true, DataType.BYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.all { 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("value"), true, DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x and 255 }}, "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("value"), true, DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x ushr 8 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("value"), true, DataType.FLOAT, ::builtinFlt), "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_memchr" to FunctionSignature.sig(false, emptyList(), false, null),
"_vm_write_memstr" 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), "_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 decl.value = newValue
} }
} }
DataType.MATRIX -> { DataType.ARRAY, DataType.ARRAY_W, DataType.MATRIX -> {
(decl.value as? LiteralValue)?.let { val litval = decl.value as? LiteralValue
val intvalue = it.asIntegerValue val size = decl.arrayspec!!.size()
if(intvalue!=null) { if (size != null) {
// replace the single int value by a properly sized array to fill the matrix. val fillvalue = if (litval == null) 0 else litval.asIntegerValue ?: 0
val size = decl.arrayspec!!.size() val fillArray = IntArray(size) { _ -> fillvalue }
if(size!=null) { val heapId = heap.add(decl.datatype, fillArray)
val newArray = Array<IExpression>(size) { _ -> LiteralValue(DataType.BYTE, bytevalue = intvalue.toShort(), position = it.position) } val valType = if(decl.datatype==DataType.MATRIX) DataType.ARRAY else decl.datatype
decl.value = LiteralValue(DataType.ARRAY, arrayvalue = newArray, position = it.position) decl.value = LiteralValue(valType, heapId = heapId, position = litval?.position ?: decl.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))
}
}
} }
} }
else -> return result else -> return result
@ -90,6 +66,21 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
return result 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 * 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 // Generated from /home/irmen/Projects/prog8/compiler/antlr/prog8.g4 by ANTLR 4.7
package prog8.parser; 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.*;
import org.antlr.v4.runtime.atn.ATN; import org.antlr.v4.runtime.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.dfa.DFA; import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class prog8Lexer extends Lexer { 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__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__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__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__94=95, T__95=96, T__96=97, LINECOMMENT=98, COMMENT=99, WS=100, EOL=101,
T__101=102, LINECOMMENT=103, COMMENT=104, WS=105, EOL=106, NAME=107, DEC_INTEGER=108, NAME=102, DEC_INTEGER=103, HEX_INTEGER=104, BIN_INTEGER=105, FLOAT_NUMBER=106,
HEX_INTEGER=109, BIN_INTEGER=110, FLOAT_NUMBER=111, STRING=112, INLINEASMBLOCK=113; STRING=107, INLINEASMBLOCK=108;
public static String[] channelNames = { public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN" "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__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__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__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", "LINECOMMENT", "COMMENT", "WS", "EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER",
"WS", "EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER", "BIN_INTEGER", "FLOAT_NUMBER", "BIN_INTEGER", "FLOAT_NUMBER", "FNUMBER", "STRING_ESCAPE_SEQ", "STRING",
"FNUMBER", "STRING_ESCAPE_SEQ", "STRING", "INLINEASMBLOCK" "INLINEASMBLOCK"
}; };
private static final String[] _LITERAL_NAMES = { private static final String[] _LITERAL_NAMES = {
@ -67,11 +68,11 @@ public class prog8Lexer extends Lexer {
"'--'", "'('", "')'", "'+'", "'-'", "'**'", "'*'", "'/'", "'//'", "'%'", "'--'", "'('", "')'", "'+'", "'-'", "'**'", "'*'", "'/'", "'//'", "'%'",
"'<'", "'>'", "'<='", "'>='", "'=='", "'!='", "'&'", "'^'", "'|'", "'to'", "'<'", "'>'", "'<='", "'>='", "'=='", "'!='", "'&'", "'^'", "'|'", "'to'",
"'step'", "'and'", "'or'", "'xor'", "'not'", "'return'", "'break'", "'continue'", "'step'", "'and'", "'or'", "'xor'", "'not'", "'return'", "'break'", "'continue'",
"'.'", "'A'", "'X'", "'Y'", "'AX'", "'AY'", "'XY'", "'Pc'", "'Pz'", "'Pn'", "'.'", "'A'", "'X'", "'Y'", "'AX'", "'AY'", "'XY'", "'.w'", "'true'",
"'Pv'", "'.w'", "'true'", "'false'", "'%asm'", "'sub'", "'->'", "'{'", "'false'", "'%asm'", "'sub'", "'->'", "'{'", "'}'", "'if'", "'else'",
"'}'", "'?'", "'if'", "'else'", "'if_cs'", "'if_cc'", "'if_eq'", "'if_z'", "'if_cs'", "'if_cc'", "'if_eq'", "'if_z'", "'if_ne'", "'if_nz'", "'if_pl'",
"'if_ne'", "'if_nz'", "'if_pl'", "'if_pos'", "'if_mi'", "'if_neg'", "'if_vs'", "'if_pos'", "'if_mi'", "'if_neg'", "'if_vs'", "'if_vc'", "'for'", "'in'",
"'if_vc'", "'for'", "'in'", "'while'", "'repeat'", "'until'" "'while'", "'repeat'", "'until'"
}; };
private static final String[] _SYMBOLIC_NAMES = { private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, null, null, null, null, null, null, null, null, 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, 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", null, null, "LINECOMMENT", "COMMENT", "WS", "EOL", "NAME", "DEC_INTEGER",
"EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER", "BIN_INTEGER", "FLOAT_NUMBER", "HEX_INTEGER", "BIN_INTEGER", "FLOAT_NUMBER", "STRING", "INLINEASMBLOCK"
"STRING", "INLINEASMBLOCK"
}; };
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
@ -146,10 +146,10 @@ public class prog8Lexer extends Lexer {
@Override @Override
public void action(RuleContext _localctx, int ruleIndex, int actionIndex) { public void action(RuleContext _localctx, int ruleIndex, int actionIndex) {
switch (ruleIndex) { switch (ruleIndex) {
case 113: case 108:
STRING_action((RuleContext)_localctx, actionIndex); STRING_action((RuleContext)_localctx, actionIndex);
break; break;
case 114: case 109:
INLINEASMBLOCK_action((RuleContext)_localctx, actionIndex); INLINEASMBLOCK_action((RuleContext)_localctx, actionIndex);
break; break;
} }
@ -178,7 +178,7 @@ public class prog8Lexer extends Lexer {
} }
public static final String _serializedATN = 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"+ "\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"+ "\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"+ "\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"+ "\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"+ "\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"+ "`\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"+ "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\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\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"+
"\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"+ "\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"+
"\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\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"+
"\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"+ "\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\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\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"+
"\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"+ "\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\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\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\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\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\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\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\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\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\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\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&\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,\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\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\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"+
"\3\66\3\67\3\67\38\38\38\39\39\39\39\39\3:\3:\3:\3:\3;\3;\3;\3<\3<\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?\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"+
"\3@\3@\3@\3@\3A\3A\3B\3B\3C\3C\3D\3D\3E\3E\3E\3F\3F\3F\3G\3G\3G\3H\3H"+ "C\3D\3D\3E\3E\3E\3F\3F\3F\3G\3G\3G\3H\3H\3H\3I\3I\3I\3I\3I\3J\3J\3J\3"+
"\3H\3I\3I\3I\3J\3J\3J\3K\3K\3K\3L\3L\3L\3M\3M\3M\3M\3M\3N\3N\3N\3N\3N"+ "J\3J\3J\3K\3K\3K\3K\3K\3L\3L\3L\3L\3M\3M\3M\3N\3N\3O\3O\3P\3P\3P\3Q\3"+
"\3N\3O\3O\3O\3O\3O\3P\3P\3P\3P\3Q\3Q\3Q\3R\3R\3S\3S\3T\3T\3U\3U\3U\3V"+ "Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3S\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3"+
"\3V\3V\3V\3V\3W\3W\3W\3W\3W\3W\3X\3X\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Y\3Z"+ "U\3U\3U\3U\3V\3V\3V\3V\3V\3V\3W\3W\3W\3W\3W\3W\3X\3X\3X\3X\3X\3X\3Y\3"+
"\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3[\3[\3\\\3\\\3\\\3\\\3\\\3\\\3]\3]\3]\3]\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`\3a\3a"+ "\\\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\3b\3b\3b\3b\3b\3b\3c\3c\3c\3c\3d\3d\3d\3e\3e\3e\3e\3e\3e"+ "a\3a\3a\3a\3a\3a\3a\3b\3b\3b\3b\3b\3b\3c\3c\7c\u0293\nc\fc\16c\u0296\13"+
"\3f\3f\3f\3f\3f\3f\3f\3g\3g\3g\3g\3g\3g\3h\3h\7h\u02ab\nh\fh\16h\u02ae"+ "c\3c\3c\3c\3c\3d\3d\7d\u029e\nd\fd\16d\u02a1\13d\3d\3d\3e\3e\3e\3e\3f"+
"\13h\3h\3h\3h\3h\3i\3i\7i\u02b6\ni\fi\16i\u02b9\13i\3i\3i\3j\3j\3j\3j"+ "\6f\u02aa\nf\rf\16f\u02ab\3g\3g\7g\u02b0\ng\fg\16g\u02b3\13g\3h\3h\3h"+
"\3k\6k\u02c2\nk\rk\16k\u02c3\3l\3l\7l\u02c8\nl\fl\16l\u02cb\13l\3m\3m"+ "\6h\u02b8\nh\rh\16h\u02b9\5h\u02bc\nh\3i\3i\6i\u02c0\ni\ri\16i\u02c1\3"+
"\3m\6m\u02d0\nm\rm\16m\u02d1\5m\u02d4\nm\3n\3n\6n\u02d8\nn\rn\16n\u02d9"+ "j\3j\6j\u02c6\nj\rj\16j\u02c7\3k\3k\3k\5k\u02cd\nk\3k\5k\u02d0\nk\3l\6"+
"\3o\3o\6o\u02de\no\ro\16o\u02df\3p\3p\3p\5p\u02e5\np\3p\5p\u02e8\np\3"+ "l\u02d3\nl\rl\16l\u02d4\3l\3l\6l\u02d9\nl\rl\16l\u02da\5l\u02dd\nl\3m"+
"q\6q\u02eb\nq\rq\16q\u02ec\3q\3q\6q\u02f1\nq\rq\16q\u02f2\5q\u02f5\nq"+ "\3m\3m\3m\5m\u02e3\nm\3n\3n\3n\7n\u02e8\nn\fn\16n\u02eb\13n\3n\3n\3n\3"+
"\3r\3r\3r\3r\5r\u02fb\nr\3s\3s\3s\7s\u0300\ns\fs\16s\u0303\13s\3s\3s\3"+ "o\3o\3o\3o\6o\u02f4\no\ro\16o\u02f5\3o\3o\3o\3o\3o\3\u02f5\2p\3\3\5\4"+
"s\3t\3t\3t\3t\6t\u030c\nt\rt\16t\u030d\3t\3t\3t\3t\3t\3\u030d\2u\3\3\5"+ "\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"+
"\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"+ "#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C"+
"!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!"+ "#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u<w"+
"A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s"+ "=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091"+
";u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008f"+ "J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3S\u00a5"+
"I\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3"+ "T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9"+
"S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7"+ "^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cbg\u00cd"+
"]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cb"+ "h\u00cfi\u00d1j\u00d3k\u00d5l\u00d7\2\u00d9\2\u00dbm\u00ddn\3\2\n\4\2"+
"g\u00cdh\u00cfi\u00d1j\u00d3k\u00d5l\u00d7m\u00d9n\u00dbo\u00ddp\u00df"+ "\f\f\17\17\4\2\13\13\"\"\5\2C\\aac|\6\2\62;C\\aac|\5\2\62;CHch\4\2GGg"+
"q\u00e1\2\u00e3\2\u00e5r\u00e7s\3\2\n\4\2\f\f\17\17\4\2\13\13\"\"\5\2"+ "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"+
"C\\aac|\6\2\62;C\\aac|\5\2\62;CHch\4\2GGgg\4\2--//\6\2\f\f\16\17$$^^\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"+
"\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"+ "\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"+
"\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\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\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\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#\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"+ "\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"+
"/\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\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"+
"\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"+ "\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["+
"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"+ "\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\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\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"+
"\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"+ "\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"+
"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\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"+
"\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"+ "\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\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"+ "\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"+
"\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\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2"+
"\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\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"+
"\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\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2"+
"\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\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"+
"\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\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2"+
"\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\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"+
"\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\u00d3\3\2\2\2\2\u00d5\3\2\2\2\2\u00db\3\2\2\2\2\u00dd\3\2\2"+
"\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\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"+
"\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"+ "\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\2\u00df\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\3\u00e9\3\2\2"+ "\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\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"+ "\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"+
"\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"+ "%\u0156\3\2\2\2\'\u015b\3\2\2\2)\u0161\3\2\2\2+\u0165\3\2\2\2-\u016b\3"+
"\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/\u0171\3\2\2\2\61\u0178\3\2\2\2\63\u017a\3\2\2\2\65\u017c\3\2\2"+
"\2\2\2\37\u014e\3\2\2\2!\u0154\3\2\2\2#\u015b\3\2\2\2%\u0160\3\2\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"+
"\u0165\3\2\2\2)\u016b\3\2\2\2+\u016f\3\2\2\2-\u0175\3\2\2\2/\u017b\3\2"+ "\3\2\2\2A\u0190\3\2\2\2C\u0193\3\2\2\2E\u0196\3\2\2\2G\u0199\3\2\2\2I"+
"\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"+ "\u019c\3\2\2\2K\u019f\3\2\2\2M\u01a1\3\2\2\2O\u01a3\3\2\2\2Q\u01a5\3\2"+
"\29\u018c\3\2\2\2;\u018f\3\2\2\2=\u0193\3\2\2\2?\u0196\3\2\2\2A\u019a"+ "\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\2C\u019d\3\2\2\2E\u01a0\3\2\2\2G\u01a3\3\2\2\2I\u01a6\3\2\2\2K"+ "\3\2\2\2]\u01b3\3\2\2\2_\u01b5\3\2\2\2a\u01b7\3\2\2\2c\u01ba\3\2\2\2e"+
"\u01a9\3\2\2\2M\u01ab\3\2\2\2O\u01ad\3\2\2\2Q\u01af\3\2\2\2S\u01b1\3\2"+ "\u01bd\3\2\2\2g\u01c0\3\2\2\2i\u01c3\3\2\2\2k\u01c5\3\2\2\2m\u01c7\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"+ "\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\2_\u01bf\3\2\2\2a\u01c1\3\2\2\2c\u01c4\3\2\2\2e\u01c7\3\2\2\2g"+ "\3\2\2\2y\u01dc\3\2\2\2{\u01e0\3\2\2\2}\u01e7\3\2\2\2\177\u01ed\3\2\2"+
"\u01ca\3\2\2\2i\u01cd\3\2\2\2k\u01cf\3\2\2\2m\u01d1\3\2\2\2o\u01d3\3\2"+ "\2\u0081\u01f6\3\2\2\2\u0083\u01f8\3\2\2\2\u0085\u01fa\3\2\2\2\u0087\u01fc"+
"\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\u0089\u01fe\3\2\2\2\u008b\u0201\3\2\2\2\u008d\u0204\3\2\2\2\u008f"+
"\3\2\2\2{\u01ea\3\2\2\2}\u01f1\3\2\2\2\177\u01f7\3\2\2\2\u0081\u0200\3"+ "\u0207\3\2\2\2\u0091\u020a\3\2\2\2\u0093\u020f\3\2\2\2\u0095\u0215\3\2"+
"\2\2\2\u0083\u0202\3\2\2\2\u0085\u0204\3\2\2\2\u0087\u0206\3\2\2\2\u0089"+ "\2\2\u0097\u021a\3\2\2\2\u0099\u021e\3\2\2\2\u009b\u0221\3\2\2\2\u009d"+
"\u0208\3\2\2\2\u008b\u020b\3\2\2\2\u008d\u020e\3\2\2\2\u008f\u0211\3\2"+ "\u0223\3\2\2\2\u009f\u0225\3\2\2\2\u00a1\u0228\3\2\2\2\u00a3\u022d\3\2"+
"\2\2\u0091\u0214\3\2\2\2\u0093\u0217\3\2\2\2\u0095\u021a\3\2\2\2\u0097"+ "\2\2\u00a5\u0233\3\2\2\2\u00a7\u0239\3\2\2\2\u00a9\u023f\3\2\2\2\u00ab"+
"\u021d\3\2\2\2\u0099\u0220\3\2\2\2\u009b\u0225\3\2\2\2\u009d\u022b\3\2"+ "\u0244\3\2\2\2\u00ad\u024a\3\2\2\2\u00af\u0250\3\2\2\2\u00b1\u0256\3\2"+
"\2\2\u009f\u0230\3\2\2\2\u00a1\u0234\3\2\2\2\u00a3\u0237\3\2\2\2\u00a5"+ "\2\2\u00b3\u025d\3\2\2\2\u00b5\u0263\3\2\2\2\u00b7\u026a\3\2\2\2\u00b9"+
"\u0239\3\2\2\2\u00a7\u023b\3\2\2\2\u00a9\u023d\3\2\2\2\u00ab\u0240\3\2"+ "\u0270\3\2\2\2\u00bb\u0276\3\2\2\2\u00bd\u027a\3\2\2\2\u00bf\u027d\3\2"+
"\2\2\u00ad\u0245\3\2\2\2\u00af\u024b\3\2\2\2\u00b1\u0251\3\2\2\2\u00b3"+ "\2\2\u00c1\u0283\3\2\2\2\u00c3\u028a\3\2\2\2\u00c5\u0290\3\2\2\2\u00c7"+
"\u0257\3\2\2\2\u00b5\u025c\3\2\2\2\u00b7\u0262\3\2\2\2\u00b9\u0268\3\2"+ "\u029b\3\2\2\2\u00c9\u02a4\3\2\2\2\u00cb\u02a9\3\2\2\2\u00cd\u02ad\3\2"+
"\2\2\u00bb\u026e\3\2\2\2\u00bd\u0275\3\2\2\2\u00bf\u027b\3\2\2\2\u00c1"+ "\2\2\u00cf\u02bb\3\2\2\2\u00d1\u02bd\3\2\2\2\u00d3\u02c3\3\2\2\2\u00d5"+
"\u0282\3\2\2\2\u00c3\u0288\3\2\2\2\u00c5\u028e\3\2\2\2\u00c7\u0292\3\2"+ "\u02c9\3\2\2\2\u00d7\u02d2\3\2\2\2\u00d9\u02e2\3\2\2\2\u00db\u02e4\3\2"+
"\2\2\u00c9\u0295\3\2\2\2\u00cb\u029b\3\2\2\2\u00cd\u02a2\3\2\2\2\u00cf"+ "\2\2\u00dd\u02ef\3\2\2\2\u00df\u00e0\7\u0080\2\2\u00e0\4\3\2\2\2\u00e1"+
"\u02a8\3\2\2\2\u00d1\u02b3\3\2\2\2\u00d3\u02bc\3\2\2\2\u00d5\u02c1\3\2"+ "\u00e2\7<\2\2\u00e2\6\3\2\2\2\u00e3\u00e4\7i\2\2\u00e4\u00e5\7q\2\2\u00e5"+
"\2\2\u00d7\u02c5\3\2\2\2\u00d9\u02d3\3\2\2\2\u00db\u02d5\3\2\2\2\u00dd"+ "\u00e6\7v\2\2\u00e6\u00e7\7q\2\2\u00e7\b\3\2\2\2\u00e8\u00e9\7\'\2\2\u00e9"+
"\u02db\3\2\2\2\u00df\u02e1\3\2\2\2\u00e1\u02ea\3\2\2\2\u00e3\u02fa\3\2"+ "\u00ea\7q\2\2\u00ea\u00eb\7w\2\2\u00eb\u00ec\7v\2\2\u00ec\u00ed\7r\2\2"+
"\2\2\u00e5\u02fc\3\2\2\2\u00e7\u0307\3\2\2\2\u00e9\u00ea\7\u0080\2\2\u00ea"+ "\u00ed\u00ee\7w\2\2\u00ee\u00ef\7v\2\2\u00ef\n\3\2\2\2\u00f0\u00f1\7\'"+
"\4\3\2\2\2\u00eb\u00ec\7<\2\2\u00ec\6\3\2\2\2\u00ed\u00ee\7i\2\2\u00ee"+ "\2\2\u00f1\u00f2\7n\2\2\u00f2\u00f3\7c\2\2\u00f3\u00f4\7w\2\2\u00f4\u00f5"+
"\u00ef\7q\2\2\u00ef\u00f0\7v\2\2\u00f0\u00f1\7q\2\2\u00f1\b\3\2\2\2\u00f2"+ "\7p\2\2\u00f5\u00f6\7e\2\2\u00f6\u00f7\7j\2\2\u00f7\u00f8\7g\2\2\u00f8"+
"\u00f3\7\'\2\2\u00f3\u00f4\7q\2\2\u00f4\u00f5\7w\2\2\u00f5\u00f6\7v\2"+ "\u00f9\7t\2\2\u00f9\f\3\2\2\2\u00fa\u00fb\7\'\2\2\u00fb\u00fc\7|\2\2\u00fc"+
"\2\u00f6\u00f7\7r\2\2\u00f7\u00f8\7w\2\2\u00f8\u00f9\7v\2\2\u00f9\n\3"+ "\u00fd\7g\2\2\u00fd\u00fe\7t\2\2\u00fe\u00ff\7q\2\2\u00ff\u0100\7r\2\2"+
"\2\2\2\u00fa\u00fb\7\'\2\2\u00fb\u00fc\7n\2\2\u00fc\u00fd\7c\2\2\u00fd"+ "\u0100\u0101\7c\2\2\u0101\u0102\7i\2\2\u0102\u0103\7g\2\2\u0103\16\3\2"+
"\u00fe\7w\2\2\u00fe\u00ff\7p\2\2\u00ff\u0100\7e\2\2\u0100\u0101\7j\2\2"+ "\2\2\u0104\u0105\7\'\2\2\u0105\u0106\7c\2\2\u0106\u0107\7f\2\2\u0107\u0108"+
"\u0101\u0102\7g\2\2\u0102\u0103\7t\2\2\u0103\f\3\2\2\2\u0104\u0105\7\'"+ "\7f\2\2\u0108\u0109\7t\2\2\u0109\u010a\7g\2\2\u010a\u010b\7u\2\2\u010b"+
"\2\2\u0105\u0106\7|\2\2\u0106\u0107\7g\2\2\u0107\u0108\7t\2\2\u0108\u0109"+ "\u010c\7u\2\2\u010c\20\3\2\2\2\u010d\u010e\7\'\2\2\u010e\u010f\7k\2\2"+
"\7q\2\2\u0109\u010a\7r\2\2\u010a\u010b\7c\2\2\u010b\u010c\7i\2\2\u010c"+ "\u010f\u0110\7o\2\2\u0110\u0111\7r\2\2\u0111\u0112\7q\2\2\u0112\u0113"+
"\u010d\7g\2\2\u010d\16\3\2\2\2\u010e\u010f\7\'\2\2\u010f\u0110\7c\2\2"+ "\7t\2\2\u0113\u0114\7v\2\2\u0114\22\3\2\2\2\u0115\u0116\7\'\2\2\u0116"+
"\u0110\u0111\7f\2\2\u0111\u0112\7f\2\2\u0112\u0113\7t\2\2\u0113\u0114"+ "\u0117\7d\2\2\u0117\u0118\7t\2\2\u0118\u0119\7g\2\2\u0119\u011a\7c\2\2"+
"\7g\2\2\u0114\u0115\7u\2\2\u0115\u0116\7u\2\2\u0116\20\3\2\2\2\u0117\u0118"+ "\u011a\u011b\7m\2\2\u011b\u011c\7r\2\2\u011c\u011d\7q\2\2\u011d\u011e"+
"\7\'\2\2\u0118\u0119\7k\2\2\u0119\u011a\7o\2\2\u011a\u011b\7r\2\2\u011b"+ "\7k\2\2\u011e\u011f\7p\2\2\u011f\u0120\7v\2\2\u0120\24\3\2\2\2\u0121\u0122"+
"\u011c\7q\2\2\u011c\u011d\7t\2\2\u011d\u011e\7v\2\2\u011e\22\3\2\2\2\u011f"+ "\7\'\2\2\u0122\u0123\7c\2\2\u0123\u0124\7u\2\2\u0124\u0125\7o\2\2\u0125"+
"\u0120\7\'\2\2\u0120\u0121\7d\2\2\u0121\u0122\7t\2\2\u0122\u0123\7g\2"+ "\u0126\7k\2\2\u0126\u0127\7p\2\2\u0127\u0128\7e\2\2\u0128\u0129\7n\2\2"+
"\2\u0123\u0124\7c\2\2\u0124\u0125\7m\2\2\u0125\u0126\7r\2\2\u0126\u0127"+ "\u0129\u012a\7w\2\2\u012a\u012b\7f\2\2\u012b\u012c\7g\2\2\u012c\26\3\2"+
"\7q\2\2\u0127\u0128\7k\2\2\u0128\u0129\7p\2\2\u0129\u012a\7v\2\2\u012a"+ "\2\2\u012d\u012e\7\'\2\2\u012e\u012f\7c\2\2\u012f\u0130\7u\2\2\u0130\u0131"+
"\24\3\2\2\2\u012b\u012c\7\'\2\2\u012c\u012d\7c\2\2\u012d\u012e\7u\2\2"+ "\7o\2\2\u0131\u0132\7d\2\2\u0132\u0133\7k\2\2\u0133\u0134\7p\2\2\u0134"+
"\u012e\u012f\7o\2\2\u012f\u0130\7k\2\2\u0130\u0131\7p\2\2\u0131\u0132"+ "\u0135\7c\2\2\u0135\u0136\7t\2\2\u0136\u0137\7{\2\2\u0137\30\3\2\2\2\u0138"+
"\7e\2\2\u0132\u0133\7n\2\2\u0133\u0134\7w\2\2\u0134\u0135\7f\2\2\u0135"+ "\u0139\7\'\2\2\u0139\u013a\7q\2\2\u013a\u013b\7r\2\2\u013b\u013c\7v\2"+
"\u0136\7g\2\2\u0136\26\3\2\2\2\u0137\u0138\7\'\2\2\u0138\u0139\7c\2\2"+ "\2\u013c\u013d\7k\2\2\u013d\u013e\7q\2\2\u013e\u013f\7p\2\2\u013f\32\3"+
"\u0139\u013a\7u\2\2\u013a\u013b\7o\2\2\u013b\u013c\7d\2\2\u013c\u013d"+ "\2\2\2\u0140\u0141\7.\2\2\u0141\34\3\2\2\2\u0142\u0143\7?\2\2\u0143\36"+
"\7k\2\2\u013d\u013e\7p\2\2\u013e\u013f\7c\2\2\u013f\u0140\7t\2\2\u0140"+ "\3\2\2\2\u0144\u0145\7e\2\2\u0145\u0146\7q\2\2\u0146\u0147\7p\2\2\u0147"+
"\u0141\7{\2\2\u0141\30\3\2\2\2\u0142\u0143\7\'\2\2\u0143\u0144\7q\2\2"+ "\u0148\7u\2\2\u0148\u0149\7v\2\2\u0149 \3\2\2\2\u014a\u014b\7o\2\2\u014b"+
"\u0144\u0145\7r\2\2\u0145\u0146\7v\2\2\u0146\u0147\7k\2\2\u0147\u0148"+ "\u014c\7g\2\2\u014c\u014d\7o\2\2\u014d\u014e\7q\2\2\u014e\u014f\7t\2\2"+
"\7q\2\2\u0148\u0149\7p\2\2\u0149\32\3\2\2\2\u014a\u014b\7.\2\2\u014b\34"+ "\u014f\u0150\7{\2\2\u0150\"\3\2\2\2\u0151\u0152\7d\2\2\u0152\u0153\7{"+
"\3\2\2\2\u014c\u014d\7?\2\2\u014d\36\3\2\2\2\u014e\u014f\7e\2\2\u014f"+ "\2\2\u0153\u0154\7v\2\2\u0154\u0155\7g\2\2\u0155$\3\2\2\2\u0156\u0157"+
"\u0150\7q\2\2\u0150\u0151\7p\2\2\u0151\u0152\7u\2\2\u0152\u0153\7v\2\2"+ "\7y\2\2\u0157\u0158\7q\2\2\u0158\u0159\7t\2\2\u0159\u015a\7f\2\2\u015a"+
"\u0153 \3\2\2\2\u0154\u0155\7o\2\2\u0155\u0156\7g\2\2\u0156\u0157\7o\2"+ "&\3\2\2\2\u015b\u015c\7h\2\2\u015c\u015d\7n\2\2\u015d\u015e\7q\2\2\u015e"+
"\2\u0157\u0158\7q\2\2\u0158\u0159\7t\2\2\u0159\u015a\7{\2\2\u015a\"\3"+ "\u015f\7c\2\2\u015f\u0160\7v\2\2\u0160(\3\2\2\2\u0161\u0162\7u\2\2\u0162"+
"\2\2\2\u015b\u015c\7d\2\2\u015c\u015d\7{\2\2\u015d\u015e\7v\2\2\u015e"+ "\u0163\7v\2\2\u0163\u0164\7t\2\2\u0164*\3\2\2\2\u0165\u0166\7u\2\2\u0166"+
"\u015f\7g\2\2\u015f$\3\2\2\2\u0160\u0161\7y\2\2\u0161\u0162\7q\2\2\u0162"+ "\u0167\7v\2\2\u0167\u0168\7t\2\2\u0168\u0169\7a\2\2\u0169\u016a\7r\2\2"+
"\u0163\7t\2\2\u0163\u0164\7f\2\2\u0164&\3\2\2\2\u0165\u0166\7h\2\2\u0166"+ "\u016a,\3\2\2\2\u016b\u016c\7u\2\2\u016c\u016d\7v\2\2\u016d\u016e\7t\2"+
"\u0167\7n\2\2\u0167\u0168\7q\2\2\u0168\u0169\7c\2\2\u0169\u016a\7v\2\2"+ "\2\u016e\u016f\7a\2\2\u016f\u0170\7u\2\2\u0170.\3\2\2\2\u0171\u0172\7"+
"\u016a(\3\2\2\2\u016b\u016c\7u\2\2\u016c\u016d\7v\2\2\u016d\u016e\7t\2"+ "u\2\2\u0172\u0173\7v\2\2\u0173\u0174\7t\2\2\u0174\u0175\7a\2\2\u0175\u0176"+
"\2\u016e*\3\2\2\2\u016f\u0170\7u\2\2\u0170\u0171\7v\2\2\u0171\u0172\7"+ "\7r\2\2\u0176\u0177\7u\2\2\u0177\60\3\2\2\2\u0178\u0179\7]\2\2\u0179\62"+
"t\2\2\u0172\u0173\7a\2\2\u0173\u0174\7r\2\2\u0174,\3\2\2\2\u0175\u0176"+ "\3\2\2\2\u017a\u017b\7_\2\2\u017b\64\3\2\2\2\u017c\u017d\7-\2\2\u017d"+
"\7u\2\2\u0176\u0177\7v\2\2\u0177\u0178\7t\2\2\u0178\u0179\7a\2\2\u0179"+ "\u017e\7?\2\2\u017e\66\3\2\2\2\u017f\u0180\7/\2\2\u0180\u0181\7?\2\2\u0181"+
"\u017a\7u\2\2\u017a.\3\2\2\2\u017b\u017c\7u\2\2\u017c\u017d\7v\2\2\u017d"+ "8\3\2\2\2\u0182\u0183\7\61\2\2\u0183\u0184\7?\2\2\u0184:\3\2\2\2\u0185"+
"\u017e\7t\2\2\u017e\u017f\7a\2\2\u017f\u0180\7r\2\2\u0180\u0181\7u\2\2"+ "\u0186\7\61\2\2\u0186\u0187\7\61\2\2\u0187\u0188\7?\2\2\u0188<\3\2\2\2"+
"\u0181\60\3\2\2\2\u0182\u0183\7]\2\2\u0183\62\3\2\2\2\u0184\u0185\7_\2"+ "\u0189\u018a\7,\2\2\u018a\u018b\7?\2\2\u018b>\3\2\2\2\u018c\u018d\7,\2"+
"\2\u0185\64\3\2\2\2\u0186\u0187\7-\2\2\u0187\u0188\7?\2\2\u0188\66\3\2"+ "\2\u018d\u018e\7,\2\2\u018e\u018f\7?\2\2\u018f@\3\2\2\2\u0190\u0191\7"+
"\2\2\u0189\u018a\7/\2\2\u018a\u018b\7?\2\2\u018b8\3\2\2\2\u018c\u018d"+ "(\2\2\u0191\u0192\7?\2\2\u0192B\3\2\2\2\u0193\u0194\7~\2\2\u0194\u0195"+
"\7\61\2\2\u018d\u018e\7?\2\2\u018e:\3\2\2\2\u018f\u0190\7\61\2\2\u0190"+ "\7?\2\2\u0195D\3\2\2\2\u0196\u0197\7`\2\2\u0197\u0198\7?\2\2\u0198F\3"+
"\u0191\7\61\2\2\u0191\u0192\7?\2\2\u0192<\3\2\2\2\u0193\u0194\7,\2\2\u0194"+ "\2\2\2\u0199\u019a\7-\2\2\u019a\u019b\7-\2\2\u019bH\3\2\2\2\u019c\u019d"+
"\u0195\7?\2\2\u0195>\3\2\2\2\u0196\u0197\7,\2\2\u0197\u0198\7,\2\2\u0198"+ "\7/\2\2\u019d\u019e\7/\2\2\u019eJ\3\2\2\2\u019f\u01a0\7*\2\2\u01a0L\3"+
"\u0199\7?\2\2\u0199@\3\2\2\2\u019a\u019b\7(\2\2\u019b\u019c\7?\2\2\u019c"+ "\2\2\2\u01a1\u01a2\7+\2\2\u01a2N\3\2\2\2\u01a3\u01a4\7-\2\2\u01a4P\3\2"+
"B\3\2\2\2\u019d\u019e\7~\2\2\u019e\u019f\7?\2\2\u019fD\3\2\2\2\u01a0\u01a1"+ "\2\2\u01a5\u01a6\7/\2\2\u01a6R\3\2\2\2\u01a7\u01a8\7,\2\2\u01a8\u01a9"+
"\7`\2\2\u01a1\u01a2\7?\2\2\u01a2F\3\2\2\2\u01a3\u01a4\7-\2\2\u01a4\u01a5"+ "\7,\2\2\u01a9T\3\2\2\2\u01aa\u01ab\7,\2\2\u01abV\3\2\2\2\u01ac\u01ad\7"+
"\7-\2\2\u01a5H\3\2\2\2\u01a6\u01a7\7/\2\2\u01a7\u01a8\7/\2\2\u01a8J\3"+ "\61\2\2\u01adX\3\2\2\2\u01ae\u01af\7\61\2\2\u01af\u01b0\7\61\2\2\u01b0"+
"\2\2\2\u01a9\u01aa\7*\2\2\u01aaL\3\2\2\2\u01ab\u01ac\7+\2\2\u01acN\3\2"+ "Z\3\2\2\2\u01b1\u01b2\7\'\2\2\u01b2\\\3\2\2\2\u01b3\u01b4\7>\2\2\u01b4"+
"\2\2\u01ad\u01ae\7-\2\2\u01aeP\3\2\2\2\u01af\u01b0\7/\2\2\u01b0R\3\2\2"+ "^\3\2\2\2\u01b5\u01b6\7@\2\2\u01b6`\3\2\2\2\u01b7\u01b8\7>\2\2\u01b8\u01b9"+
"\2\u01b1\u01b2\7,\2\2\u01b2\u01b3\7,\2\2\u01b3T\3\2\2\2\u01b4\u01b5\7"+ "\7?\2\2\u01b9b\3\2\2\2\u01ba\u01bb\7@\2\2\u01bb\u01bc\7?\2\2\u01bcd\3"+
",\2\2\u01b5V\3\2\2\2\u01b6\u01b7\7\61\2\2\u01b7X\3\2\2\2\u01b8\u01b9\7"+ "\2\2\2\u01bd\u01be\7?\2\2\u01be\u01bf\7?\2\2\u01bff\3\2\2\2\u01c0\u01c1"+
"\61\2\2\u01b9\u01ba\7\61\2\2\u01baZ\3\2\2\2\u01bb\u01bc\7\'\2\2\u01bc"+ "\7#\2\2\u01c1\u01c2\7?\2\2\u01c2h\3\2\2\2\u01c3\u01c4\7(\2\2\u01c4j\3"+
"\\\3\2\2\2\u01bd\u01be\7>\2\2\u01be^\3\2\2\2\u01bf\u01c0\7@\2\2\u01c0"+ "\2\2\2\u01c5\u01c6\7`\2\2\u01c6l\3\2\2\2\u01c7\u01c8\7~\2\2\u01c8n\3\2"+
"`\3\2\2\2\u01c1\u01c2\7>\2\2\u01c2\u01c3\7?\2\2\u01c3b\3\2\2\2\u01c4\u01c5"+ "\2\2\u01c9\u01ca\7v\2\2\u01ca\u01cb\7q\2\2\u01cbp\3\2\2\2\u01cc\u01cd"+
"\7@\2\2\u01c5\u01c6\7?\2\2\u01c6d\3\2\2\2\u01c7\u01c8\7?\2\2\u01c8\u01c9"+ "\7u\2\2\u01cd\u01ce\7v\2\2\u01ce\u01cf\7g\2\2\u01cf\u01d0\7r\2\2\u01d0"+
"\7?\2\2\u01c9f\3\2\2\2\u01ca\u01cb\7#\2\2\u01cb\u01cc\7?\2\2\u01cch\3"+ "r\3\2\2\2\u01d1\u01d2\7c\2\2\u01d2\u01d3\7p\2\2\u01d3\u01d4\7f\2\2\u01d4"+
"\2\2\2\u01cd\u01ce\7(\2\2\u01cej\3\2\2\2\u01cf\u01d0\7`\2\2\u01d0l\3\2"+ "t\3\2\2\2\u01d5\u01d6\7q\2\2\u01d6\u01d7\7t\2\2\u01d7v\3\2\2\2\u01d8\u01d9"+
"\2\2\u01d1\u01d2\7~\2\2\u01d2n\3\2\2\2\u01d3\u01d4\7v\2\2\u01d4\u01d5"+ "\7z\2\2\u01d9\u01da\7q\2\2\u01da\u01db\7t\2\2\u01dbx\3\2\2\2\u01dc\u01dd"+
"\7q\2\2\u01d5p\3\2\2\2\u01d6\u01d7\7u\2\2\u01d7\u01d8\7v\2\2\u01d8\u01d9"+ "\7p\2\2\u01dd\u01de\7q\2\2\u01de\u01df\7v\2\2\u01dfz\3\2\2\2\u01e0\u01e1"+
"\7g\2\2\u01d9\u01da\7r\2\2\u01dar\3\2\2\2\u01db\u01dc\7c\2\2\u01dc\u01dd"+ "\7t\2\2\u01e1\u01e2\7g\2\2\u01e2\u01e3\7v\2\2\u01e3\u01e4\7w\2\2\u01e4"+
"\7p\2\2\u01dd\u01de\7f\2\2\u01det\3\2\2\2\u01df\u01e0\7q\2\2\u01e0\u01e1"+ "\u01e5\7t\2\2\u01e5\u01e6\7p\2\2\u01e6|\3\2\2\2\u01e7\u01e8\7d\2\2\u01e8"+
"\7t\2\2\u01e1v\3\2\2\2\u01e2\u01e3\7z\2\2\u01e3\u01e4\7q\2\2\u01e4\u01e5"+ "\u01e9\7t\2\2\u01e9\u01ea\7g\2\2\u01ea\u01eb\7c\2\2\u01eb\u01ec\7m\2\2"+
"\7t\2\2\u01e5x\3\2\2\2\u01e6\u01e7\7p\2\2\u01e7\u01e8\7q\2\2\u01e8\u01e9"+ "\u01ec~\3\2\2\2\u01ed\u01ee\7e\2\2\u01ee\u01ef\7q\2\2\u01ef\u01f0\7p\2"+
"\7v\2\2\u01e9z\3\2\2\2\u01ea\u01eb\7t\2\2\u01eb\u01ec\7g\2\2\u01ec\u01ed"+ "\2\u01f0\u01f1\7v\2\2\u01f1\u01f2\7k\2\2\u01f2\u01f3\7p\2\2\u01f3\u01f4"+
"\7v\2\2\u01ed\u01ee\7w\2\2\u01ee\u01ef\7t\2\2\u01ef\u01f0\7p\2\2\u01f0"+ "\7w\2\2\u01f4\u01f5\7g\2\2\u01f5\u0080\3\2\2\2\u01f6\u01f7\7\60\2\2\u01f7"+
"|\3\2\2\2\u01f1\u01f2\7d\2\2\u01f2\u01f3\7t\2\2\u01f3\u01f4\7g\2\2\u01f4"+ "\u0082\3\2\2\2\u01f8\u01f9\7C\2\2\u01f9\u0084\3\2\2\2\u01fa\u01fb\7Z\2"+
"\u01f5\7c\2\2\u01f5\u01f6\7m\2\2\u01f6~\3\2\2\2\u01f7\u01f8\7e\2\2\u01f8"+ "\2\u01fb\u0086\3\2\2\2\u01fc\u01fd\7[\2\2\u01fd\u0088\3\2\2\2\u01fe\u01ff"+
"\u01f9\7q\2\2\u01f9\u01fa\7p\2\2\u01fa\u01fb\7v\2\2\u01fb\u01fc\7k\2\2"+ "\7C\2\2\u01ff\u0200\7Z\2\2\u0200\u008a\3\2\2\2\u0201\u0202\7C\2\2\u0202"+
"\u01fc\u01fd\7p\2\2\u01fd\u01fe\7w\2\2\u01fe\u01ff\7g\2\2\u01ff\u0080"+ "\u0203\7[\2\2\u0203\u008c\3\2\2\2\u0204\u0205\7Z\2\2\u0205\u0206\7[\2"+
"\3\2\2\2\u0200\u0201\7\60\2\2\u0201\u0082\3\2\2\2\u0202\u0203\7C\2\2\u0203"+ "\2\u0206\u008e\3\2\2\2\u0207\u0208\7\60\2\2\u0208\u0209\7y\2\2\u0209\u0090"+
"\u0084\3\2\2\2\u0204\u0205\7Z\2\2\u0205\u0086\3\2\2\2\u0206\u0207\7[\2"+ "\3\2\2\2\u020a\u020b\7v\2\2\u020b\u020c\7t\2\2\u020c\u020d\7w\2\2\u020d"+
"\2\u0207\u0088\3\2\2\2\u0208\u0209\7C\2\2\u0209\u020a\7Z\2\2\u020a\u008a"+ "\u020e\7g\2\2\u020e\u0092\3\2\2\2\u020f\u0210\7h\2\2\u0210\u0211\7c\2"+
"\3\2\2\2\u020b\u020c\7C\2\2\u020c\u020d\7[\2\2\u020d\u008c\3\2\2\2\u020e"+ "\2\u0211\u0212\7n\2\2\u0212\u0213\7u\2\2\u0213\u0214\7g\2\2\u0214\u0094"+
"\u020f\7Z\2\2\u020f\u0210\7[\2\2\u0210\u008e\3\2\2\2\u0211\u0212\7R\2"+ "\3\2\2\2\u0215\u0216\7\'\2\2\u0216\u0217\7c\2\2\u0217\u0218\7u\2\2\u0218"+
"\2\u0212\u0213\7e\2\2\u0213\u0090\3\2\2\2\u0214\u0215\7R\2\2\u0215\u0216"+ "\u0219\7o\2\2\u0219\u0096\3\2\2\2\u021a\u021b\7u\2\2\u021b\u021c\7w\2"+
"\7|\2\2\u0216\u0092\3\2\2\2\u0217\u0218\7R\2\2\u0218\u0219\7p\2\2\u0219"+ "\2\u021c\u021d\7d\2\2\u021d\u0098\3\2\2\2\u021e\u021f\7/\2\2\u021f\u0220"+
"\u0094\3\2\2\2\u021a\u021b\7R\2\2\u021b\u021c\7x\2\2\u021c\u0096\3\2\2"+ "\7@\2\2\u0220\u009a\3\2\2\2\u0221\u0222\7}\2\2\u0222\u009c\3\2\2\2\u0223"+
"\2\u021d\u021e\7\60\2\2\u021e\u021f\7y\2\2\u021f\u0098\3\2\2\2\u0220\u0221"+ "\u0224\7\177\2\2\u0224\u009e\3\2\2\2\u0225\u0226\7k\2\2\u0226\u0227\7"+
"\7v\2\2\u0221\u0222\7t\2\2\u0222\u0223\7w\2\2\u0223\u0224\7g\2\2\u0224"+ "h\2\2\u0227\u00a0\3\2\2\2\u0228\u0229\7g\2\2\u0229\u022a\7n\2\2\u022a"+
"\u009a\3\2\2\2\u0225\u0226\7h\2\2\u0226\u0227\7c\2\2\u0227\u0228\7n\2"+ "\u022b\7u\2\2\u022b\u022c\7g\2\2\u022c\u00a2\3\2\2\2\u022d\u022e\7k\2"+
"\2\u0228\u0229\7u\2\2\u0229\u022a\7g\2\2\u022a\u009c\3\2\2\2\u022b\u022c"+ "\2\u022e\u022f\7h\2\2\u022f\u0230\7a\2\2\u0230\u0231\7e\2\2\u0231\u0232"+
"\7\'\2\2\u022c\u022d\7c\2\2\u022d\u022e\7u\2\2\u022e\u022f\7o\2\2\u022f"+ "\7u\2\2\u0232\u00a4\3\2\2\2\u0233\u0234\7k\2\2\u0234\u0235\7h\2\2\u0235"+
"\u009e\3\2\2\2\u0230\u0231\7u\2\2\u0231\u0232\7w\2\2\u0232\u0233\7d\2"+ "\u0236\7a\2\2\u0236\u0237\7e\2\2\u0237\u0238\7e\2\2\u0238\u00a6\3\2\2"+
"\2\u0233\u00a0\3\2\2\2\u0234\u0235\7/\2\2\u0235\u0236\7@\2\2\u0236\u00a2"+ "\2\u0239\u023a\7k\2\2\u023a\u023b\7h\2\2\u023b\u023c\7a\2\2\u023c\u023d"+
"\3\2\2\2\u0237\u0238\7}\2\2\u0238\u00a4\3\2\2\2\u0239\u023a\7\177\2\2"+ "\7g\2\2\u023d\u023e\7s\2\2\u023e\u00a8\3\2\2\2\u023f\u0240\7k\2\2\u0240"+
"\u023a\u00a6\3\2\2\2\u023b\u023c\7A\2\2\u023c\u00a8\3\2\2\2\u023d\u023e"+ "\u0241\7h\2\2\u0241\u0242\7a\2\2\u0242\u0243\7|\2\2\u0243\u00aa\3\2\2"+
"\7k\2\2\u023e\u023f\7h\2\2\u023f\u00aa\3\2\2\2\u0240\u0241\7g\2\2\u0241"+ "\2\u0244\u0245\7k\2\2\u0245\u0246\7h\2\2\u0246\u0247\7a\2\2\u0247\u0248"+
"\u0242\7n\2\2\u0242\u0243\7u\2\2\u0243\u0244\7g\2\2\u0244\u00ac\3\2\2"+ "\7p\2\2\u0248\u0249\7g\2\2\u0249\u00ac\3\2\2\2\u024a\u024b\7k\2\2\u024b"+
"\2\u0245\u0246\7k\2\2\u0246\u0247\7h\2\2\u0247\u0248\7a\2\2\u0248\u0249"+ "\u024c\7h\2\2\u024c\u024d\7a\2\2\u024d\u024e\7p\2\2\u024e\u024f\7|\2\2"+
"\7e\2\2\u0249\u024a\7u\2\2\u024a\u00ae\3\2\2\2\u024b\u024c\7k\2\2\u024c"+ "\u024f\u00ae\3\2\2\2\u0250\u0251\7k\2\2\u0251\u0252\7h\2\2\u0252\u0253"+
"\u024d\7h\2\2\u024d\u024e\7a\2\2\u024e\u024f\7e\2\2\u024f\u0250\7e\2\2"+ "\7a\2\2\u0253\u0254\7r\2\2\u0254\u0255\7n\2\2\u0255\u00b0\3\2\2\2\u0256"+
"\u0250\u00b0\3\2\2\2\u0251\u0252\7k\2\2\u0252\u0253\7h\2\2\u0253\u0254"+ "\u0257\7k\2\2\u0257\u0258\7h\2\2\u0258\u0259\7a\2\2\u0259\u025a\7r\2\2"+
"\7a\2\2\u0254\u0255\7g\2\2\u0255\u0256\7s\2\2\u0256\u00b2\3\2\2\2\u0257"+ "\u025a\u025b\7q\2\2\u025b\u025c\7u\2\2\u025c\u00b2\3\2\2\2\u025d\u025e"+
"\u0258\7k\2\2\u0258\u0259\7h\2\2\u0259\u025a\7a\2\2\u025a\u025b\7|\2\2"+ "\7k\2\2\u025e\u025f\7h\2\2\u025f\u0260\7a\2\2\u0260\u0261\7o\2\2\u0261"+
"\u025b\u00b4\3\2\2\2\u025c\u025d\7k\2\2\u025d\u025e\7h\2\2\u025e\u025f"+ "\u0262\7k\2\2\u0262\u00b4\3\2\2\2\u0263\u0264\7k\2\2\u0264\u0265\7h\2"+
"\7a\2\2\u025f\u0260\7p\2\2\u0260\u0261\7g\2\2\u0261\u00b6\3\2\2\2\u0262"+ "\2\u0265\u0266\7a\2\2\u0266\u0267\7p\2\2\u0267\u0268\7g\2\2\u0268\u0269"+
"\u0263\7k\2\2\u0263\u0264\7h\2\2\u0264\u0265\7a\2\2\u0265\u0266\7p\2\2"+ "\7i\2\2\u0269\u00b6\3\2\2\2\u026a\u026b\7k\2\2\u026b\u026c\7h\2\2\u026c"+
"\u0266\u0267\7|\2\2\u0267\u00b8\3\2\2\2\u0268\u0269\7k\2\2\u0269\u026a"+ "\u026d\7a\2\2\u026d\u026e\7x\2\2\u026e\u026f\7u\2\2\u026f\u00b8\3\2\2"+
"\7h\2\2\u026a\u026b\7a\2\2\u026b\u026c\7r\2\2\u026c\u026d\7n\2\2\u026d"+ "\2\u0270\u0271\7k\2\2\u0271\u0272\7h\2\2\u0272\u0273\7a\2\2\u0273\u0274"+
"\u00ba\3\2\2\2\u026e\u026f\7k\2\2\u026f\u0270\7h\2\2\u0270\u0271\7a\2"+ "\7x\2\2\u0274\u0275\7e\2\2\u0275\u00ba\3\2\2\2\u0276\u0277\7h\2\2\u0277"+
"\2\u0271\u0272\7r\2\2\u0272\u0273\7q\2\2\u0273\u0274\7u\2\2\u0274\u00bc"+ "\u0278\7q\2\2\u0278\u0279\7t\2\2\u0279\u00bc\3\2\2\2\u027a\u027b\7k\2"+
"\3\2\2\2\u0275\u0276\7k\2\2\u0276\u0277\7h\2\2\u0277\u0278\7a\2\2\u0278"+ "\2\u027b\u027c\7p\2\2\u027c\u00be\3\2\2\2\u027d\u027e\7y\2\2\u027e\u027f"+
"\u0279\7o\2\2\u0279\u027a\7k\2\2\u027a\u00be\3\2\2\2\u027b\u027c\7k\2"+ "\7j\2\2\u027f\u0280\7k\2\2\u0280\u0281\7n\2\2\u0281\u0282\7g\2\2\u0282"+
"\2\u027c\u027d\7h\2\2\u027d\u027e\7a\2\2\u027e\u027f\7p\2\2\u027f\u0280"+ "\u00c0\3\2\2\2\u0283\u0284\7t\2\2\u0284\u0285\7g\2\2\u0285\u0286\7r\2"+
"\7g\2\2\u0280\u0281\7i\2\2\u0281\u00c0\3\2\2\2\u0282\u0283\7k\2\2\u0283"+ "\2\u0286\u0287\7g\2\2\u0287\u0288\7c\2\2\u0288\u0289\7v\2\2\u0289\u00c2"+
"\u0284\7h\2\2\u0284\u0285\7a\2\2\u0285\u0286\7x\2\2\u0286\u0287\7u\2\2"+ "\3\2\2\2\u028a\u028b\7w\2\2\u028b\u028c\7p\2\2\u028c\u028d\7v\2\2\u028d"+
"\u0287\u00c2\3\2\2\2\u0288\u0289\7k\2\2\u0289\u028a\7h\2\2\u028a\u028b"+ "\u028e\7k\2\2\u028e\u028f\7n\2\2\u028f\u00c4\3\2\2\2\u0290\u0294\t\2\2"+
"\7a\2\2\u028b\u028c\7x\2\2\u028c\u028d\7e\2\2\u028d\u00c4\3\2\2\2\u028e"+ "\2\u0291\u0293\t\3\2\2\u0292\u0291\3\2\2\2\u0293\u0296\3\2\2\2\u0294\u0292"+
"\u028f\7h\2\2\u028f\u0290\7q\2\2\u0290\u0291\7t\2\2\u0291\u00c6\3\2\2"+ "\3\2\2\2\u0294\u0295\3\2\2\2\u0295\u0297\3\2\2\2\u0296\u0294\3\2\2\2\u0297"+
"\2\u0292\u0293\7k\2\2\u0293\u0294\7p\2\2\u0294\u00c8\3\2\2\2\u0295\u0296"+ "\u0298\5\u00c7d\2\u0298\u0299\3\2\2\2\u0299\u029a\bc\2\2\u029a\u00c6\3"+
"\7y\2\2\u0296\u0297\7j\2\2\u0297\u0298\7k\2\2\u0298\u0299\7n\2\2\u0299"+ "\2\2\2\u029b\u029f\7=\2\2\u029c\u029e\n\2\2\2\u029d\u029c\3\2\2\2\u029e"+
"\u029a\7g\2\2\u029a\u00ca\3\2\2\2\u029b\u029c\7t\2\2\u029c\u029d\7g\2"+ "\u02a1\3\2\2\2\u029f\u029d\3\2\2\2\u029f\u02a0\3\2\2\2\u02a0\u02a2\3\2"+
"\2\u029d\u029e\7r\2\2\u029e\u029f\7g\2\2\u029f\u02a0\7c\2\2\u02a0\u02a1"+ "\2\2\u02a1\u029f\3\2\2\2\u02a2\u02a3\bd\2\2\u02a3\u00c8\3\2\2\2\u02a4"+
"\7v\2\2\u02a1\u00cc\3\2\2\2\u02a2\u02a3\7w\2\2\u02a3\u02a4\7p\2\2\u02a4"+ "\u02a5\t\3\2\2\u02a5\u02a6\3\2\2\2\u02a6\u02a7\be\3\2\u02a7\u00ca\3\2"+
"\u02a5\7v\2\2\u02a5\u02a6\7k\2\2\u02a6\u02a7\7n\2\2\u02a7\u00ce\3\2\2"+ "\2\2\u02a8\u02aa\t\2\2\2\u02a9\u02a8\3\2\2\2\u02aa\u02ab\3\2\2\2\u02ab"+
"\2\u02a8\u02ac\t\2\2\2\u02a9\u02ab\t\3\2\2\u02aa\u02a9\3\2\2\2\u02ab\u02ae"+ "\u02a9\3\2\2\2\u02ab\u02ac\3\2\2\2\u02ac\u00cc\3\2\2\2\u02ad\u02b1\t\4"+
"\3\2\2\2\u02ac\u02aa\3\2\2\2\u02ac\u02ad\3\2\2\2\u02ad\u02af\3\2\2\2\u02ae"+ "\2\2\u02ae\u02b0\t\5\2\2\u02af\u02ae\3\2\2\2\u02b0\u02b3\3\2\2\2\u02b1"+
"\u02ac\3\2\2\2\u02af\u02b0\5\u00d1i\2\u02b0\u02b1\3\2\2\2\u02b1\u02b2"+ "\u02af\3\2\2\2\u02b1\u02b2\3\2\2\2\u02b2\u00ce\3\2\2\2\u02b3\u02b1\3\2"+
"\bh\2\2\u02b2\u00d0\3\2\2\2\u02b3\u02b7\7=\2\2\u02b4\u02b6\n\2\2\2\u02b5"+ "\2\2\u02b4\u02bc\4\62;\2\u02b5\u02b7\4\63;\2\u02b6\u02b8\4\62;\2\u02b7"+
"\u02b4\3\2\2\2\u02b6\u02b9\3\2\2\2\u02b7\u02b5\3\2\2\2\u02b7\u02b8\3\2"+ "\u02b6\3\2\2\2\u02b8\u02b9\3\2\2\2\u02b9\u02b7\3\2\2\2\u02b9\u02ba\3\2"+
"\2\2\u02b8\u02ba\3\2\2\2\u02b9\u02b7\3\2\2\2\u02ba\u02bb\bi\2\2\u02bb"+ "\2\2\u02ba\u02bc\3\2\2\2\u02bb\u02b4\3\2\2\2\u02bb\u02b5\3\2\2\2\u02bc"+
"\u00d2\3\2\2\2\u02bc\u02bd\t\3\2\2\u02bd\u02be\3\2\2\2\u02be\u02bf\bj"+ "\u00d0\3\2\2\2\u02bd\u02bf\7&\2\2\u02be\u02c0\t\6\2\2\u02bf\u02be\3\2"+
"\3\2\u02bf\u00d4\3\2\2\2\u02c0\u02c2\t\2\2\2\u02c1\u02c0\3\2\2\2\u02c2"+ "\2\2\u02c0\u02c1\3\2\2\2\u02c1\u02bf\3\2\2\2\u02c1\u02c2\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"+ "\u00d2\3\2\2\2\u02c3\u02c5\7\'\2\2\u02c4\u02c6\4\62\63\2\u02c5\u02c4\3"+
"\2\2\u02c5\u02c9\t\4\2\2\u02c6\u02c8\t\5\2\2\u02c7\u02c6\3\2\2\2\u02c8"+ "\2\2\2\u02c6\u02c7\3\2\2\2\u02c7\u02c5\3\2\2\2\u02c7\u02c8\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"+ "\u00d4\3\2\2\2\u02c9\u02cf\5\u00d7l\2\u02ca\u02cc\t\7\2\2\u02cb\u02cd"+
"\2\2\u02cb\u02c9\3\2\2\2\u02cc\u02d4\4\62;\2\u02cd\u02cf\4\63;\2\u02ce"+ "\t\b\2\2\u02cc\u02cb\3\2\2\2\u02cc\u02cd\3\2\2\2\u02cd\u02ce\3\2\2\2\u02ce"+
"\u02d0\4\62;\2\u02cf\u02ce\3\2\2\2\u02d0\u02d1\3\2\2\2\u02d1\u02cf\3\2"+ "\u02d0\5\u00d7l\2\u02cf\u02ca\3\2\2\2\u02cf\u02d0\3\2\2\2\u02d0\u00d6"+
"\2\2\u02d1\u02d2\3\2\2\2\u02d2\u02d4\3\2\2\2\u02d3\u02cc\3\2\2\2\u02d3"+ "\3\2\2\2\u02d1\u02d3\4\62;\2\u02d2\u02d1\3\2\2\2\u02d3\u02d4\3\2\2\2\u02d4"+
"\u02cd\3\2\2\2\u02d4\u00da\3\2\2\2\u02d5\u02d7\7&\2\2\u02d6\u02d8\t\6"+ "\u02d2\3\2\2\2\u02d4\u02d5\3\2\2\2\u02d5\u02dc\3\2\2\2\u02d6\u02d8\7\60"+
"\2\2\u02d7\u02d6\3\2\2\2\u02d8\u02d9\3\2\2\2\u02d9\u02d7\3\2\2\2\u02d9"+ "\2\2\u02d7\u02d9\4\62;\2\u02d8\u02d7\3\2\2\2\u02d9\u02da\3\2\2\2\u02da"+
"\u02da\3\2\2\2\u02da\u00dc\3\2\2\2\u02db\u02dd\7\'\2\2\u02dc\u02de\4\62"+ "\u02d8\3\2\2\2\u02da\u02db\3\2\2\2\u02db\u02dd\3\2\2\2\u02dc\u02d6\3\2"+
"\63\2\u02dd\u02dc\3\2\2\2\u02de\u02df\3\2\2\2\u02df\u02dd\3\2\2\2\u02df"+ "\2\2\u02dc\u02dd\3\2\2\2\u02dd\u00d8\3\2\2\2\u02de\u02df\7^\2\2\u02df"+
"\u02e0\3\2\2\2\u02e0\u00de\3\2\2\2\u02e1\u02e7\5\u00e1q\2\u02e2\u02e4"+ "\u02e3\13\2\2\2\u02e0\u02e1\7^\2\2\u02e1\u02e3\5\u00cbf\2\u02e2\u02de"+
"\t\7\2\2\u02e3\u02e5\t\b\2\2\u02e4\u02e3\3\2\2\2\u02e4\u02e5\3\2\2\2\u02e5"+ "\3\2\2\2\u02e2\u02e0\3\2\2\2\u02e3\u00da\3\2\2\2\u02e4\u02e9\7$\2\2\u02e5"+
"\u02e6\3\2\2\2\u02e6\u02e8\5\u00e1q\2\u02e7\u02e2\3\2\2\2\u02e7\u02e8"+ "\u02e8\5\u00d9m\2\u02e6\u02e8\n\t\2\2\u02e7\u02e5\3\2\2\2\u02e7\u02e6"+
"\3\2\2\2\u02e8\u00e0\3\2\2\2\u02e9\u02eb\4\62;\2\u02ea\u02e9\3\2\2\2\u02eb"+ "\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\u02ec\u02ea\3\2\2\2\u02ec\u02ed\3\2\2\2\u02ed\u02f4\3\2"+ "\u02ec\3\2\2\2\u02eb\u02e9\3\2\2\2\u02ec\u02ed\7$\2\2\u02ed\u02ee\bn\4"+
"\2\2\u02ee\u02f0\7\60\2\2\u02ef\u02f1\4\62;\2\u02f0\u02ef\3\2\2\2\u02f1"+ "\2\u02ee\u00dc\3\2\2\2\u02ef\u02f0\7}\2\2\u02f0\u02f1\7}\2\2\u02f1\u02f3"+
"\u02f2\3\2\2\2\u02f2\u02f0\3\2\2\2\u02f2\u02f3\3\2\2\2\u02f3\u02f5\3\2"+ "\3\2\2\2\u02f2\u02f4\13\2\2\2\u02f3\u02f2\3\2\2\2\u02f4\u02f5\3\2\2\2"+
"\2\2\u02f4\u02ee\3\2\2\2\u02f4\u02f5\3\2\2\2\u02f5\u00e2\3\2\2\2\u02f6"+ "\u02f5\u02f6\3\2\2\2\u02f5\u02f3\3\2\2\2\u02f6\u02f7\3\2\2\2\u02f7\u02f8"+
"\u02f7\7^\2\2\u02f7\u02fb\13\2\2\2\u02f8\u02f9\7^\2\2\u02f9\u02fb\5\u00d5"+ "\7\177\2\2\u02f8\u02f9\7\177\2\2\u02f9\u02fa\3\2\2\2\u02fa\u02fb\bo\5"+
"k\2\u02fa\u02f6\3\2\2\2\u02fa\u02f8\3\2\2\2\u02fb\u00e4\3\2\2\2\u02fc"+ "\2\u02fb\u00de\3\2\2\2\25\2\u0294\u029f\u02ab\u02b1\u02b9\u02bb\u02bf"+
"\u0301\7$\2\2\u02fd\u0300\5\u00e3r\2\u02fe\u0300\n\t\2\2\u02ff\u02fd\3"+ "\u02c1\u02c7\u02cc\u02cf\u02d4\u02da\u02dc\u02e2\u02e7\u02e9\u02f5\6\2"+
"\2\2\2\u02ff\u02fe\3\2\2\2\u0300\u0303\3\2\2\2\u0301\u02ff\3\2\2\2\u0301"+ "\3\2\b\2\2\3n\2\3o\3";
"\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";
public static final ATN _ATN = public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray()); new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static { 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):: As any subroutine, it has to end with a ``return`` statement (or a ``goto`` call)::
~ main { ~ main {
sub start () -> () { sub start () {
; program entrypoint code here ; program entrypoint code here
return 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. 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. 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).
Subroutines can be defined in a Block, but also nested inside another subroutine. Everything is scoped accordingly. 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 Calling a subroutine
^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
The output variables must occur in the correct sequence of return registers as specified The arguments in parentheses after the function name, should match the parameters in the subroutine definition.
in the subroutine's definiton. It is possible to not specify any of them but the compiler The output variables must occur in the correct sequence of return values as specified
will issue a warning then if the result values of a subroutine call are discarded. in the subroutine's definiton. It is possible to not store the return values but the compiler
If you don't have a variable to store the output register in, it's then required will issue a warning then telling you the result values of a subroutine call are discarded.
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.
.. caution:: .. caution::
Note that *recursive* subroutine calls are not supported at this time. Note that *recursive* subroutine calls are not supported at this time.

View File

@ -411,42 +411,39 @@ Subroutine definitions
The syntax is:: The syntax is::
sub <identifier> ([proc_parameters]) -> ([proc_results]) { sub <identifier> ( [parameters] ) [ -> returnvalues ] {
... statements ... ... statements ...
} }
; example: ; example:
sub triple_something (amount: X) -> A { sub triple_something (amount: word) -> word {
return X * 3 return X * 3
} }
The open curly brace must immediately follow the subroutine result specification on the same line, 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. 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 .. todo::
(in system ROM for instance) can be defined by assigning the routine's memory address to the sub, Pre-defined subroutines that are available on specific memory addresses
and not specifying a code block:: (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: ; example:
sub CLOSE (logical: A) -> (A?, X?, Y?) = $FFC3 sub CLOSE (logical: A) -> (A?, X?, Y?) = $FFC3
.. data:: proc_parameters .. data:: parameters
comma separated list of "<parametername>:<register>" pairs specifying the input parameters. Comma separated list of "<parametername>:<datatype>" pairs specifying the input parameters.
You can omit these parameter names in subroutine calls, as long as the arguments "line up". Can be empty.
.. data:: proc_results .. data:: proc_results
comma separated list of <register> names specifying in which register(s) the output is returned. Comma separated list of result value datatypes.
If the register name ends with a '?', that means the register doesn't contain a real return value but A subroutine without return values must omit the whole part with the arrow
is clobbered in the process so the original value it had before calling the sub is no longer valid. after the parameter list.
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")
Loops Loops