now explicit separation between byte and word literal integers

This commit is contained in:
Irmen de Jong 2018-09-13 22:31:59 +02:00
parent 949e468543
commit ea94063689
20 changed files with 1269 additions and 1078 deletions

View File

@ -248,6 +248,18 @@ type identifier type storage size example var declara
=============== ======================= ================= =========================================
**hexadecimal numbers:** you can use a dollar prefix to write hexadecimal numbers: ``$20ac``
**binary numbers:** you can use a percent prefix to write binary numbers: ``%10010011``
**``byte`` versus ``word`` values:**
- When an integer value ranges from 0..255 the compiler sees it as a ``byte``.
- When an integer value ranges from 256..65535 the compiler sees it as a ``word``.
- When a hex number has 3 or 4 digits, for example ``$0004``, it is seen as a ``word`` otherwise as a ``byte``.
- When a binary number has 9 to 16 digits, for example ``%1100110011``, it is seen as a ``word`` otherwise as a ``byte``.
- You can force a byte value into a word value by adding the ``.w`` datatype suffix to the number: ``$2a.w`` is equivalent to ``$002a``.
**@todo pointers/addresses? (as opposed to normal WORDs)**
**@todo signed integers (byte and word)?**

View File

@ -1,10 +1,10 @@
/*
IL65 combined lexer bitand parser grammar
IL65 combined lexer and parser grammar
NOTES:
- whitespace is ignored. (tabs/spaces)
- every position can be empty, be a comment, bitor contain ONE statement.
- every position can be empty, be a comment, or contain ONE statement.
*/
@ -155,7 +155,9 @@ register : 'A' | 'X' | 'Y' | 'AX' | 'AY' | 'XY' ;
statusflag : 'Pc' | 'Pz' | 'Pn' | 'Pv' ;
integerliteral : DEC_INTEGER | HEX_INTEGER | BIN_INTEGER ;
integerliteral : intpart=(DEC_INTEGER | HEX_INTEGER | BIN_INTEGER) wordsuffix? ;
wordsuffix : '.w' ;
booleanliteral : 'true' | 'false' ;

View File

@ -9,8 +9,8 @@
byte [2,3] matrix1 = 2
byte [2,3] matrix2 = [1,2,3,4,5,6]
const byte [100] carray1 = 0
const word [100] carray2 = 1
const byte [100] carray1 = 2
const word [100] carray2 = 1.w
const byte [2,3] cmatrix1 = [1,2,3,4,5,255]
@ -30,7 +30,13 @@
const word len1 = len([1,2,3,wa1, wa2, ws1, all1])
const word wa1 = ceil(abs(-999.22))
const byte wa1b = abs(99)
const byte wa1c = -(1-99)
const byte wa1d = -0
const byte wa2 = abs(-99)
const byte wa2b= abs(-99.w)
const byte wa2c = abs(-99)
const word wa2d = abs(-999)
const float wa3 = abs(-1.23456)
const float wa4 = abs(-133)
const float avg1 = avg([-1.23456, 99999])
@ -44,7 +50,7 @@
const word all2 = all([0.0])
const word all3 = all([wa1, wa2, ws1, all1])
const word max1 = max([-1,-2,3,99+22])
const word max1 = max([-1,-2,3.33,99+22])
const word min1 = min([1,2,3,99+22])
word dinges = round(not_main.len1)
@ -154,12 +160,21 @@
sub start () -> () {
word dinges = 0
word blerp1 =99
word blerp1 =999
word blerp3 = 1
byte blerp2 =99
dinges=blerp1
A=blerp1 ; @todo error can't assign word to byte
A=blerp3 ; @todo error can't assign word to byte
blerp2=blerp3; @todo error can't assign word to byte
blerp3 = blerp2
A=blerp2
A=9999
A=$02
A=$002
A=$00ff
A=%11001100
A=%0010011001
A=99.w
XY=blerp1
X=blerp1 ; @todo error can't assign word to byte
X=blerp2

View File

@ -15,7 +15,7 @@ fun main(args: Array<String>) {
println("\nIL65 compiler by Irmen de Jong (irmen@razorvine.net)")
println("This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html\n")
// import main module bitand process additional imports
// import main module and process additional imports
if(args.size != 1) {
System.err.println("module filename argument missing")
@ -46,7 +46,7 @@ fun main(args: Array<String>) {
)
// perform syntax checks bitand optimizations
// perform syntax checks and optimizations
moduleAst.checkIdentifiers()
moduleAst.optimizeExpressions(globalNameSpaceBeforeOptimization)
moduleAst.checkValid(globalNameSpaceBeforeOptimization, compilerOptions) // check if tree is valid
@ -59,7 +59,7 @@ fun main(args: Array<String>) {
// globalNamespaceAfterOptimize.debugPrint()
// compile the syntax tree into stackvmProg form, bitand optimize that
// compile the syntax tree into stackvmProg form, and optimize that
val compiler = Compiler(compilerOptions)
val intermediate = compiler.compile(moduleAst)
intermediate.optimize()

View File

@ -5,6 +5,7 @@ import il65.parser.il65Parser
import org.antlr.v4.runtime.ParserRuleContext
import org.antlr.v4.runtime.tree.TerminalNode
import java.nio.file.Paths
import kotlin.math.floor
/**************************** AST Data classes ****************************/
@ -86,7 +87,7 @@ data class Position(val file: String, val line: Int, val startCol: Int, val endC
interface IAstProcessor {
fun process(module: Module) {
module.statements = module.statements.map { it.process(this) }.toMutableList()
module.statements = module.statements.asSequence().map { it.process(this) }.toMutableList()
}
fun process(expr: PrefixExpression): IExpression {
@ -105,7 +106,7 @@ interface IAstProcessor {
}
fun process(block: Block): IStatement {
block.statements = block.statements.map { it.process(this) }.toMutableList()
block.statements = block.statements.asSequence().map { it.process(this) }.toMutableList()
return block
}
@ -116,7 +117,7 @@ interface IAstProcessor {
}
fun process(subroutine: Subroutine): IStatement {
subroutine.statements = subroutine.statements.map { it.process(this) }.toMutableList()
subroutine.statements = subroutine.statements.asSequence().map { it.process(this) }.toMutableList()
return subroutine
}
@ -197,7 +198,7 @@ interface Node {
}
// find the parent node of a specific type bitor interface
// find the parent node of a specific type or interface
// (useful to figure out in what namespace/block something is defined, etc)
inline fun <reified T> findParentNode(node: Node): T? {
var candidate = node.parent
@ -243,9 +244,9 @@ interface INameScope {
fun registerUsedName(name: String)
fun subScopes() = statements.filter { it is INameScope } .map { it as INameScope }.associate { it.name to it }
fun subScopes() = statements.asSequence().filter { it is INameScope }.map { it as INameScope }.associate { it.name to it }
fun labelsAndVariables() = statements.filter { it is Label || it is VarDecl }
fun labelsAndVariables() = statements.asSequence().filter { it is Label || it is VarDecl }
.associate {((it as? Label)?.name ?: (it as? VarDecl)?.name) to it }
fun lookup(scopedName: List<String>, statement: Node) : IStatement? {
@ -302,7 +303,7 @@ interface INameScope {
/**
* Inserted into the Ast in place of modified nodes (not inserted directly as a parser result)
* It can hold zero bitor more replacement statements that have to be inserted at that point.
* It can hold zero or more replacement statements that have to be inserted at that point.
*/
class AnonymousStatementList(override var parent: Node, var statements: List<IStatement>) : IStatement {
override var position: Position? = null
@ -371,7 +372,7 @@ private class GlobalNamespace(override val name: String,
override var statements: MutableList<IStatement>,
override val position: Position?) : INameScope {
private val scopedNamesUsed: MutableSet<String> = mutableSetOf("main", "main.start") // main bitand main.start are always used
private val scopedNamesUsed: MutableSet<String> = mutableSetOf("main", "main.start") // main and main.start are always used
override fun usedNames(): Set<String> = scopedNamesUsed
@ -548,16 +549,16 @@ class VarDecl(val type: VarDeclType,
}
DataType.ARRAY -> {
val aX = arrayspec?.x as? LiteralValue ?: throw ExpressionError("need constant value expression for arrayspec", position)
aX.intvalue!!
aX.asIntegerValue!!
}
DataType.ARRAY_W -> {
val aX = arrayspec?.x as? LiteralValue ?: throw ExpressionError("need constant value expression for arrayspec", position)
2*aX.intvalue!!
2*aX.asIntegerValue!!
}
DataType.MATRIX -> {
val aX = arrayspec?.x as? LiteralValue ?: throw ExpressionError("need constant value expression for arrayspec", position)
val aY = arrayspec.y as? LiteralValue ?: throw ExpressionError("need constant value expression for arrayspec", position)
aX.intvalue!! * aY.intvalue!!
aX.asIntegerValue!! * aY.asIntegerValue!!
}
}
@ -576,7 +577,7 @@ class VarDecl(val type: VarDeclType,
else -> when (declaredDatatype) {
DataType.BYTE -> DataType.ARRAY
DataType.WORD -> DataType.ARRAY_W
else -> throw SyntaxError("array can only contain bytes bitor words", position)
else -> throw SyntaxError("array can only contain bytes or words", position)
}
}
}
@ -666,7 +667,13 @@ class BinaryExpression(var left: IExpression, val operator: String, var right: I
override fun referencesIdentifier(name: String) = left.referencesIdentifier(name) || right.referencesIdentifier(name)
}
data class LiteralValue(val intvalue: Int? = null,
private data class ByteOrWordLiteral(val intvalue: Int, val datatype: DataType) {
fun asWord() = ByteOrWordLiteral(intvalue, DataType.WORD)
fun asByte() = ByteOrWordLiteral(intvalue, DataType.BYTE)
}
data class LiteralValue(val bytevalue: Short? = null,
val wordvalue: Int? = null,
val floatvalue: Double? = null,
val strvalue: String? = null,
val arrayvalue: MutableList<IExpression>? = null) : IExpression {
@ -674,21 +681,52 @@ data class LiteralValue(val intvalue: Int? = null,
override lateinit var parent: Node
override fun referencesIdentifier(name: String) = arrayvalue?.any { it.referencesIdentifier(name) } ?: false
val isInteger = intvalue!=null
companion object {
fun optimalNumeric(value: Number): LiteralValue {
val floatval = value.toDouble()
return if(floatval == floor(floatval) && floatval in -32768..65535) {
// the floating point value is actually an integer.
when (floatval) {
// note: we cheat a little here and allow negative integers during expression evaluations
in -128..255 -> LiteralValue(bytevalue = floatval.toShort())
in -32768..65535 -> LiteralValue(wordvalue = floatval.toInt())
else -> throw FatalAstException("integer overflow: $floatval")
}
} else {
LiteralValue(floatvalue = floatval)
}
}
}
val isByte = bytevalue!=null
val isWord = wordvalue!=null
val isInteger = isByte or isWord
val isFloat = floatvalue!=null
val isNumeric = intvalue!=null || floatvalue!=null
val isArray = arrayvalue!=null
val isArray = arrayvalue!=null // @todo: array / word-array / matrix ?
val isString = strvalue!=null
init {
if(bytevalue==null && wordvalue==null && floatvalue==null && arrayvalue==null && strvalue==null)
throw FatalAstException("literal value without actual value")
}
val asNumericValue: Number? = when {
intvalue!=null -> intvalue
bytevalue!=null -> bytevalue
wordvalue!=null -> wordvalue
floatvalue!=null -> floatvalue
else -> null
}
val asIntegerValue: Int? = when {
bytevalue!=null -> bytevalue.toInt()
wordvalue!=null -> wordvalue
else -> null
}
val asBooleanValue: Boolean =
(floatvalue!=null && floatvalue != 0.0) ||
(intvalue!=null && intvalue != 0) ||
(bytevalue!=null && bytevalue != 0.toShort()) ||
(wordvalue!=null && wordvalue != 0) ||
(strvalue!=null && strvalue.isNotEmpty()) ||
(arrayvalue != null && arrayvalue.isNotEmpty())
@ -701,7 +739,7 @@ data class LiteralValue(val intvalue: Int? = null,
override fun process(processor: IAstProcessor) = processor.process(this)
override fun toString(): String {
return "LiteralValue(int=$intvalue, float=$floatvalue, str=$strvalue, array=$arrayvalue pos=$position)"
return "LiteralValue(byte=$bytevalue, word=$wordvalue, float=$floatvalue, str=$strvalue, array=$arrayvalue pos=$position)"
}
}
@ -816,7 +854,7 @@ class FunctionCall(override var target: IdentifierReference, override var arglis
}
override fun constValue(namespace: INameScope): LiteralValue? {
// if the function is a built-in function bitand the args are consts, should try to const-evaluate!
// if the function is a built-in function and the args are consts, should try to const-evaluate!
if(target.nameInSource.size>1) return null
try {
return when (target.nameInSource[0]) {
@ -988,7 +1026,7 @@ class BranchStatement(var condition: BranchCondition,
/***************** Antlr Extension methods to create AST ****************/
fun il65Parser.ModuleContext.toAst(name: String, withPosition: Boolean) : Module {
val module = Module(name, modulestatement().map { it.toAst(withPosition) }.toMutableList())
val module = Module(name, modulestatement().asSequence().map { it.toAst(withPosition) }.toMutableList())
module.position = toPosition(withPosition)
return module
}
@ -1019,7 +1057,7 @@ private fun il65Parser.ModulestatementContext.toAst(withPosition: Boolean) : ISt
private fun il65Parser.BlockContext.toAst(withPosition: Boolean) : IStatement {
val block= Block(identifier().text,
integerliteral()?.toAst(),
integerliteral()?.toAst()?.intvalue,
statement_block().toAst(withPosition))
block.position = toPosition(withPosition)
return block
@ -1027,7 +1065,7 @@ private fun il65Parser.BlockContext.toAst(withPosition: Boolean) : IStatement {
private fun il65Parser.Statement_blockContext.toAst(withPosition: Boolean): MutableList<IStatement>
= statement().map { it.toAst(withPosition) }.toMutableList()
= statement().asSequence().map { it.toAst(withPosition) }.toMutableList()
private fun il65Parser.StatementContext.toAst(withPosition: Boolean) : IStatement {
@ -1164,7 +1202,7 @@ private fun il65Parser.ReturnstmtContext.toAst(withPosition: Boolean) : IStateme
private fun il65Parser.UnconditionaljumpContext.toAst(withPosition: Boolean): IStatement {
val address = integerliteral()?.toAst()
val address = integerliteral()?.toAst()?.intvalue
val identifier =
if(identifier()!=null) identifier()?.toAst(withPosition)
else scoped_identifier()?.toAst(withPosition)
@ -1186,7 +1224,7 @@ private fun il65Parser.SubroutineContext.toAst(withPosition: Boolean) : Subrouti
val sub = Subroutine(identifier().text,
if(sub_params()==null) emptyList() else sub_params().toAst(),
if(sub_returns()==null) emptyList() else sub_returns().toAst(),
sub_address()?.integerliteral()?.toAst(),
sub_address()?.integerliteral()?.toAst()?.intvalue,
if(statement_block()==null) mutableListOf() else statement_block().toAst(withPosition))
sub.position = toPosition(withPosition)
return sub
@ -1244,18 +1282,39 @@ private fun il65Parser.DirectiveContext.toAst(withPosition: Boolean) : Directive
private fun il65Parser.DirectiveargContext.toAst(withPosition: Boolean) : DirectiveArg {
val darg = DirectiveArg(stringliteral()?.text,
identifier()?.text,
integerliteral()?.toAst())
integerliteral()?.toAst()?.intvalue)
darg.position = toPosition(withPosition)
return darg
}
private fun il65Parser.IntegerliteralContext.toAst(): Int {
private fun il65Parser.IntegerliteralContext.toAst(): ByteOrWordLiteral {
fun makeLiteral(text: String, radix: Int, forceWord: Boolean): ByteOrWordLiteral {
val integer: Int
var datatype = DataType.BYTE
if(radix==10) {
integer = text.toInt()
if(integer in 256..65535)
datatype = DataType.WORD
} else if(radix==2) {
if(text.length>8)
datatype = DataType.WORD
integer = text.toInt(2)
} else if(radix==16) {
if(text.length>2)
datatype = DataType.WORD
integer = text.toInt(16)
} else {
throw FatalAstException("invalid radix")
}
return ByteOrWordLiteral(integer, if(forceWord) DataType.WORD else datatype)
}
val terminal: TerminalNode = children[0] as TerminalNode
val integerPart = this.intpart.text
return when (terminal.symbol.type) {
il65Parser.DEC_INTEGER -> text.toInt()
il65Parser.HEX_INTEGER -> text.substring(1).toInt(16)
il65Parser.BIN_INTEGER -> text.substring(1).toInt(2)
il65Parser.DEC_INTEGER -> makeLiteral(integerPart, 10, wordsuffix()!=null)
il65Parser.HEX_INTEGER -> makeLiteral(integerPart.substring(1), 16, wordsuffix()!=null)
il65Parser.BIN_INTEGER -> makeLiteral(integerPart.substring(1), 2, wordsuffix()!=null)
else -> throw FatalAstException(terminal.text)
}
}
@ -1268,12 +1327,22 @@ private fun il65Parser.ExpressionContext.toAst(withPosition: Boolean) : IExpress
val booleanlit = litval.booleanliteral()?.toAst()
val value =
if(booleanlit!=null)
LiteralValue(intvalue = if(booleanlit) 1 else 0)
else
LiteralValue(litval.integerliteral()?.toAst(),
litval.floatliteral()?.toAst(),
litval.stringliteral()?.text,
litval.arrayliteral()?.toAst(withPosition))
LiteralValue(bytevalue = if(booleanlit) 1 else 0)
else {
val intLit = litval.integerliteral()?.toAst()
if(intLit!=null) {
when(intLit.datatype) {
DataType.BYTE -> LiteralValue(bytevalue = intLit.intvalue.toShort())
DataType.WORD -> LiteralValue(wordvalue = intLit.intvalue)
else -> throw FatalAstException("invalid datatype for integer literal")
}
} else {
LiteralValue(null, null,
litval.floatliteral()?.toAst(),
litval.stringliteral()?.text,
litval.arrayliteral()?.toAst(withPosition))
}
}
value.position = litval.toPosition(withPosition)
return value
}
@ -1349,7 +1418,7 @@ private fun il65Parser.BooleanliteralContext.toAst() = when(text) {
private fun il65Parser.ArrayliteralContext.toAst(withPosition: Boolean) =
expression().map { it.toAst(withPosition) }.toMutableList()
expression().asSequence().map { it.toAst(withPosition) }.toMutableList()
private fun il65Parser.If_stmtContext.toAst(withPosition: Boolean): IfStatement {

View File

@ -34,7 +34,7 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
override fun process(module: Module) {
super.process(module)
val directives = module.statements.filter { it is Directive }.groupBy { (it as Directive).directive }
val directives = module.statements.asSequence().filter { it is Directive }.groupBy { (it as Directive).directive }
directives.filter { it.value.size > 1 }.forEach{ entry ->
when(entry.key) {
"%output", "%launcher", "%zeropage", "%address" ->
@ -88,31 +88,32 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
if(BuiltinFunctionNames.contains(subroutine.name))
err("cannot redefine a built-in function")
val uniqueNames = subroutine.parameters.map { it.name }.toSet()
val uniqueNames = subroutine.parameters.asSequence().map { it.name }.toSet()
if(uniqueNames.size!=subroutine.parameters.size)
err("parameter names should be unique")
val uniqueParamRegs = subroutine.parameters.map {it.register}.toSet()
val uniqueParamRegs = subroutine.parameters.asSequence().map {it.register}.toSet()
if(uniqueParamRegs.size!=subroutine.parameters.size)
err("parameter registers should be unique")
val uniqueResultRegisters = subroutine.returnvalues.filter{it.register!=null}.map {it.register.toString()}.toMutableSet()
uniqueResultRegisters.addAll(subroutine.returnvalues.filter{it.statusflag!=null}.map{it.statusflag.toString()})
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 should be unique")
super.process(subroutine)
checkSubroutinesPrecededByReturnOrJump(subroutine.statements)
// subroutine must contain at least one 'return' bitor 'goto'
// (bitor if it has an asm block, that must contain a 'rts' bitor 'jmp')
// subroutine must contain at least one 'return' or 'goto'
// (or if it has an asm block, that must contain a 'rts' or 'jmp')
if(subroutine.statements.count { it is Return || it is Jump } == 0) {
if(subroutine.address==null) {
val amount = subroutine.statements
.asSequence()
.filter { it is InlineAssembly }
.map {(it as InlineAssembly).assembly}
.count { it.contains(" rts") || it.contains("\trts") ||
it.contains(" jmp") || it.contains("\tjmp")}
if(amount==0 )
err("subroutine must have at least one 'return' bitor 'goto' in it (bitor 'rts' / 'jmp' in case of %asm)")
err("subroutine must have at least one 'return' or 'goto' in it (or 'rts' / 'jmp' in case of %asm)")
}
}
@ -128,7 +129,7 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
&& preceding !is Subroutine
&& preceding !is VarDecl
&& preceding !is BuiltinFunctionStatementPlaceholder) {
checkResult.add(SyntaxError("subroutine definition should be preceded by a return, jump, vardecl, bitor another subroutine statement", stmt.position))
checkResult.add(SyntaxError("subroutine definition should be preceded by a return, jump, vardecl, or another subroutine statement", stmt.position))
}
}
preceding = stmt
@ -136,7 +137,7 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
}
/**
* Assignment target must be register, bitor a variable name
* Assignment target must be register, or a variable name
* for constant-value assignments, check the datatype as well
*/
override fun process(assignment: Assignment): IStatement {
@ -149,7 +150,7 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
return super.process(assignment)
}
targetSymbol !is VarDecl -> {
checkResult.add(SyntaxError("assignment LHS must be register bitor variable", assignment.position))
checkResult.add(SyntaxError("assignment LHS must be register or variable", assignment.position))
return super.process(assignment)
}
targetSymbol.type == VarDeclType.CONST -> {
@ -204,7 +205,7 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
err("value of memory var decl is not a literal (it is a ${decl.value!!::class.simpleName}).", decl.value?.position)
} else {
val value = decl.value as LiteralValue
if (value.intvalue == null || value.intvalue < 0 || value.intvalue > 65535) {
if (value.asIntegerValue == null || value.asIntegerValue< 0 || value.asIntegerValue > 65535) {
err("memory address must be valid integer 0..\$ffff")
}
}
@ -238,12 +239,12 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
"%output" -> {
if(directive.parent !is Module) err("this directive may only occur at module level")
if(directive.args.size!=1 || directive.args[0].name != "raw" && directive.args[0].name != "prg")
err("invalid output directive type, expected raw bitor prg")
err("invalid output directive type, expected raw or prg")
}
"%launcher" -> {
if(directive.parent !is Module) err("this directive may only occur at module level")
if(directive.args.size!=1 || directive.args[0].name != "basic" && directive.args[0].name != "none")
err("invalid launcher directive type, expected basic bitor none")
err("invalid launcher directive type, expected basic or none")
}
"%zeropage" -> {
if(directive.parent !is Module) err("this directive may only occur at module level")
@ -251,7 +252,7 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
directive.args[0].name != "basicsafe" &&
directive.args[0].name != "kernalsafe" &&
directive.args[0].name != "full")
err("invalid zp directive style, expected basicsafe, kernalsafe, bitor full")
err("invalid zp directive style, expected basicsafe, kernalsafe, or full")
}
"%address" -> {
if(directive.parent !is Module) err("this directive may only occur at module level")
@ -298,6 +299,11 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
if(!compilerOptions.floats && literalValue.isFloat) {
checkResult.add(SyntaxError("floating point value used, but floating point is not enabled via options", literalValue.position))
}
when {
literalValue.isByte -> checkValueTypeAndRange(DataType.BYTE, null, literalValue, literalValue.position)
literalValue.isWord -> checkValueTypeAndRange(DataType.WORD, null, literalValue, literalValue.position)
literalValue.isFloat -> checkValueTypeAndRange(DataType.FLOAT, null, literalValue, literalValue.position)
}
return super.process(literalValue)
}
@ -310,17 +316,17 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
val to = range.to.constValue(namespace)
if(from!=null && to != null) {
when {
from.intvalue!=null && to.intvalue!=null -> {
if(from.intvalue > to.intvalue)
from.asIntegerValue!=null && to.asIntegerValue!=null -> {
if(from.asIntegerValue > to.asIntegerValue)
err("range from is larger than to value")
}
from.strvalue!=null && to.strvalue!=null -> {
if(from.strvalue.length!=1 || to.strvalue.length!=1)
err("range from bitand to must be a single character")
err("range from and to must be a single character")
if(from.strvalue[0] > to.strvalue[0])
err("range from is larger than to value")
}
else -> err("range expression must be over integers bitor over characters")
else -> err("range expression must be over integers or over characters")
}
}
return range
@ -352,9 +358,9 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
checkResult.add(SyntaxError("undefined symbol: ${targetName.joinToString(".")}", postIncrDecr.position))
} else {
if(target !is VarDecl || target.type==VarDeclType.CONST) {
checkResult.add(SyntaxError("can only increment bitor decrement a variable", postIncrDecr.position))
checkResult.add(SyntaxError("can only increment or decrement a variable", postIncrDecr.position))
} else if(target.datatype!=DataType.FLOAT && target.datatype!=DataType.WORD && target.datatype!=DataType.BYTE) {
checkResult.add(SyntaxError("can only increment bitor decrement a byte/float/word variable", postIncrDecr.position))
checkResult.add(SyntaxError("can only increment or decrement a byte/float/word variable", postIncrDecr.position))
}
}
}
@ -365,7 +371,7 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
val targetStatement = target.targetStatement(namespace)
if(targetStatement is Label || targetStatement is Subroutine || targetStatement is BuiltinFunctionStatementPlaceholder)
return targetStatement
checkResult.add(SyntaxError("undefined function bitor subroutine: ${target.nameInSource.joinToString(".")}", statement.position))
checkResult.add(SyntaxError("undefined function or subroutine: ${target.nameInSource.joinToString(".")}", statement.position))
return null
}
@ -373,13 +379,13 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
if(call.target.nameInSource.size==1 && BuiltinFunctionNames.contains(call.target.nameInSource[0])) {
val functionName = call.target.nameInSource[0]
if(functionName=="P_carry" || functionName=="P_irqd") {
// these functions allow only 0 bitor 1 as argument
// these functions allow only 0 or 1 as argument
if(call.arglist.size!=1 || call.arglist[0] !is LiteralValue) {
checkResult.add(SyntaxError("$functionName requires one argument, 0 bitor 1", position))
checkResult.add(SyntaxError("$functionName requires one argument, 0 or 1", position))
} else {
val value = call.arglist[0] as LiteralValue
if(value.intvalue==null || value.intvalue < 0 || value.intvalue > 1) {
checkResult.add(SyntaxError("$functionName requires one argument, 0 bitor 1", position))
if(value.asIntegerValue==null || value.asIntegerValue < 0 || value.asIntegerValue > 1) {
checkResult.add(SyntaxError("$functionName requires one argument, 0 or 1", position))
}
}
}
@ -399,14 +405,18 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
return err("floating point value '$number' out of range for MFLPT format")
}
DataType.BYTE -> {
val number = value.intvalue
?: return err("byte integer value expected")
val number = value.asIntegerValue ?: return if (value.floatvalue!=null)
err("unsigned byte integer value expected instead of float; possible loss of precision")
else
err("unsigned byte integer value expected")
if (number < 0 || number > 255)
return err("value '$number' out of range for unsigned byte")
}
DataType.WORD -> {
val number = value.intvalue
?: return err("word integer value expected")
val number = value.asIntegerValue ?: return if (value.floatvalue!=null)
err("unsigned word integer value expected instead of float; possible loss of precision")
else
err("unsigned word integer value expected")
if (number < 0 || number > 65535)
return err("value '$number' out of range for unsigned word")
}
@ -417,13 +427,13 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
return err("string length must be 1..65535")
}
DataType.ARRAY -> {
// value may be either a single byte, bitor a byte array
// value may be either a single byte, or a byte array
if(value.isArray) {
for (av in value.arrayvalue!!) {
val number = (av as LiteralValue).intvalue
val number = (av as LiteralValue).bytevalue
?: return err("array must be all bytes")
val expectedSize = arrayspec?.x?.constValue(namespace)?.intvalue
val expectedSize = arrayspec?.x?.constValue(namespace)?.asIntegerValue
if (value.arrayvalue.size != expectedSize)
return err("initializer array size mismatch (expecting $expectedSize, got ${value.arrayvalue.size})")
@ -431,20 +441,22 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
return err("value '$number' in byte array is out of range for unsigned byte")
}
} else {
val number = value.intvalue
?: return err("byte integer value expected")
val number = value.bytevalue ?: return if (value.floatvalue!=null)
err("unsigned byte integer value expected instead of float; possible loss of precision")
else
err("unsigned byte integer value expected")
if (number < 0 || number > 255)
return err("value '$number' out of range for unsigned byte")
}
}
DataType.ARRAY_W -> {
// value may be either a single word, bitor a word array
// value may be either a single word, or a word array
if(value.isArray) {
for (av in value.arrayvalue!!) {
val number = (av as LiteralValue).intvalue
val number = (av as LiteralValue).asIntegerValue // both byte and word are acceptable
?: return err("array must be all words")
val expectedSize = arrayspec!!.x.constValue(namespace)?.intvalue!!
val expectedSize = arrayspec!!.x.constValue(namespace)?.asIntegerValue
if (value.arrayvalue.size != expectedSize)
return err("initializer array size mismatch (expecting $expectedSize, got ${value.arrayvalue.size})")
@ -452,21 +464,24 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
return err("value '$number' in word array is out of range for unsigned word")
}
} else {
val number = value.intvalue
?: return err("word integer value expected")
val number = value.asIntegerValue // both byte and word are acceptable
?: return if (value.floatvalue!=null)
err("unsigned word integer value expected instead of float; possible loss of precision")
else
err("unsigned word integer value expected")
if (number < 0 || number > 65535)
return err("value '$number' out of range for unsigned word")
}
}
DataType.MATRIX -> {
// value can only be a single byte, bitor a byte array (which represents the matrix)
// value can only be a single byte, or a byte array (which represents the matrix)
if(value.isArray) {
for (av in value.arrayvalue!!) {
val number = (av as LiteralValue).intvalue
val number = (av as LiteralValue).bytevalue
?: return err("array must be all bytes")
val expectedSizeX = arrayspec!!.x.constValue(namespace)?.intvalue!!
val expectedSizeY = arrayspec.y!!.constValue(namespace)?.intvalue!!
val expectedSizeX = arrayspec!!.x.constValue(namespace)?.asIntegerValue!!
val expectedSizeY = arrayspec.y!!.constValue(namespace)?.asIntegerValue!!
val expectedSize = expectedSizeX * expectedSizeY
if (value.arrayvalue.size != expectedSize)
return err("initializer array size mismatch (expecting $expectedSize, got ${value.arrayvalue.size})")
@ -475,8 +490,8 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
return err("value '$number' in byte array is out of range for unsigned byte")
}
} else {
val number = value.intvalue
?: return err("byte integer value expected")
val number = value.bytevalue
?: return err("unsigned byte integer value expected")
if (number < 0 || number > 255)
return err("value '$number' out of range for unsigned byte")
}

View File

@ -66,7 +66,7 @@ class DirectedGraph<VT> {
if(recStack[node]==true) return true
if(visited[node]==true) return false
// mark current node as visited bitand add to recursion stack
// mark current node as visited and add to recursion stack
visited[node] = true
recStack[node] = true

View File

@ -4,7 +4,7 @@ class StatementReorderer: IAstProcessor {
// Reorders the statements in a way the compiler needs.
// - 'main' block must be the very first statement.
// - in every scope:
// -- the directives '%output', '%launcher', '%zeropage', '%address' bitand '%option' will come first.
// -- the directives '%output', '%launcher', '%zeropage', '%address' and '%option' will come first.
// -- all vardecls then follow.
// -- the remaining statements then follow in their original order.
// - the 'start' subroutine in the 'main' block will be moved to the top immediately following the directives.

View File

@ -34,8 +34,8 @@ data class Mflpt5(val b0: Short, val b1: Short, val b2: Short, val b3: Short, va
val zero = Mflpt5(0, 0,0,0,0)
fun fromNumber(num: Number): Mflpt5 {
// see https://en.wikipedia.org/wiki/Microsoft_Binary_Format
// bitand https://sourceforge.net/p/acme-crossass/code-0/62/tree/trunk/ACME_Lib/cbm/mflpt.a
// bitand https://en.wikipedia.org/wiki/IEEE_754-1985
// and https://sourceforge.net/p/acme-crossass/code-0/62/tree/trunk/ACME_Lib/cbm/mflpt.a
// and https://en.wikipedia.org/wiki/IEEE_754-1985
val flt = num.toDouble()
if(flt < FLOAT_MAX_NEGATIVE || flt > FLOAT_MAX_POSITIVE)
@ -47,12 +47,12 @@ data class Mflpt5(val b0: Short, val b1: Short, val b2: Short, val b3: Short, va
var exponent = 128 + 32 // 128 is cbm's bias, 32 is this algo's bias
var mantissa = flt.absoluteValue
// if mantissa is too large, shift right bitand adjust exponent
// if mantissa is too large, shift right and adjust exponent
while(mantissa >= 0x100000000) {
mantissa /= 2.0
exponent ++
}
// if mantissa is too small, shift left bitand adjust exponent
// if mantissa is too small, shift left and adjust exponent
while(mantissa < 0x80000000) {
mantissa *= 2.0
exponent --
@ -95,10 +95,10 @@ class Compiler(private val options: CompilationOptions) {
val intermediate = StackVmProgram(module.name)
namespace.debugPrint()
// create the pool of all variables used in all blocks bitand scopes
// create the pool of all variables used in all blocks and scopes
val varGather = VarGatherer(intermediate)
varGather.process(module)
println("Number of allocated variables bitand constants: ${intermediate.variables.size} (${intermediate.variablesMemSize} bytes)")
println("Number of allocated variables and constants: ${intermediate.variables.size} (${intermediate.variablesMemSize} bytes)")
val translator = StatementTranslator(intermediate, namespace)
translator.process(module)
@ -271,14 +271,9 @@ class Compiler(private val options: CompilationOptions) {
val lv = expr.constValue(namespace) ?: throw CompilerException("constant expression required, not $expr")
when {
lv.isString -> stackvmProg.instruction("push \"${lv.strvalue}\"")
lv.isInteger -> {
val intval = lv.intvalue!!
if(intval<=255)
stackvmProg.instruction("push b:${intval.toString(16)}")
else if(intval <= 65535)
stackvmProg.instruction("push w:${intval.toString(16)}")
}
lv.isNumeric -> stackvmProg.instruction("push f:${lv.asNumericValue}")
lv.isByte -> stackvmProg.instruction("push b:${lv.bytevalue!!.toString(16)}")
lv.isWord -> stackvmProg.instruction("push w:${lv.wordvalue!!.toString(16)}")
lv.isFloat -> stackvmProg.instruction("push f:${lv.floatvalue}")
lv.isArray -> {
lv.arrayvalue?.forEach { translate(it) }
stackvmProg.instruction("array w:${lv.arrayvalue!!.size.toString(16)}")
@ -299,9 +294,9 @@ class Compiler(private val options: CompilationOptions) {
"&" -> "bitand"
"|" -> "bitor"
"^" -> "bitxor"
"bitand" -> "bitand"
"bitor" -> "bitor"
"bitxor" -> "bitxor"
"and" -> "and"
"or" -> "or"
"xor" -> "xor"
"<" -> "less"
">" -> "greater"
"<=" -> "lesseq"
@ -450,11 +445,12 @@ class StackVmProgram(val name: String) {
result.add("%variables")
for(v in variables) {
if (!(v.value.type == VarDeclType.VAR || v.value.type == VarDeclType.CONST)) {
throw AssertionError("Should be only VAR bitor CONST variables")
throw AssertionError("Should be only VAR or CONST variables")
}
val litval = v.value.value as LiteralValue
val litvalStr = when {
litval.isInteger -> litval.intvalue!!.toString(16)
litval.isByte -> litval.bytevalue!!.toString(16)
litval.isWord -> litval.wordvalue!!.toString(16)
litval.isFloat -> litval.floatvalue.toString()
litval.isString -> "\"${litval.strvalue}\""
else -> TODO("non-scalar value")

View File

@ -56,19 +56,19 @@ class Zeropage(private val options: CompilationOptions) {
if(vardecl.position!=null)
print(vardecl.position)
println(" warning: allocating a large value (array) in zeropage")
val y = (vardecl.arrayspec.y as? LiteralValue)?.intvalue
val y = (vardecl.arrayspec.y as? LiteralValue)?.asIntegerValue
if(y==null) {
// 1 dimensional array
when(vardecl.datatype) {
DataType.BYTE -> (vardecl.arrayspec.x as LiteralValue).intvalue!!
DataType.WORD -> (vardecl.arrayspec.x as LiteralValue).intvalue!! * 2
DataType.FLOAT -> (vardecl.arrayspec.x as LiteralValue).intvalue!! * 5
DataType.BYTE -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!!
DataType.WORD -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!! * 2
DataType.FLOAT -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!! * 5
else -> throw CompilerException("array can only be of byte, word, float")
}
} else {
// 2 dimensional matrix (only bytes for now)
when(vardecl.datatype) {
DataType.BYTE -> (vardecl.arrayspec.x as LiteralValue).intvalue!! * y
DataType.BYTE -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!! * y
else -> throw CompilerException("matrix can only contain bytes")
}
}

View File

@ -23,9 +23,7 @@ private fun oneDoubleArg(args: List<IExpression>, position: Position?, namespace
throw SyntaxError("built-in function requires one floating point argument", position)
val float = constval.asNumericValue?.toDouble()!!
val result = numericLiteral(function(float), args[0].position)
result.position = args[0].position
return result
return numericLiteral(function(float), args[0].position)
}
private fun oneDoubleArgOutputInt(args: List<IExpression>, position: Position?, namespace:INameScope, function: (arg: Double)->Number): LiteralValue {
@ -36,9 +34,7 @@ private fun oneDoubleArgOutputInt(args: List<IExpression>, position: Position?,
throw SyntaxError("built-in function requires one floating point argument", position)
val float = constval.asNumericValue?.toDouble()!!
val result = LiteralValue(function(float).toInt())
result.position = args[0].position
return result
return numericLiteral(function(float).toInt(), args[0].position)
}
private fun oneIntArgOutputInt(args: List<IExpression>, position: Position?, namespace:INameScope, function: (arg: Int)->Number): LiteralValue {
@ -49,9 +45,7 @@ private fun oneIntArgOutputInt(args: List<IExpression>, position: Position?, nam
throw SyntaxError("built-in function requires one integer argument", position)
val integer = constval.asNumericValue?.toInt()!!
val result = LiteralValue(function(integer).toInt())
result.position = args[0].position
return result
return numericLiteral(function(integer).toInt(), args[0].position)
}
private fun collectionArgOutputNumber(args: List<IExpression>, position: Position?, namespace:INameScope,
@ -65,14 +59,7 @@ private fun collectionArgOutputNumber(args: List<IExpression>, position: Positio
if(constants.contains(null))
throw NotConstArgumentException()
val result = function(constants.map { it!!.toDouble() }).toDouble()
val value =
if(result-floor(result) == 0.0) {
LiteralValue(result.toInt())
} else {
LiteralValue(floatvalue = result)
}
value.position = args[0].position
return value
return numericLiteral(result, args[0].position)
}
private fun collectionArgOutputBoolean(args: List<IExpression>, position: Position?, namespace:INameScope,
@ -86,7 +73,7 @@ private fun collectionArgOutputBoolean(args: List<IExpression>, position: Positi
if(constants.contains(null))
throw NotConstArgumentException()
val result = function(constants.map { it?.toDouble()!! })
return LiteralValue(if(result) 1 else 0)
return LiteralValue(bytevalue = if(result) 1 else 0)
}
fun builtinRound(args: List<IExpression>, position: Position?, namespace:INameScope): LiteralValue
@ -132,26 +119,21 @@ fun builtinDeg(args: List<IExpression>, position: Position?, namespace:INameScop
= oneDoubleArg(args, position, namespace, Math::toDegrees)
fun builtinAbs(args: List<IExpression>, position: Position?, namespace:INameScope): LiteralValue {
// 1 arg, type = float bitor int, result type= same as argument type
// 1 arg, type = float or int, result type= same as argument type
if(args.size!=1)
throw SyntaxError("abs requires one numeric argument", position)
val constval = args[0].constValue(namespace) ?: throw NotConstArgumentException()
var number = constval.asNumericValue
val result =
if(number is Int || number is Byte || number is Short) {
number = number.toInt()
LiteralValue(intvalue = abs(number))
} else if(number is Double) {
LiteralValue(floatvalue = abs(number.toDouble()))
} else {
throw SyntaxError("abs requires one numeric argument", position)
}
result.position = args[0].position
return result
val number = constval.asNumericValue
return when (number) {
is Int, is Byte, is Short -> numericLiteral(abs(number.toInt()), args[0].position)
is Double -> numericLiteral(abs(number.toDouble()), args[0].position)
else -> throw SyntaxError("abs requires one numeric argument", position)
}
}
// todo different functions for byte/word params/results?
fun builtinLsb(args: List<IExpression>, position: Position?, namespace:INameScope): LiteralValue
= oneIntArgOutputInt(args, position, namespace) { x: Int -> x and 255 }
@ -183,9 +165,7 @@ fun builtinAvg(args: List<IExpression>, position: Position?, namespace:INameScop
if(constants.contains(null))
throw NotConstArgumentException()
val result = (constants.map { it!!.toDouble() }).average()
val value = LiteralValue(floatvalue = result)
value.position = args[0].position
return value
return numericLiteral(result, args[0].position)
}
fun builtinLen(args: List<IExpression>, position: Position?, namespace:INameScope): LiteralValue {
@ -198,9 +178,7 @@ fun builtinLen(args: List<IExpression>, position: Position?, namespace:INameScop
if(constants.contains(null))
throw NotConstArgumentException()
val result = (constants.map { it!!.toDouble() }).size
val value = LiteralValue(intvalue = result)
value.position = args[0].position
return value
return numericLiteral(result, args[0].position)
}
fun builtinAny(args: List<IExpression>, position: Position?, namespace:INameScope): LiteralValue
@ -211,10 +189,17 @@ fun builtinAll(args: List<IExpression>, position: Position?, namespace:INameScop
private fun numericLiteral(value: Number, position: Position?): LiteralValue {
val result = when(value) {
is Int -> LiteralValue(intvalue = value.toInt())
is Short -> LiteralValue(intvalue = value.toInt())
is Byte -> LiteralValue(intvalue = value.toInt())
val floatNum=value.toDouble()
val tweakedValue: Number =
if(floatNum==floor(floatNum) && floatNum in -32768..65535)
floatNum.toInt() // we have an integer disguised as a float.
else
floatNum
val result = when(tweakedValue) {
is Int -> LiteralValue.optimalNumeric(value.toInt())
is Short -> LiteralValue.optimalNumeric(value.toInt())
is Byte -> LiteralValue(bytevalue = value.toShort())
is Double -> LiteralValue(floatvalue = value.toDouble())
is Float -> LiteralValue(floatvalue = value.toDouble())
else -> throw FatalAstException("invalid number type ${value::class}")

View File

@ -47,7 +47,7 @@ fun Module.optimizeExpressions(globalNamespace: INameScope) {
X ^ 0 -> X
todo expression optimization: reduce expression nesting / flattening of parenthesis
todo expression optimization: simplify logical expression when a term makes it always true bitor false (1 bitor 0)
todo expression optimization: simplify logical expression when a term makes it always true or false (1 or 0)
todo expression optimization: optimize some simple multiplications into shifts (A*8 -> A<<3, A/4 -> A>>2)
todo expression optimization: common (sub) expression elimination (turn common expressions into single subroutine call)
@ -83,7 +83,7 @@ class ExpressionOptimizer(private val globalNamespace: INameScope) : IAstProcess
// vardecl: for float vars, promote constant integer initialization values to floats
val literal = decl.value as? LiteralValue
if (literal != null && literal.isInteger) {
val newValue = LiteralValue(floatvalue = literal.intvalue!!.toDouble())
val newValue = LiteralValue(floatvalue = literal.asNumericValue!!.toDouble())
newValue.position = literal.position
decl.value = newValue
}
@ -93,7 +93,7 @@ class ExpressionOptimizer(private val globalNamespace: INameScope) : IAstProcess
val literal = decl.value as? LiteralValue
if (literal != null && literal.isString && literal.strvalue?.length == 1) {
val petscii = Petscii.encodePetscii(literal.strvalue)[0]
val newValue = LiteralValue(petscii.toInt())
val newValue = LiteralValue(bytevalue = petscii)
newValue.position = literal.position
decl.value = newValue
}
@ -140,31 +140,31 @@ class ExpressionOptimizer(private val globalNamespace: INameScope) : IAstProcess
val result = when {
expr.operator == "+" -> subexpr
expr.operator == "-" -> when {
subexpr.intvalue != null -> {
subexpr.asIntegerValue!= null -> {
optimizationsDone++
LiteralValue(intvalue = -subexpr.intvalue)
LiteralValue.optimalNumeric(-subexpr.asIntegerValue)
}
subexpr.floatvalue != null -> {
optimizationsDone++
LiteralValue(floatvalue = -subexpr.floatvalue)
}
else -> throw ExpressionError("can only take negative of int bitor float", subexpr.position)
else -> throw ExpressionError("can only take negative of int or float", subexpr.position)
}
expr.operator == "~" -> when {
subexpr.intvalue != null -> {
subexpr.asIntegerValue != null -> {
optimizationsDone++
LiteralValue(intvalue = subexpr.intvalue.inv())
LiteralValue.optimalNumeric(subexpr.asIntegerValue.inv())
}
else -> throw ExpressionError("can only take bitwise inversion of int", subexpr.position)
}
expr.operator == "not" -> when {
subexpr.intvalue != null -> {
subexpr.asIntegerValue != null -> {
optimizationsDone++
LiteralValue(intvalue = if (subexpr.intvalue == 0) 1 else 0)
LiteralValue(bytevalue = if (subexpr.asIntegerValue == 0) 1 else 0)
}
subexpr.floatvalue != null -> {
optimizationsDone++
LiteralValue(intvalue = if (subexpr.floatvalue == 0.0) 1 else 0)
LiteralValue(bytevalue = if (subexpr.floatvalue == 0.0) 1 else 0)
}
else -> throw ExpressionError("can not take logical not of $subexpr", subexpr.position)
}
@ -212,14 +212,27 @@ class ExpressionOptimizer(private val globalNamespace: INameScope) : IAstProcess
val to = range.to.constValue(globalNamespace)
if (from != null && to != null) {
when {
from.intvalue != null && to.intvalue != null -> {
// int range
val rangevalue = from.intvalue.rangeTo(to.intvalue)
if (rangevalue.last - rangevalue.first > 65535) {
from.isWord || to.isWord -> {
// range on word value boundaries
val rangeValue = from.asIntegerValue!!.rangeTo(to.asIntegerValue!!)
if (rangeValue.last - rangeValue.first > 65535) {
throw ExpressionError("amount of values in range exceeds 65535", range.position)
}
return LiteralValue(arrayvalue = rangevalue.map {
val v = LiteralValue(intvalue = it)
return LiteralValue(arrayvalue = rangeValue.map {
val v = LiteralValue(wordvalue = it)
v.position = range.position
v.parent = range.parent
v
}.toMutableList())
}
from.isByte && to.isByte -> {
// range on byte value boundaries
val rangeValue = from.bytevalue!!.rangeTo(to.bytevalue!!)
if (rangeValue.last - rangeValue.first > 65535) {
throw ExpressionError("amount of values in range exceeds 65535", range.position)
}
return LiteralValue(arrayvalue = rangeValue.map {
val v = LiteralValue(bytevalue = it.toShort())
v.position = range.position
v.parent = range.parent
v
@ -236,6 +249,7 @@ class ExpressionOptimizer(private val globalNamespace: INameScope) : IAstProcess
newval.parent = range.parent
return newval
}
else -> AstException("range on weird datatype")
}
}
return range
@ -268,9 +282,9 @@ class ConstExprEvaluator {
"&" -> bitwiseand(left, right)
"|" -> bitwiseor(left, right)
"^" -> bitwisexor(left, right)
"bitand" -> logicaland(left, right)
"bitor" -> logicalor(left, right)
"bitxor" -> logicalxor(left, right)
"and" -> logicaland(left, right)
"or" -> logicalor(left, right)
"xor" -> logicalxor(left, right)
"<" -> compareless(left, right)
">" -> comparegreater(left, right)
"<=" -> comparelessequal(left, right)
@ -283,27 +297,29 @@ class ConstExprEvaluator {
private fun comparenotequal(left: LiteralValue, right: LiteralValue): LiteralValue {
val leq = compareequal(left, right)
val litval = LiteralValue(intvalue = if (leq.intvalue == 1) 0 else 1)
val litval = LiteralValue(bytevalue = if (leq.bytevalue == 1.toShort()) 0 else 1)
litval.position = left.position
return litval
}
private fun compareequal(left: LiteralValue, right: LiteralValue): LiteralValue {
val leftvalue: Any = when {
left.intvalue!=null -> left.intvalue
left.bytevalue!=null -> left.bytevalue
left.wordvalue!=null -> left.wordvalue
left.floatvalue!=null -> left.floatvalue
left.strvalue!=null -> left.strvalue
left.arrayvalue!=null -> left.arrayvalue
else -> throw FatalAstException("missing literal value")
}
val rightvalue: Any = when {
right.intvalue!=null -> right.intvalue
right.bytevalue!=null -> right.bytevalue
right.wordvalue!=null -> right.wordvalue
right.floatvalue!=null -> right.floatvalue
right.strvalue!=null -> right.strvalue
right.arrayvalue!=null -> right.arrayvalue
else -> throw FatalAstException("missing literal value")
}
val litval = LiteralValue(intvalue = if (leftvalue == rightvalue) 1 else 0)
val litval = LiteralValue(bytevalue = if (leftvalue == rightvalue) 1 else 0)
litval.position = left.position
return litval
}
@ -311,18 +327,18 @@ class ConstExprEvaluator {
private fun comparegreaterequal(left: LiteralValue, right: LiteralValue): LiteralValue {
val error = "cannot compute $left >= $right"
val litval = when {
left.intvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if (left.intvalue >= right.intvalue) 1 else 0)
left.asIntegerValue!=null -> when {
right.asIntegerValue!=null -> LiteralValue(
bytevalue = if (left.asIntegerValue >= right.asIntegerValue) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if (left.intvalue >= right.floatvalue) 1 else 0)
bytevalue = if (left.asIntegerValue >= right.floatvalue) 1 else 0)
else -> throw ExpressionError(error, left.position)
}
left.floatvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if (left.floatvalue >= right.intvalue) 1 else 0)
right.asIntegerValue!=null -> LiteralValue(
bytevalue = if (left.floatvalue >= right.asIntegerValue) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if (left.floatvalue >= right.floatvalue) 1 else 0)
bytevalue = if (left.floatvalue >= right.floatvalue) 1 else 0)
else -> throw ExpressionError(error, left.position)
}
else -> throw ExpressionError(error, left.position)
@ -334,18 +350,18 @@ class ConstExprEvaluator {
private fun comparelessequal(left: LiteralValue, right: LiteralValue): LiteralValue {
val error = "cannot compute $left >= $right"
val litval = when {
left.intvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if (left.intvalue <= right.intvalue) 1 else 0)
left.asIntegerValue!=null -> when {
right.asIntegerValue!=null -> LiteralValue(
bytevalue = if (left.asIntegerValue <= right.asIntegerValue) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if (left.intvalue <= right.floatvalue) 1 else 0)
bytevalue = if (left.asIntegerValue <= right.floatvalue) 1 else 0)
else -> throw ExpressionError(error, left.position)
}
left.floatvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if (left.floatvalue <= right.intvalue) 1 else 0)
right.asIntegerValue!=null -> LiteralValue(
bytevalue = if (left.floatvalue <= right.asIntegerValue) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if (left.floatvalue <= right.floatvalue) 1 else 0)
bytevalue = if (left.floatvalue <= right.floatvalue) 1 else 0)
else -> throw ExpressionError(error, left.position)
}
else -> throw ExpressionError(error, left.position)
@ -356,14 +372,14 @@ class ConstExprEvaluator {
private fun comparegreater(left: LiteralValue, right: LiteralValue): LiteralValue {
val leq = comparelessequal(left, right)
val litval = LiteralValue(intvalue = if (leq.intvalue == 1) 0 else 1)
val litval = LiteralValue(bytevalue = if (leq.bytevalue == 1.toShort()) 0 else 1)
litval.position = left.position
return litval
}
private fun compareless(left: LiteralValue, right: LiteralValue): LiteralValue {
val leq = comparegreaterequal(left, right)
val litval = LiteralValue(intvalue = if (leq.intvalue == 1) 0 else 1)
val litval = LiteralValue(bytevalue = if (leq.bytevalue == 1.toShort()) 0 else 1)
litval.position = left.position
return litval
}
@ -371,18 +387,18 @@ class ConstExprEvaluator {
private fun logicalxor(left: LiteralValue, right: LiteralValue): LiteralValue {
val error = "cannot compute $left locical-bitxor $right"
val litval = when {
left.intvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if ((left.intvalue != 0).xor(right.intvalue != 0)) 1 else 0)
left.asIntegerValue!=null -> when {
right.asIntegerValue!=null -> LiteralValue(
bytevalue = if ((left.asIntegerValue != 0).xor(right.asIntegerValue != 0)) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if ((left.intvalue != 0).xor(right.floatvalue != 0.0)) 1 else 0)
bytevalue = if ((left.asIntegerValue != 0).xor(right.floatvalue != 0.0)) 1 else 0)
else -> throw ExpressionError(error, left.position)
}
left.floatvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if ((left.floatvalue != 0.0).xor(right.intvalue != 0)) 1 else 0)
right.asIntegerValue!=null -> LiteralValue(
bytevalue = if ((left.floatvalue != 0.0).xor(right.asIntegerValue != 0)) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if ((left.floatvalue != 0.0).xor(right.floatvalue != 0.0)) 1 else 0)
bytevalue = if ((left.floatvalue != 0.0).xor(right.floatvalue != 0.0)) 1 else 0)
else -> throw ExpressionError(error, left.position)
}
else -> throw ExpressionError(error, left.position)
@ -392,20 +408,20 @@ class ConstExprEvaluator {
}
private fun logicalor(left: LiteralValue, right: LiteralValue): LiteralValue {
val error = "cannot compute $left locical-bitor $right"
val error = "cannot compute $left locical-or $right"
val litval = when {
left.intvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if (left.intvalue != 0 || right.intvalue != 0) 1 else 0)
left.asIntegerValue!=null -> when {
right.asIntegerValue!=null -> LiteralValue(
bytevalue = if (left.asIntegerValue != 0 || right.asIntegerValue != 0) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if (left.intvalue != 0 || right.floatvalue != 0.0) 1 else 0)
bytevalue = if (left.asIntegerValue != 0 || right.floatvalue != 0.0) 1 else 0)
else -> throw ExpressionError(error, left.position)
}
left.floatvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if (left.floatvalue != 0.0 || right.intvalue != 0) 1 else 0)
right.asIntegerValue!=null -> LiteralValue(
bytevalue = if (left.floatvalue != 0.0 || right.asIntegerValue != 0) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if (left.floatvalue != 0.0 || right.floatvalue != 0.0) 1 else 0)
bytevalue = if (left.floatvalue != 0.0 || right.floatvalue != 0.0) 1 else 0)
else -> throw ExpressionError(error, left.position)
}
else -> throw ExpressionError(error, left.position)
@ -415,20 +431,20 @@ class ConstExprEvaluator {
}
private fun logicaland(left: LiteralValue, right: LiteralValue): LiteralValue {
val error = "cannot compute $left locical-bitand $right"
val error = "cannot compute $left locical-and $right"
val litval = when {
left.intvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if (left.intvalue != 0 && right.intvalue != 0) 1 else 0)
left.asIntegerValue!=null -> when {
right.asIntegerValue!=null -> LiteralValue(
bytevalue = if (left.asIntegerValue != 0 && right.asIntegerValue != 0) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if (left.intvalue != 0 && right.floatvalue != 0.0) 1 else 0)
bytevalue = if (left.asIntegerValue != 0 && right.floatvalue != 0.0) 1 else 0)
else -> throw ExpressionError(error, left.position)
}
left.floatvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if (left.floatvalue != 0.0 && right.intvalue != 0) 1 else 0)
right.asIntegerValue!=null -> LiteralValue(
bytevalue = if (left.floatvalue != 0.0 && right.asIntegerValue != 0) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if (left.floatvalue != 0.0 && right.floatvalue != 0.0) 1 else 0)
bytevalue = if (left.floatvalue != 0.0 && right.floatvalue != 0.0) 1 else 0)
else -> throw ExpressionError(error, left.position)
}
else -> throw ExpressionError(error, left.position)
@ -438,28 +454,52 @@ class ConstExprEvaluator {
}
private fun bitwisexor(left: LiteralValue, right: LiteralValue): LiteralValue {
if(left.intvalue!=null && right.intvalue !=null) {
val litval = LiteralValue(intvalue = left.intvalue.xor(right.intvalue))
litval.position = left.position
return litval
if(left.isByte) {
if(right.asIntegerValue!=null) {
val litval = LiteralValue(bytevalue = (left.bytevalue!!.toInt() xor (right.asIntegerValue and 255)).toShort())
litval.position = left.position
return litval
}
} else if(left.isWord) {
if(right.asIntegerValue!=null) {
val litval = LiteralValue(wordvalue = left.wordvalue!! xor right.asIntegerValue)
litval.position = left.position
return litval
}
}
throw ExpressionError("cannot calculate $left ^ $right", left.position)
}
private fun bitwiseor(left: LiteralValue, right: LiteralValue): LiteralValue {
if(left.intvalue!=null && right.intvalue !=null) {
val litval = LiteralValue(intvalue = left.intvalue.or(right.intvalue))
litval.position = left.position
return litval
if(left.isByte) {
if(right.asIntegerValue!=null) {
val litval = LiteralValue(bytevalue = (left.bytevalue!!.toInt() or (right.asIntegerValue and 255)).toShort())
litval.position = left.position
return litval
}
} else if(left.isWord) {
if(right.asIntegerValue!=null) {
val litval = LiteralValue(wordvalue = left.wordvalue!! or right.asIntegerValue)
litval.position = left.position
return litval
}
}
throw ExpressionError("cannot calculate $left | $right", left.position)
}
private fun bitwiseand(left: LiteralValue, right: LiteralValue): LiteralValue {
if(left.intvalue!=null && right.intvalue !=null) {
val litval = LiteralValue(intvalue = left.intvalue.and(right.intvalue))
litval.position = left.position
return litval
if(left.isByte) {
if(right.asIntegerValue!=null) {
val litval = LiteralValue(bytevalue = (left.bytevalue!!.toInt() or (right.asIntegerValue and 255)).toShort())
litval.position = left.position
return litval
}
} else if(left.isWord) {
if(right.asIntegerValue!=null) {
val litval = LiteralValue(wordvalue = left.wordvalue!! or right.asIntegerValue)
litval.position = left.position
return litval
}
}
throw ExpressionError("cannot calculate $left & $right", left.position)
}
@ -467,13 +507,13 @@ class ConstExprEvaluator {
private fun power(left: LiteralValue, right: LiteralValue): LiteralValue {
val error = "cannot calculate $left ** $right"
val litval = when {
left.intvalue!=null -> when {
right.intvalue!=null -> LiteralValue(intvalue = left.intvalue.toDouble().pow(right.intvalue).toInt())
right.floatvalue!=null -> LiteralValue(floatvalue = left.intvalue.toDouble().pow(right.floatvalue))
left.asIntegerValue!=null -> when {
right.asIntegerValue!=null -> LiteralValue(wordvalue = left.asIntegerValue.toDouble().pow(right.asIntegerValue).toInt())
right.floatvalue!=null -> LiteralValue(floatvalue = left.asIntegerValue.toDouble().pow(right.floatvalue))
else -> throw ExpressionError(error, left.position)
}
left.floatvalue!=null -> when {
right.intvalue!=null -> LiteralValue(floatvalue = left.floatvalue.pow(right.intvalue))
right.asIntegerValue!=null -> LiteralValue(floatvalue = left.floatvalue.pow(right.asIntegerValue))
right.floatvalue!=null -> LiteralValue(floatvalue = left.floatvalue.pow(right.floatvalue))
else -> throw ExpressionError(error, left.position)
}
@ -484,15 +524,15 @@ class ConstExprEvaluator {
}
private fun plus(left: LiteralValue, right: LiteralValue): LiteralValue {
val error = "cannot add $left bitand $right"
val error = "cannot add $left and $right"
val litval = when {
left.intvalue!=null -> when {
right.intvalue!=null -> LiteralValue(intvalue = left.intvalue + right.intvalue)
right.floatvalue!=null -> LiteralValue(floatvalue = left.intvalue + right.floatvalue)
left.asIntegerValue!=null -> when {
right.asIntegerValue!=null -> LiteralValue.optimalNumeric(left.asIntegerValue + right.asIntegerValue)
right.floatvalue!=null -> LiteralValue(floatvalue = left.asIntegerValue + right.floatvalue)
else -> throw ExpressionError(error, left.position)
}
left.floatvalue!=null -> when {
right.intvalue!=null -> LiteralValue(floatvalue = left.floatvalue + right.intvalue)
right.asIntegerValue!=null -> LiteralValue(floatvalue = left.floatvalue + right.asIntegerValue)
right.floatvalue!=null -> LiteralValue(floatvalue = left.floatvalue + right.floatvalue)
else -> throw ExpressionError(error, left.position)
}
@ -503,15 +543,15 @@ class ConstExprEvaluator {
}
private fun minus(left: LiteralValue, right: LiteralValue): LiteralValue {
val error = "cannot subtract $left bitand $right"
val error = "cannot subtract $left and $right"
val litval = when {
left.intvalue!=null -> when {
right.intvalue!=null -> LiteralValue(intvalue = left.intvalue - right.intvalue)
right.floatvalue!=null -> LiteralValue(floatvalue = left.intvalue - right.floatvalue)
left.asIntegerValue!=null -> when {
right.asIntegerValue!=null -> LiteralValue.optimalNumeric(left.asIntegerValue - right.asIntegerValue)
right.floatvalue!=null -> LiteralValue(floatvalue = left.asIntegerValue - right.floatvalue)
else -> throw ExpressionError(error, left.position)
}
left.floatvalue!=null -> when {
right.intvalue!=null -> LiteralValue(floatvalue = left.floatvalue - right.intvalue)
right.asIntegerValue!=null -> LiteralValue(floatvalue = left.floatvalue - right.asIntegerValue)
right.floatvalue!=null -> LiteralValue(floatvalue = left.floatvalue - right.floatvalue)
else -> throw ExpressionError(error, left.position)
}
@ -522,26 +562,26 @@ class ConstExprEvaluator {
}
private fun multiply(left: LiteralValue, right: LiteralValue): LiteralValue {
val error = "cannot multiply $left bitand $right"
val error = "cannot multiply $left and $right"
val litval = when {
left.intvalue!=null -> when {
right.intvalue!=null -> LiteralValue(intvalue = left.intvalue * right.intvalue)
right.floatvalue!=null -> LiteralValue(floatvalue = left.intvalue * right.floatvalue)
left.asIntegerValue!=null -> when {
right.asIntegerValue!=null -> LiteralValue.optimalNumeric(left.asIntegerValue * right.asIntegerValue)
right.floatvalue!=null -> LiteralValue(floatvalue = left.asIntegerValue * right.floatvalue)
right.strvalue!=null -> {
if(right.strvalue.length * left.intvalue > 65535) throw ExpressionError("string too large", left.position)
LiteralValue(strvalue = right.strvalue.repeat(left.intvalue))
if(right.strvalue.length * left.asIntegerValue > 65535) throw ExpressionError("string too large", left.position)
LiteralValue(strvalue = right.strvalue.repeat(left.asIntegerValue))
}
else -> throw ExpressionError(error, left.position)
}
left.floatvalue!=null -> when {
right.intvalue!=null -> LiteralValue(floatvalue = left.floatvalue * right.intvalue)
right.asIntegerValue!=null -> LiteralValue(floatvalue = left.floatvalue * right.asIntegerValue)
right.floatvalue!=null -> LiteralValue(floatvalue = left.floatvalue * right.floatvalue)
else -> throw ExpressionError(error, left.position)
}
left.strvalue!=null -> when {
right.intvalue!=null -> {
if(left.strvalue.length * right.intvalue > 65535) throw ExpressionError("string too large", left.position)
LiteralValue(strvalue = left.strvalue.repeat(right.intvalue))
right.asIntegerValue!=null -> {
if(left.strvalue.length * right.asIntegerValue > 65535) throw ExpressionError("string too large", left.position)
LiteralValue(strvalue = left.strvalue.repeat(right.asIntegerValue))
}
else -> throw ExpressionError(error, left.position)
}
@ -554,21 +594,21 @@ class ConstExprEvaluator {
private fun divide(left: LiteralValue, right: LiteralValue): LiteralValue {
val error = "cannot divide $left by $right"
val litval = when {
left.intvalue!=null -> when {
right.intvalue!=null -> {
if(right.intvalue==0) throw ExpressionError("attempt to divide by zero", left.position)
LiteralValue(intvalue = left.intvalue / right.intvalue)
left.asIntegerValue!=null -> when {
right.asIntegerValue!=null -> {
if(right.asIntegerValue==0) throw ExpressionError("attempt to divide by zero", left.position)
LiteralValue.optimalNumeric(left.asIntegerValue / right.asIntegerValue)
}
right.floatvalue!=null -> {
if(right.floatvalue==0.0) throw ExpressionError("attempt to divide by zero", left.position)
LiteralValue(floatvalue = left.intvalue / right.floatvalue)
LiteralValue(floatvalue = left.asIntegerValue / right.floatvalue)
}
else -> throw ExpressionError(error, left.position)
}
left.floatvalue!=null -> when {
right.intvalue!=null -> {
if(right.intvalue==0) throw ExpressionError("attempt to divide by zero", left.position)
LiteralValue(floatvalue = left.floatvalue / right.intvalue)
right.asIntegerValue!=null -> {
if(right.asIntegerValue==0) throw ExpressionError("attempt to divide by zero", left.position)
LiteralValue(floatvalue = left.floatvalue / right.asIntegerValue)
}
right.floatvalue!=null -> {
if(right.floatvalue==0.0) throw ExpressionError("attempt to divide by zero", left.position)

View File

@ -24,8 +24,8 @@ fun Module.optimizeStatements(globalNamespace: INameScope, allScopedSymbolDefini
todo remove statements that have no effect X=X , X+=0, X-=0, X*=1, X/=1, X//=1, A |= 0, A ^= 0, A<<=0, etc etc
todo optimize addition with self into shift 1 (A+=A -> A<<=1)
todo assignment optimization: optimize some simple multiplications into shifts (A*=8 -> A<<=3)
todo analyse for unreachable code bitand remove that (f.i. code after goto bitor return that has no label so can never be jumped to)
todo merge sequence of assignments into one (as long as the value is a constant bitand the target not a MEMORY type!)
todo analyse for unreachable code and remove that (f.i. code after goto or return that has no label so can never be jumped to)
todo merge sequence of assignments into one (as long as the value is a constant and the target not a MEMORY type!)
todo report more always true/always false conditions
*/

View File

@ -12,11 +12,13 @@ class CommentHandlingTokenStream(lexer: Lexer) : CommonTokenStream(lexer) {
// extract the comments
val commentTokenChannel = il65Lexer.channelNames.indexOf("HIDDEN")
val theLexer = tokenSource as Lexer
return get(0, size())
return get(0, size())
.asSequence()
.filter { it.channel == commentTokenChannel }
.map {
Comment(theLexer.vocabulary.getSymbolicName(it.type),
it.line, it.text.substringAfter(';').trim())
}
.toList()
}
}

View File

@ -38,9 +38,11 @@ fun importModule(filePath: Path) : Module {
// process imports
val lines = moduleAst.statements.toMutableList()
val imports = lines
.asSequence()
.mapIndexed { i, it -> Pair(i, it) }
.filter { (it.second as? Directive)?.directive == "%import" }
.map { Pair(it.first, executeImportDirective(it.second as Directive, filePath)) }
.toList()
imports.reversed().forEach {
if(it.second==null) {

View File

@ -84,17 +84,18 @@ T__82=83
T__83=84
T__84=85
T__85=86
LINECOMMENT=87
COMMENT=88
WS=89
EOL=90
NAME=91
DEC_INTEGER=92
HEX_INTEGER=93
BIN_INTEGER=94
FLOAT_NUMBER=95
STRING=96
INLINEASMBLOCK=97
T__86=87
LINECOMMENT=88
COMMENT=89
WS=90
EOL=91
NAME=92
DEC_INTEGER=93
HEX_INTEGER=94
BIN_INTEGER=95
FLOAT_NUMBER=96
STRING=97
INLINEASMBLOCK=98
'~'=1
':'=2
'goto'=3
@ -163,21 +164,22 @@ INLINEASMBLOCK=97
'Pz'=66
'Pn'=67
'Pv'=68
'true'=69
'false'=70
'%asm'=71
'sub'=72
'->'=73
'{'=74
'}'=75
'?'=76
'if'=77
'else'=78
'if_cs'=79
'if_cc'=80
'if_eq'=81
'if_ne'=82
'if_pl'=83
'if_mi'=84
'if_vs'=85
'if_vc'=86
'.w'=69
'true'=70
'false'=71
'%asm'=72
'sub'=73
'->'=74
'{'=75
'}'=76
'?'=77
'if'=78
'else'=79
'if_cs'=80
'if_cc'=81
'if_eq'=82
'if_ne'=83
'if_pl'=84
'if_mi'=85
'if_vs'=86
'if_vc'=87

View File

@ -28,9 +28,9 @@ public class il65Lexer extends Lexer {
T__59=60, T__60=61, T__61=62, T__62=63, T__63=64, T__64=65, T__65=66,
T__66=67, T__67=68, T__68=69, T__69=70, T__70=71, T__71=72, T__72=73,
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, LINECOMMENT=87,
COMMENT=88, WS=89, EOL=90, NAME=91, DEC_INTEGER=92, HEX_INTEGER=93, BIN_INTEGER=94,
FLOAT_NUMBER=95, STRING=96, INLINEASMBLOCK=97;
T__80=81, T__81=82, T__82=83, T__83=84, T__84=85, T__85=86, T__86=87,
LINECOMMENT=88, COMMENT=89, WS=90, EOL=91, NAME=92, DEC_INTEGER=93, HEX_INTEGER=94,
BIN_INTEGER=95, FLOAT_NUMBER=96, STRING=97, INLINEASMBLOCK=98;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
@ -50,7 +50,7 @@ public class il65Lexer extends Lexer {
"T__57", "T__58", "T__59", "T__60", "T__61", "T__62", "T__63", "T__64",
"T__65", "T__66", "T__67", "T__68", "T__69", "T__70", "T__71", "T__72",
"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", "LINECOMMENT", "COMMENT",
"T__81", "T__82", "T__83", "T__84", "T__85", "T__86", "LINECOMMENT", "COMMENT",
"WS", "EOL", "NAME", "DEC_INTEGER", "HEX_INTEGER", "BIN_INTEGER", "FLOAT_NUMBER",
"FNUMBER", "STRING_ESCAPE_SEQ", "STRING", "INLINEASMBLOCK"
};
@ -64,7 +64,7 @@ public class il65Lexer extends Lexer {
"'('", "')'", "'+'", "'-'", "'**'", "'*'", "'/'", "'<'", "'>'", "'<='",
"'>='", "'=='", "'!='", "'&'", "'^'", "'|'", "'to'", "'and'", "'or'",
"'xor'", "'not'", "'return'", "'.'", "'A'", "'X'", "'Y'", "'AX'", "'AY'",
"'XY'", "'Pc'", "'Pz'", "'Pn'", "'Pv'", "'true'", "'false'", "'%asm'",
"'XY'", "'Pc'", "'Pz'", "'Pn'", "'Pv'", "'.w'", "'true'", "'false'", "'%asm'",
"'sub'", "'->'", "'{'", "'}'", "'?'", "'if'", "'else'", "'if_cs'", "'if_cc'",
"'if_eq'", "'if_ne'", "'if_pl'", "'if_mi'", "'if_vs'", "'if_vc'"
};
@ -76,8 +76,9 @@ public class il65Lexer 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, "LINECOMMENT", "COMMENT", "WS", "EOL", "NAME", "DEC_INTEGER",
"HEX_INTEGER", "BIN_INTEGER", "FLOAT_NUMBER", "STRING", "INLINEASMBLOCK"
null, null, 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);
@ -139,10 +140,10 @@ public class il65Lexer extends Lexer {
@Override
public void action(RuleContext _localctx, int ruleIndex, int actionIndex) {
switch (ruleIndex) {
case 97:
case 98:
STRING_action((RuleContext)_localctx, actionIndex);
break;
case 98:
case 99:
INLINEASMBLOCK_action((RuleContext)_localctx, actionIndex);
break;
}
@ -171,7 +172,7 @@ public class il65Lexer extends Lexer {
}
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2c\u02a1\b\1\4\2\t"+
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2d\u02a6\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"+
@ -182,218 +183,220 @@ public class il65Lexer extends Lexer {
"\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\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\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\37\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\60\3\60\3\60\3\61\3\61\3\61\3\62\3\62\3\63"+
"\3\63\3\64\3\64\3\65\3\65\3\65\3\66\3\66\3\66\3\66\3\67\3\67\3\67\38\3"+
"8\38\38\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@\3A\3A\3A\3B\3B\3B\3C\3C\3C\3D\3D\3D\3E\3E\3E\3F\3F\3F\3"+
"F\3F\3G\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I\3I\3I\3J\3J\3J\3K\3K\3L\3"+
"L\3M\3M\3N\3N\3N\3O\3O\3O\3O\3O\3P\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3"+
"R\3R\3R\3R\3R\3R\3S\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3"+
"U\3V\3V\3V\3V\3V\3V\3W\3W\3W\3W\3W\3W\3X\3X\7X\u0238\nX\fX\16X\u023b\13"+
"X\3X\3X\3X\3X\3Y\3Y\7Y\u0243\nY\fY\16Y\u0246\13Y\3Y\3Y\3Z\3Z\3Z\3Z\3["+
"\6[\u024f\n[\r[\16[\u0250\3\\\3\\\7\\\u0255\n\\\f\\\16\\\u0258\13\\\3"+
"]\3]\3]\6]\u025d\n]\r]\16]\u025e\5]\u0261\n]\3^\3^\6^\u0265\n^\r^\16^"+
"\u0266\3_\3_\6_\u026b\n_\r_\16_\u026c\3`\3`\3`\5`\u0272\n`\3`\5`\u0275"+
"\n`\3a\6a\u0278\na\ra\16a\u0279\3a\3a\6a\u027e\na\ra\16a\u027f\5a\u0282"+
"\na\3b\3b\3b\3b\5b\u0288\nb\3c\3c\3c\7c\u028d\nc\fc\16c\u0290\13c\3c\3"+
"c\3c\3d\3d\3d\3d\6d\u0299\nd\rd\16d\u029a\3d\3d\3d\3d\3d\3\u029a\2e\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\67m8o9"+
"q: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\u00c1\2\u00c3\2\u00c5b\u00c7c\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\u02af\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\u00c5\3\2\2\2\2\u00c7\3\2\2\2\3\u00c9\3\2\2\2\5\u00cb\3\2\2"+
"\2\7\u00cd\3\2\2\2\t\u00d2\3\2\2\2\13\u00da\3\2\2\2\r\u00e4\3\2\2\2\17"+
"\u00ee\3\2\2\2\21\u00f7\3\2\2\2\23\u00ff\3\2\2\2\25\u010b\3\2\2\2\27\u0117"+
"\3\2\2\2\31\u0122\3\2\2\2\33\u012a\3\2\2\2\35\u012c\3\2\2\2\37\u012e\3"+
"\2\2\2!\u0134\3\2\2\2#\u013b\3\2\2\2%\u0140\3\2\2\2\'\u0145\3\2\2\2)\u014b"+
"\3\2\2\2+\u014f\3\2\2\2-\u0155\3\2\2\2/\u015b\3\2\2\2\61\u0162\3\2\2\2"+
"\63\u0164\3\2\2\2\65\u0166\3\2\2\2\67\u0169\3\2\2\29\u016c\3\2\2\2;\u016f"+
"\3\2\2\2=\u0172\3\2\2\2?\u0176\3\2\2\2A\u0179\3\2\2\2C\u017c\3\2\2\2E"+
"\u017f\3\2\2\2G\u0182\3\2\2\2I\u0185\3\2\2\2K\u0187\3\2\2\2M\u0189\3\2"+
"\2\2O\u018b\3\2\2\2Q\u018d\3\2\2\2S\u0190\3\2\2\2U\u0192\3\2\2\2W\u0194"+
"\3\2\2\2Y\u0196\3\2\2\2[\u0198\3\2\2\2]\u019b\3\2\2\2_\u019e\3\2\2\2a"+
"\u01a1\3\2\2\2c\u01a4\3\2\2\2e\u01a6\3\2\2\2g\u01a8\3\2\2\2i\u01aa\3\2"+
"\2\2k\u01ad\3\2\2\2m\u01b1\3\2\2\2o\u01b4\3\2\2\2q\u01b8\3\2\2\2s\u01bc"+
"\3\2\2\2u\u01c3\3\2\2\2w\u01c5\3\2\2\2y\u01c7\3\2\2\2{\u01c9\3\2\2\2}"+
"\u01cb\3\2\2\2\177\u01ce\3\2\2\2\u0081\u01d1\3\2\2\2\u0083\u01d4\3\2\2"+
"\2\u0085\u01d7\3\2\2\2\u0087\u01da\3\2\2\2\u0089\u01dd\3\2\2\2\u008b\u01e0"+
"\3\2\2\2\u008d\u01e5\3\2\2\2\u008f\u01eb\3\2\2\2\u0091\u01f0\3\2\2\2\u0093"+
"\u01f4\3\2\2\2\u0095\u01f7\3\2\2\2\u0097\u01f9\3\2\2\2\u0099\u01fb\3\2"+
"\2\2\u009b\u01fd\3\2\2\2\u009d\u0200\3\2\2\2\u009f\u0205\3\2\2\2\u00a1"+
"\u020b\3\2\2\2\u00a3\u0211\3\2\2\2\u00a5\u0217\3\2\2\2\u00a7\u021d\3\2"+
"\2\2\u00a9\u0223\3\2\2\2\u00ab\u0229\3\2\2\2\u00ad\u022f\3\2\2\2\u00af"+
"\u0235\3\2\2\2\u00b1\u0240\3\2\2\2\u00b3\u0249\3\2\2\2\u00b5\u024e\3\2"+
"\2\2\u00b7\u0252\3\2\2\2\u00b9\u0260\3\2\2\2\u00bb\u0262\3\2\2\2\u00bd"+
"\u0268\3\2\2\2\u00bf\u026e\3\2\2\2\u00c1\u0277\3\2\2\2\u00c3\u0287\3\2"+
"\2\2\u00c5\u0289\3\2\2\2\u00c7\u0294\3\2\2\2\u00c9\u00ca\7\u0080\2\2\u00ca"+
"\4\3\2\2\2\u00cb\u00cc\7<\2\2\u00cc\6\3\2\2\2\u00cd\u00ce\7i\2\2\u00ce"+
"\u00cf\7q\2\2\u00cf\u00d0\7v\2\2\u00d0\u00d1\7q\2\2\u00d1\b\3\2\2\2\u00d2"+
"\u00d3\7\'\2\2\u00d3\u00d4\7q\2\2\u00d4\u00d5\7w\2\2\u00d5\u00d6\7v\2"+
"\2\u00d6\u00d7\7r\2\2\u00d7\u00d8\7w\2\2\u00d8\u00d9\7v\2\2\u00d9\n\3"+
"\2\2\2\u00da\u00db\7\'\2\2\u00db\u00dc\7n\2\2\u00dc\u00dd\7c\2\2\u00dd"+
"\u00de\7w\2\2\u00de\u00df\7p\2\2\u00df\u00e0\7e\2\2\u00e0\u00e1\7j\2\2"+
"\u00e1\u00e2\7g\2\2\u00e2\u00e3\7t\2\2\u00e3\f\3\2\2\2\u00e4\u00e5\7\'"+
"\2\2\u00e5\u00e6\7|\2\2\u00e6\u00e7\7g\2\2\u00e7\u00e8\7t\2\2\u00e8\u00e9"+
"\7q\2\2\u00e9\u00ea\7r\2\2\u00ea\u00eb\7c\2\2\u00eb\u00ec\7i\2\2\u00ec"+
"\u00ed\7g\2\2\u00ed\16\3\2\2\2\u00ee\u00ef\7\'\2\2\u00ef\u00f0\7c\2\2"+
"\u00f0\u00f1\7f\2\2\u00f1\u00f2\7f\2\2\u00f2\u00f3\7t\2\2\u00f3\u00f4"+
"\7g\2\2\u00f4\u00f5\7u\2\2\u00f5\u00f6\7u\2\2\u00f6\20\3\2\2\2\u00f7\u00f8"+
"\7\'\2\2\u00f8\u00f9\7k\2\2\u00f9\u00fa\7o\2\2\u00fa\u00fb\7r\2\2\u00fb"+
"\u00fc\7q\2\2\u00fc\u00fd\7t\2\2\u00fd\u00fe\7v\2\2\u00fe\22\3\2\2\2\u00ff"+
"\u0100\7\'\2\2\u0100\u0101\7d\2\2\u0101\u0102\7t\2\2\u0102\u0103\7g\2"+
"\2\u0103\u0104\7c\2\2\u0104\u0105\7m\2\2\u0105\u0106\7r\2\2\u0106\u0107"+
"\7q\2\2\u0107\u0108\7k\2\2\u0108\u0109\7p\2\2\u0109\u010a\7v\2\2\u010a"+
"\24\3\2\2\2\u010b\u010c\7\'\2\2\u010c\u010d\7c\2\2\u010d\u010e\7u\2\2"+
"\u010e\u010f\7o\2\2\u010f\u0110\7k\2\2\u0110\u0111\7p\2\2\u0111\u0112"+
"\7e\2\2\u0112\u0113\7n\2\2\u0113\u0114\7w\2\2\u0114\u0115\7f\2\2\u0115"+
"\u0116\7g\2\2\u0116\26\3\2\2\2\u0117\u0118\7\'\2\2\u0118\u0119\7c\2\2"+
"\u0119\u011a\7u\2\2\u011a\u011b\7o\2\2\u011b\u011c\7d\2\2\u011c\u011d"+
"\7k\2\2\u011d\u011e\7p\2\2\u011e\u011f\7c\2\2\u011f\u0120\7t\2\2\u0120"+
"\u0121\7{\2\2\u0121\30\3\2\2\2\u0122\u0123\7\'\2\2\u0123\u0124\7q\2\2"+
"\u0124\u0125\7r\2\2\u0125\u0126\7v\2\2\u0126\u0127\7k\2\2\u0127\u0128"+
"\7q\2\2\u0128\u0129\7p\2\2\u0129\32\3\2\2\2\u012a\u012b\7.\2\2\u012b\34"+
"\3\2\2\2\u012c\u012d\7?\2\2\u012d\36\3\2\2\2\u012e\u012f\7e\2\2\u012f"+
"\u0130\7q\2\2\u0130\u0131\7p\2\2\u0131\u0132\7u\2\2\u0132\u0133\7v\2\2"+
"\u0133 \3\2\2\2\u0134\u0135\7o\2\2\u0135\u0136\7g\2\2\u0136\u0137\7o\2"+
"\2\u0137\u0138\7q\2\2\u0138\u0139\7t\2\2\u0139\u013a\7{\2\2\u013a\"\3"+
"\2\2\2\u013b\u013c\7d\2\2\u013c\u013d\7{\2\2\u013d\u013e\7v\2\2\u013e"+
"\u013f\7g\2\2\u013f$\3\2\2\2\u0140\u0141\7y\2\2\u0141\u0142\7q\2\2\u0142"+
"\u0143\7t\2\2\u0143\u0144\7f\2\2\u0144&\3\2\2\2\u0145\u0146\7h\2\2\u0146"+
"\u0147\7n\2\2\u0147\u0148\7q\2\2\u0148\u0149\7c\2\2\u0149\u014a\7v\2\2"+
"\u014a(\3\2\2\2\u014b\u014c\7u\2\2\u014c\u014d\7v\2\2\u014d\u014e\7t\2"+
"\2\u014e*\3\2\2\2\u014f\u0150\7u\2\2\u0150\u0151\7v\2\2\u0151\u0152\7"+
"t\2\2\u0152\u0153\7a\2\2\u0153\u0154\7r\2\2\u0154,\3\2\2\2\u0155\u0156"+
"\7u\2\2\u0156\u0157\7v\2\2\u0157\u0158\7t\2\2\u0158\u0159\7a\2\2\u0159"+
"\u015a\7u\2\2\u015a.\3\2\2\2\u015b\u015c\7u\2\2\u015c\u015d\7v\2\2\u015d"+
"\u015e\7t\2\2\u015e\u015f\7a\2\2\u015f\u0160\7r\2\2\u0160\u0161\7u\2\2"+
"\u0161\60\3\2\2\2\u0162\u0163\7]\2\2\u0163\62\3\2\2\2\u0164\u0165\7_\2"+
"\2\u0165\64\3\2\2\2\u0166\u0167\7-\2\2\u0167\u0168\7?\2\2\u0168\66\3\2"+
"\2\2\u0169\u016a\7/\2\2\u016a\u016b\7?\2\2\u016b8\3\2\2\2\u016c\u016d"+
"\7\61\2\2\u016d\u016e\7?\2\2\u016e:\3\2\2\2\u016f\u0170\7,\2\2\u0170\u0171"+
"\7?\2\2\u0171<\3\2\2\2\u0172\u0173\7,\2\2\u0173\u0174\7,\2\2\u0174\u0175"+
"\7?\2\2\u0175>\3\2\2\2\u0176\u0177\7(\2\2\u0177\u0178\7?\2\2\u0178@\3"+
"\2\2\2\u0179\u017a\7~\2\2\u017a\u017b\7?\2\2\u017bB\3\2\2\2\u017c\u017d"+
"\7`\2\2\u017d\u017e\7?\2\2\u017eD\3\2\2\2\u017f\u0180\7-\2\2\u0180\u0181"+
"\7-\2\2\u0181F\3\2\2\2\u0182\u0183\7/\2\2\u0183\u0184\7/\2\2\u0184H\3"+
"\2\2\2\u0185\u0186\7*\2\2\u0186J\3\2\2\2\u0187\u0188\7+\2\2\u0188L\3\2"+
"\2\2\u0189\u018a\7-\2\2\u018aN\3\2\2\2\u018b\u018c\7/\2\2\u018cP\3\2\2"+
"\2\u018d\u018e\7,\2\2\u018e\u018f\7,\2\2\u018fR\3\2\2\2\u0190\u0191\7"+
",\2\2\u0191T\3\2\2\2\u0192\u0193\7\61\2\2\u0193V\3\2\2\2\u0194\u0195\7"+
">\2\2\u0195X\3\2\2\2\u0196\u0197\7@\2\2\u0197Z\3\2\2\2\u0198\u0199\7>"+
"\2\2\u0199\u019a\7?\2\2\u019a\\\3\2\2\2\u019b\u019c\7@\2\2\u019c\u019d"+
"\7?\2\2\u019d^\3\2\2\2\u019e\u019f\7?\2\2\u019f\u01a0\7?\2\2\u01a0`\3"+
"\2\2\2\u01a1\u01a2\7#\2\2\u01a2\u01a3\7?\2\2\u01a3b\3\2\2\2\u01a4\u01a5"+
"\7(\2\2\u01a5d\3\2\2\2\u01a6\u01a7\7`\2\2\u01a7f\3\2\2\2\u01a8\u01a9\7"+
"~\2\2\u01a9h\3\2\2\2\u01aa\u01ab\7v\2\2\u01ab\u01ac\7q\2\2\u01acj\3\2"+
"\2\2\u01ad\u01ae\7c\2\2\u01ae\u01af\7p\2\2\u01af\u01b0\7f\2\2\u01b0l\3"+
"\2\2\2\u01b1\u01b2\7q\2\2\u01b2\u01b3\7t\2\2\u01b3n\3\2\2\2\u01b4\u01b5"+
"\7z\2\2\u01b5\u01b6\7q\2\2\u01b6\u01b7\7t\2\2\u01b7p\3\2\2\2\u01b8\u01b9"+
"\7p\2\2\u01b9\u01ba\7q\2\2\u01ba\u01bb\7v\2\2\u01bbr\3\2\2\2\u01bc\u01bd"+
"\7t\2\2\u01bd\u01be\7g\2\2\u01be\u01bf\7v\2\2\u01bf\u01c0\7w\2\2\u01c0"+
"\u01c1\7t\2\2\u01c1\u01c2\7p\2\2\u01c2t\3\2\2\2\u01c3\u01c4\7\60\2\2\u01c4"+
"v\3\2\2\2\u01c5\u01c6\7C\2\2\u01c6x\3\2\2\2\u01c7\u01c8\7Z\2\2\u01c8z"+
"\3\2\2\2\u01c9\u01ca\7[\2\2\u01ca|\3\2\2\2\u01cb\u01cc\7C\2\2\u01cc\u01cd"+
"\7Z\2\2\u01cd~\3\2\2\2\u01ce\u01cf\7C\2\2\u01cf\u01d0\7[\2\2\u01d0\u0080"+
"\3\2\2\2\u01d1\u01d2\7Z\2\2\u01d2\u01d3\7[\2\2\u01d3\u0082\3\2\2\2\u01d4"+
"\u01d5\7R\2\2\u01d5\u01d6\7e\2\2\u01d6\u0084\3\2\2\2\u01d7\u01d8\7R\2"+
"\2\u01d8\u01d9\7|\2\2\u01d9\u0086\3\2\2\2\u01da\u01db\7R\2\2\u01db\u01dc"+
"\7p\2\2\u01dc\u0088\3\2\2\2\u01dd\u01de\7R\2\2\u01de\u01df\7x\2\2\u01df"+
"\u008a\3\2\2\2\u01e0\u01e1\7v\2\2\u01e1\u01e2\7t\2\2\u01e2\u01e3\7w\2"+
"\2\u01e3\u01e4\7g\2\2\u01e4\u008c\3\2\2\2\u01e5\u01e6\7h\2\2\u01e6\u01e7"+
"\7c\2\2\u01e7\u01e8\7n\2\2\u01e8\u01e9\7u\2\2\u01e9\u01ea\7g\2\2\u01ea"+
"\u008e\3\2\2\2\u01eb\u01ec\7\'\2\2\u01ec\u01ed\7c\2\2\u01ed\u01ee\7u\2"+
"\2\u01ee\u01ef\7o\2\2\u01ef\u0090\3\2\2\2\u01f0\u01f1\7u\2\2\u01f1\u01f2"+
"\7w\2\2\u01f2\u01f3\7d\2\2\u01f3\u0092\3\2\2\2\u01f4\u01f5\7/\2\2\u01f5"+
"\u01f6\7@\2\2\u01f6\u0094\3\2\2\2\u01f7\u01f8\7}\2\2\u01f8\u0096\3\2\2"+
"\2\u01f9\u01fa\7\177\2\2\u01fa\u0098\3\2\2\2\u01fb\u01fc\7A\2\2\u01fc"+
"\u009a\3\2\2\2\u01fd\u01fe\7k\2\2\u01fe\u01ff\7h\2\2\u01ff\u009c\3\2\2"+
"\2\u0200\u0201\7g\2\2\u0201\u0202\7n\2\2\u0202\u0203\7u\2\2\u0203\u0204"+
"\7g\2\2\u0204\u009e\3\2\2\2\u0205\u0206\7k\2\2\u0206\u0207\7h\2\2\u0207"+
"\u0208\7a\2\2\u0208\u0209\7e\2\2\u0209\u020a\7u\2\2\u020a\u00a0\3\2\2"+
"\2\u020b\u020c\7k\2\2\u020c\u020d\7h\2\2\u020d\u020e\7a\2\2\u020e\u020f"+
"\7e\2\2\u020f\u0210\7e\2\2\u0210\u00a2\3\2\2\2\u0211\u0212\7k\2\2\u0212"+
"\u0213\7h\2\2\u0213\u0214\7a\2\2\u0214\u0215\7g\2\2\u0215\u0216\7s\2\2"+
"\u0216\u00a4\3\2\2\2\u0217\u0218\7k\2\2\u0218\u0219\7h\2\2\u0219\u021a"+
"\7a\2\2\u021a\u021b\7p\2\2\u021b\u021c\7g\2\2\u021c\u00a6\3\2\2\2\u021d"+
"\u021e\7k\2\2\u021e\u021f\7h\2\2\u021f\u0220\7a\2\2\u0220\u0221\7r\2\2"+
"\u0221\u0222\7n\2\2\u0222\u00a8\3\2\2\2\u0223\u0224\7k\2\2\u0224\u0225"+
"\7h\2\2\u0225\u0226\7a\2\2\u0226\u0227\7o\2\2\u0227\u0228\7k\2\2\u0228"+
"\u00aa\3\2\2\2\u0229\u022a\7k\2\2\u022a\u022b\7h\2\2\u022b\u022c\7a\2"+
"\2\u022c\u022d\7x\2\2\u022d\u022e\7u\2\2\u022e\u00ac\3\2\2\2\u022f\u0230"+
"\7k\2\2\u0230\u0231\7h\2\2\u0231\u0232\7a\2\2\u0232\u0233\7x\2\2\u0233"+
"\u0234\7e\2\2\u0234\u00ae\3\2\2\2\u0235\u0239\t\2\2\2\u0236\u0238\t\3"+
"\2\2\u0237\u0236\3\2\2\2\u0238\u023b\3\2\2\2\u0239\u0237\3\2\2\2\u0239"+
"\u023a\3\2\2\2\u023a\u023c\3\2\2\2\u023b\u0239\3\2\2\2\u023c\u023d\5\u00b1"+
"Y\2\u023d\u023e\3\2\2\2\u023e\u023f\bX\2\2\u023f\u00b0\3\2\2\2\u0240\u0244"+
"\7=\2\2\u0241\u0243\n\2\2\2\u0242\u0241\3\2\2\2\u0243\u0246\3\2\2\2\u0244"+
"\u0242\3\2\2\2\u0244\u0245\3\2\2\2\u0245\u0247\3\2\2\2\u0246\u0244\3\2"+
"\2\2\u0247\u0248\bY\2\2\u0248\u00b2\3\2\2\2\u0249\u024a\t\3\2\2\u024a"+
"\u024b\3\2\2\2\u024b\u024c\bZ\3\2\u024c\u00b4\3\2\2\2\u024d\u024f\t\2"+
"\2\2\u024e\u024d\3\2\2\2\u024f\u0250\3\2\2\2\u0250\u024e\3\2\2\2\u0250"+
"\u0251\3\2\2\2\u0251\u00b6\3\2\2\2\u0252\u0256\t\4\2\2\u0253\u0255\t\5"+
"\2\2\u0254\u0253\3\2\2\2\u0255\u0258\3\2\2\2\u0256\u0254\3\2\2\2\u0256"+
"\u0257\3\2\2\2\u0257\u00b8\3\2\2\2\u0258\u0256\3\2\2\2\u0259\u0261\4\62"+
";\2\u025a\u025c\4\63;\2\u025b\u025d\4\62;\2\u025c\u025b\3\2\2\2\u025d"+
"\u025e\3\2\2\2\u025e\u025c\3\2\2\2\u025e\u025f\3\2\2\2\u025f\u0261\3\2"+
"\2\2\u0260\u0259\3\2\2\2\u0260\u025a\3\2\2\2\u0261\u00ba\3\2\2\2\u0262"+
"\u0264\7&\2\2\u0263\u0265\t\6\2\2\u0264\u0263\3\2\2\2\u0265\u0266\3\2"+
"\2\2\u0266\u0264\3\2\2\2\u0266\u0267\3\2\2\2\u0267\u00bc\3\2\2\2\u0268"+
"\u026a\7\'\2\2\u0269\u026b\4\62\63\2\u026a\u0269\3\2\2\2\u026b\u026c\3"+
"\2\2\2\u026c\u026a\3\2\2\2\u026c\u026d\3\2\2\2\u026d\u00be\3\2\2\2\u026e"+
"\u0274\5\u00c1a\2\u026f\u0271\t\7\2\2\u0270\u0272\t\b\2\2\u0271\u0270"+
"\3\2\2\2\u0271\u0272\3\2\2\2\u0272\u0273\3\2\2\2\u0273\u0275\5\u00c1a"+
"\2\u0274\u026f\3\2\2\2\u0274\u0275\3\2\2\2\u0275\u00c0\3\2\2\2\u0276\u0278"+
"\4\62;\2\u0277\u0276\3\2\2\2\u0278\u0279\3\2\2\2\u0279\u0277\3\2\2\2\u0279"+
"\u027a\3\2\2\2\u027a\u0281\3\2\2\2\u027b\u027d\7\60\2\2\u027c\u027e\4"+
"\62;\2\u027d\u027c\3\2\2\2\u027e\u027f\3\2\2\2\u027f\u027d\3\2\2\2\u027f"+
"\u0280\3\2\2\2\u0280\u0282\3\2\2\2\u0281\u027b\3\2\2\2\u0281\u0282\3\2"+
"\2\2\u0282\u00c2\3\2\2\2\u0283\u0284\7^\2\2\u0284\u0288\13\2\2\2\u0285"+
"\u0286\7^\2\2\u0286\u0288\5\u00b5[\2\u0287\u0283\3\2\2\2\u0287\u0285\3"+
"\2\2\2\u0288\u00c4\3\2\2\2\u0289\u028e\7$\2\2\u028a\u028d\5\u00c3b\2\u028b"+
"\u028d\n\t\2\2\u028c\u028a\3\2\2\2\u028c\u028b\3\2\2\2\u028d\u0290\3\2"+
"\2\2\u028e\u028c\3\2\2\2\u028e\u028f\3\2\2\2\u028f\u0291\3\2\2\2\u0290"+
"\u028e\3\2\2\2\u0291\u0292\7$\2\2\u0292\u0293\bc\4\2\u0293\u00c6\3\2\2"+
"\2\u0294\u0295\7}\2\2\u0295\u0296\7}\2\2\u0296\u0298\3\2\2\2\u0297\u0299"+
"\13\2\2\2\u0298\u0297\3\2\2\2\u0299\u029a\3\2\2\2\u029a\u029b\3\2\2\2"+
"\u029a\u0298\3\2\2\2\u029b\u029c\3\2\2\2\u029c\u029d\7\177\2\2\u029d\u029e"+
"\7\177\2\2\u029e\u029f\3\2\2\2\u029f\u02a0\bd\5\2\u02a0\u00c8\3\2\2\2"+
"\25\2\u0239\u0244\u0250\u0256\u025e\u0260\u0264\u0266\u026c\u0271\u0274"+
"\u0279\u027f\u0281\u0287\u028c\u028e\u029a\6\2\3\2\b\2\2\3c\2\3d\3";
"`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\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\37\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\60\3\60\3\60\3\61\3\61\3\61\3\62\3\62"+
"\3\63\3\63\3\64\3\64\3\65\3\65\3\65\3\66\3\66\3\66\3\66\3\67\3\67\3\67"+
"\38\38\38\38\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@\3A\3A\3A\3B\3B\3B\3C\3C\3C\3D\3D\3D\3E\3E\3E\3F\3F"+
"\3F\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3J\3J\3J\3J\3K\3K"+
"\3K\3L\3L\3M\3M\3N\3N\3O\3O\3O\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R"+
"\3R\3R\3R\3R\3S\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3U\3V"+
"\3V\3V\3V\3V\3V\3W\3W\3W\3W\3W\3W\3X\3X\3X\3X\3X\3X\3Y\3Y\7Y\u023d\nY"+
"\fY\16Y\u0240\13Y\3Y\3Y\3Y\3Y\3Z\3Z\7Z\u0248\nZ\fZ\16Z\u024b\13Z\3Z\3"+
"Z\3[\3[\3[\3[\3\\\6\\\u0254\n\\\r\\\16\\\u0255\3]\3]\7]\u025a\n]\f]\16"+
"]\u025d\13]\3^\3^\3^\6^\u0262\n^\r^\16^\u0263\5^\u0266\n^\3_\3_\6_\u026a"+
"\n_\r_\16_\u026b\3`\3`\6`\u0270\n`\r`\16`\u0271\3a\3a\3a\5a\u0277\na\3"+
"a\5a\u027a\na\3b\6b\u027d\nb\rb\16b\u027e\3b\3b\6b\u0283\nb\rb\16b\u0284"+
"\5b\u0287\nb\3c\3c\3c\3c\5c\u028d\nc\3d\3d\3d\7d\u0292\nd\fd\16d\u0295"+
"\13d\3d\3d\3d\3e\3e\3e\3e\6e\u029e\ne\re\16e\u029f\3e\3e\3e\3e\3e\3\u029f"+
"\2f\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\67"+
"m8o9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008d"+
"H\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1"+
"R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5"+
"\\\u00b7]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3\2\u00c5\2\u00c7c\u00c9"+
"d\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\2GGgg\4\2--//\6\2\f\f\16\17$$^^\2\u02b4\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\u00c7\3\2\2\2\2\u00c9\3\2\2\2\3\u00cb"+
"\3\2\2\2\5\u00cd\3\2\2\2\7\u00cf\3\2\2\2\t\u00d4\3\2\2\2\13\u00dc\3\2"+
"\2\2\r\u00e6\3\2\2\2\17\u00f0\3\2\2\2\21\u00f9\3\2\2\2\23\u0101\3\2\2"+
"\2\25\u010d\3\2\2\2\27\u0119\3\2\2\2\31\u0124\3\2\2\2\33\u012c\3\2\2\2"+
"\35\u012e\3\2\2\2\37\u0130\3\2\2\2!\u0136\3\2\2\2#\u013d\3\2\2\2%\u0142"+
"\3\2\2\2\'\u0147\3\2\2\2)\u014d\3\2\2\2+\u0151\3\2\2\2-\u0157\3\2\2\2"+
"/\u015d\3\2\2\2\61\u0164\3\2\2\2\63\u0166\3\2\2\2\65\u0168\3\2\2\2\67"+
"\u016b\3\2\2\29\u016e\3\2\2\2;\u0171\3\2\2\2=\u0174\3\2\2\2?\u0178\3\2"+
"\2\2A\u017b\3\2\2\2C\u017e\3\2\2\2E\u0181\3\2\2\2G\u0184\3\2\2\2I\u0187"+
"\3\2\2\2K\u0189\3\2\2\2M\u018b\3\2\2\2O\u018d\3\2\2\2Q\u018f\3\2\2\2S"+
"\u0192\3\2\2\2U\u0194\3\2\2\2W\u0196\3\2\2\2Y\u0198\3\2\2\2[\u019a\3\2"+
"\2\2]\u019d\3\2\2\2_\u01a0\3\2\2\2a\u01a3\3\2\2\2c\u01a6\3\2\2\2e\u01a8"+
"\3\2\2\2g\u01aa\3\2\2\2i\u01ac\3\2\2\2k\u01af\3\2\2\2m\u01b3\3\2\2\2o"+
"\u01b6\3\2\2\2q\u01ba\3\2\2\2s\u01be\3\2\2\2u\u01c5\3\2\2\2w\u01c7\3\2"+
"\2\2y\u01c9\3\2\2\2{\u01cb\3\2\2\2}\u01cd\3\2\2\2\177\u01d0\3\2\2\2\u0081"+
"\u01d3\3\2\2\2\u0083\u01d6\3\2\2\2\u0085\u01d9\3\2\2\2\u0087\u01dc\3\2"+
"\2\2\u0089\u01df\3\2\2\2\u008b\u01e2\3\2\2\2\u008d\u01e5\3\2\2\2\u008f"+
"\u01ea\3\2\2\2\u0091\u01f0\3\2\2\2\u0093\u01f5\3\2\2\2\u0095\u01f9\3\2"+
"\2\2\u0097\u01fc\3\2\2\2\u0099\u01fe\3\2\2\2\u009b\u0200\3\2\2\2\u009d"+
"\u0202\3\2\2\2\u009f\u0205\3\2\2\2\u00a1\u020a\3\2\2\2\u00a3\u0210\3\2"+
"\2\2\u00a5\u0216\3\2\2\2\u00a7\u021c\3\2\2\2\u00a9\u0222\3\2\2\2\u00ab"+
"\u0228\3\2\2\2\u00ad\u022e\3\2\2\2\u00af\u0234\3\2\2\2\u00b1\u023a\3\2"+
"\2\2\u00b3\u0245\3\2\2\2\u00b5\u024e\3\2\2\2\u00b7\u0253\3\2\2\2\u00b9"+
"\u0257\3\2\2\2\u00bb\u0265\3\2\2\2\u00bd\u0267\3\2\2\2\u00bf\u026d\3\2"+
"\2\2\u00c1\u0273\3\2\2\2\u00c3\u027c\3\2\2\2\u00c5\u028c\3\2\2\2\u00c7"+
"\u028e\3\2\2\2\u00c9\u0299\3\2\2\2\u00cb\u00cc\7\u0080\2\2\u00cc\4\3\2"+
"\2\2\u00cd\u00ce\7<\2\2\u00ce\6\3\2\2\2\u00cf\u00d0\7i\2\2\u00d0\u00d1"+
"\7q\2\2\u00d1\u00d2\7v\2\2\u00d2\u00d3\7q\2\2\u00d3\b\3\2\2\2\u00d4\u00d5"+
"\7\'\2\2\u00d5\u00d6\7q\2\2\u00d6\u00d7\7w\2\2\u00d7\u00d8\7v\2\2\u00d8"+
"\u00d9\7r\2\2\u00d9\u00da\7w\2\2\u00da\u00db\7v\2\2\u00db\n\3\2\2\2\u00dc"+
"\u00dd\7\'\2\2\u00dd\u00de\7n\2\2\u00de\u00df\7c\2\2\u00df\u00e0\7w\2"+
"\2\u00e0\u00e1\7p\2\2\u00e1\u00e2\7e\2\2\u00e2\u00e3\7j\2\2\u00e3\u00e4"+
"\7g\2\2\u00e4\u00e5\7t\2\2\u00e5\f\3\2\2\2\u00e6\u00e7\7\'\2\2\u00e7\u00e8"+
"\7|\2\2\u00e8\u00e9\7g\2\2\u00e9\u00ea\7t\2\2\u00ea\u00eb\7q\2\2\u00eb"+
"\u00ec\7r\2\2\u00ec\u00ed\7c\2\2\u00ed\u00ee\7i\2\2\u00ee\u00ef\7g\2\2"+
"\u00ef\16\3\2\2\2\u00f0\u00f1\7\'\2\2\u00f1\u00f2\7c\2\2\u00f2\u00f3\7"+
"f\2\2\u00f3\u00f4\7f\2\2\u00f4\u00f5\7t\2\2\u00f5\u00f6\7g\2\2\u00f6\u00f7"+
"\7u\2\2\u00f7\u00f8\7u\2\2\u00f8\20\3\2\2\2\u00f9\u00fa\7\'\2\2\u00fa"+
"\u00fb\7k\2\2\u00fb\u00fc\7o\2\2\u00fc\u00fd\7r\2\2\u00fd\u00fe\7q\2\2"+
"\u00fe\u00ff\7t\2\2\u00ff\u0100\7v\2\2\u0100\22\3\2\2\2\u0101\u0102\7"+
"\'\2\2\u0102\u0103\7d\2\2\u0103\u0104\7t\2\2\u0104\u0105\7g\2\2\u0105"+
"\u0106\7c\2\2\u0106\u0107\7m\2\2\u0107\u0108\7r\2\2\u0108\u0109\7q\2\2"+
"\u0109\u010a\7k\2\2\u010a\u010b\7p\2\2\u010b\u010c\7v\2\2\u010c\24\3\2"+
"\2\2\u010d\u010e\7\'\2\2\u010e\u010f\7c\2\2\u010f\u0110\7u\2\2\u0110\u0111"+
"\7o\2\2\u0111\u0112\7k\2\2\u0112\u0113\7p\2\2\u0113\u0114\7e\2\2\u0114"+
"\u0115\7n\2\2\u0115\u0116\7w\2\2\u0116\u0117\7f\2\2\u0117\u0118\7g\2\2"+
"\u0118\26\3\2\2\2\u0119\u011a\7\'\2\2\u011a\u011b\7c\2\2\u011b\u011c\7"+
"u\2\2\u011c\u011d\7o\2\2\u011d\u011e\7d\2\2\u011e\u011f\7k\2\2\u011f\u0120"+
"\7p\2\2\u0120\u0121\7c\2\2\u0121\u0122\7t\2\2\u0122\u0123\7{\2\2\u0123"+
"\30\3\2\2\2\u0124\u0125\7\'\2\2\u0125\u0126\7q\2\2\u0126\u0127\7r\2\2"+
"\u0127\u0128\7v\2\2\u0128\u0129\7k\2\2\u0129\u012a\7q\2\2\u012a\u012b"+
"\7p\2\2\u012b\32\3\2\2\2\u012c\u012d\7.\2\2\u012d\34\3\2\2\2\u012e\u012f"+
"\7?\2\2\u012f\36\3\2\2\2\u0130\u0131\7e\2\2\u0131\u0132\7q\2\2\u0132\u0133"+
"\7p\2\2\u0133\u0134\7u\2\2\u0134\u0135\7v\2\2\u0135 \3\2\2\2\u0136\u0137"+
"\7o\2\2\u0137\u0138\7g\2\2\u0138\u0139\7o\2\2\u0139\u013a\7q\2\2\u013a"+
"\u013b\7t\2\2\u013b\u013c\7{\2\2\u013c\"\3\2\2\2\u013d\u013e\7d\2\2\u013e"+
"\u013f\7{\2\2\u013f\u0140\7v\2\2\u0140\u0141\7g\2\2\u0141$\3\2\2\2\u0142"+
"\u0143\7y\2\2\u0143\u0144\7q\2\2\u0144\u0145\7t\2\2\u0145\u0146\7f\2\2"+
"\u0146&\3\2\2\2\u0147\u0148\7h\2\2\u0148\u0149\7n\2\2\u0149\u014a\7q\2"+
"\2\u014a\u014b\7c\2\2\u014b\u014c\7v\2\2\u014c(\3\2\2\2\u014d\u014e\7"+
"u\2\2\u014e\u014f\7v\2\2\u014f\u0150\7t\2\2\u0150*\3\2\2\2\u0151\u0152"+
"\7u\2\2\u0152\u0153\7v\2\2\u0153\u0154\7t\2\2\u0154\u0155\7a\2\2\u0155"+
"\u0156\7r\2\2\u0156,\3\2\2\2\u0157\u0158\7u\2\2\u0158\u0159\7v\2\2\u0159"+
"\u015a\7t\2\2\u015a\u015b\7a\2\2\u015b\u015c\7u\2\2\u015c.\3\2\2\2\u015d"+
"\u015e\7u\2\2\u015e\u015f\7v\2\2\u015f\u0160\7t\2\2\u0160\u0161\7a\2\2"+
"\u0161\u0162\7r\2\2\u0162\u0163\7u\2\2\u0163\60\3\2\2\2\u0164\u0165\7"+
"]\2\2\u0165\62\3\2\2\2\u0166\u0167\7_\2\2\u0167\64\3\2\2\2\u0168\u0169"+
"\7-\2\2\u0169\u016a\7?\2\2\u016a\66\3\2\2\2\u016b\u016c\7/\2\2\u016c\u016d"+
"\7?\2\2\u016d8\3\2\2\2\u016e\u016f\7\61\2\2\u016f\u0170\7?\2\2\u0170:"+
"\3\2\2\2\u0171\u0172\7,\2\2\u0172\u0173\7?\2\2\u0173<\3\2\2\2\u0174\u0175"+
"\7,\2\2\u0175\u0176\7,\2\2\u0176\u0177\7?\2\2\u0177>\3\2\2\2\u0178\u0179"+
"\7(\2\2\u0179\u017a\7?\2\2\u017a@\3\2\2\2\u017b\u017c\7~\2\2\u017c\u017d"+
"\7?\2\2\u017dB\3\2\2\2\u017e\u017f\7`\2\2\u017f\u0180\7?\2\2\u0180D\3"+
"\2\2\2\u0181\u0182\7-\2\2\u0182\u0183\7-\2\2\u0183F\3\2\2\2\u0184\u0185"+
"\7/\2\2\u0185\u0186\7/\2\2\u0186H\3\2\2\2\u0187\u0188\7*\2\2\u0188J\3"+
"\2\2\2\u0189\u018a\7+\2\2\u018aL\3\2\2\2\u018b\u018c\7-\2\2\u018cN\3\2"+
"\2\2\u018d\u018e\7/\2\2\u018eP\3\2\2\2\u018f\u0190\7,\2\2\u0190\u0191"+
"\7,\2\2\u0191R\3\2\2\2\u0192\u0193\7,\2\2\u0193T\3\2\2\2\u0194\u0195\7"+
"\61\2\2\u0195V\3\2\2\2\u0196\u0197\7>\2\2\u0197X\3\2\2\2\u0198\u0199\7"+
"@\2\2\u0199Z\3\2\2\2\u019a\u019b\7>\2\2\u019b\u019c\7?\2\2\u019c\\\3\2"+
"\2\2\u019d\u019e\7@\2\2\u019e\u019f\7?\2\2\u019f^\3\2\2\2\u01a0\u01a1"+
"\7?\2\2\u01a1\u01a2\7?\2\2\u01a2`\3\2\2\2\u01a3\u01a4\7#\2\2\u01a4\u01a5"+
"\7?\2\2\u01a5b\3\2\2\2\u01a6\u01a7\7(\2\2\u01a7d\3\2\2\2\u01a8\u01a9\7"+
"`\2\2\u01a9f\3\2\2\2\u01aa\u01ab\7~\2\2\u01abh\3\2\2\2\u01ac\u01ad\7v"+
"\2\2\u01ad\u01ae\7q\2\2\u01aej\3\2\2\2\u01af\u01b0\7c\2\2\u01b0\u01b1"+
"\7p\2\2\u01b1\u01b2\7f\2\2\u01b2l\3\2\2\2\u01b3\u01b4\7q\2\2\u01b4\u01b5"+
"\7t\2\2\u01b5n\3\2\2\2\u01b6\u01b7\7z\2\2\u01b7\u01b8\7q\2\2\u01b8\u01b9"+
"\7t\2\2\u01b9p\3\2\2\2\u01ba\u01bb\7p\2\2\u01bb\u01bc\7q\2\2\u01bc\u01bd"+
"\7v\2\2\u01bdr\3\2\2\2\u01be\u01bf\7t\2\2\u01bf\u01c0\7g\2\2\u01c0\u01c1"+
"\7v\2\2\u01c1\u01c2\7w\2\2\u01c2\u01c3\7t\2\2\u01c3\u01c4\7p\2\2\u01c4"+
"t\3\2\2\2\u01c5\u01c6\7\60\2\2\u01c6v\3\2\2\2\u01c7\u01c8\7C\2\2\u01c8"+
"x\3\2\2\2\u01c9\u01ca\7Z\2\2\u01caz\3\2\2\2\u01cb\u01cc\7[\2\2\u01cc|"+
"\3\2\2\2\u01cd\u01ce\7C\2\2\u01ce\u01cf\7Z\2\2\u01cf~\3\2\2\2\u01d0\u01d1"+
"\7C\2\2\u01d1\u01d2\7[\2\2\u01d2\u0080\3\2\2\2\u01d3\u01d4\7Z\2\2\u01d4"+
"\u01d5\7[\2\2\u01d5\u0082\3\2\2\2\u01d6\u01d7\7R\2\2\u01d7\u01d8\7e\2"+
"\2\u01d8\u0084\3\2\2\2\u01d9\u01da\7R\2\2\u01da\u01db\7|\2\2\u01db\u0086"+
"\3\2\2\2\u01dc\u01dd\7R\2\2\u01dd\u01de\7p\2\2\u01de\u0088\3\2\2\2\u01df"+
"\u01e0\7R\2\2\u01e0\u01e1\7x\2\2\u01e1\u008a\3\2\2\2\u01e2\u01e3\7\60"+
"\2\2\u01e3\u01e4\7y\2\2\u01e4\u008c\3\2\2\2\u01e5\u01e6\7v\2\2\u01e6\u01e7"+
"\7t\2\2\u01e7\u01e8\7w\2\2\u01e8\u01e9\7g\2\2\u01e9\u008e\3\2\2\2\u01ea"+
"\u01eb\7h\2\2\u01eb\u01ec\7c\2\2\u01ec\u01ed\7n\2\2\u01ed\u01ee\7u\2\2"+
"\u01ee\u01ef\7g\2\2\u01ef\u0090\3\2\2\2\u01f0\u01f1\7\'\2\2\u01f1\u01f2"+
"\7c\2\2\u01f2\u01f3\7u\2\2\u01f3\u01f4\7o\2\2\u01f4\u0092\3\2\2\2\u01f5"+
"\u01f6\7u\2\2\u01f6\u01f7\7w\2\2\u01f7\u01f8\7d\2\2\u01f8\u0094\3\2\2"+
"\2\u01f9\u01fa\7/\2\2\u01fa\u01fb\7@\2\2\u01fb\u0096\3\2\2\2\u01fc\u01fd"+
"\7}\2\2\u01fd\u0098\3\2\2\2\u01fe\u01ff\7\177\2\2\u01ff\u009a\3\2\2\2"+
"\u0200\u0201\7A\2\2\u0201\u009c\3\2\2\2\u0202\u0203\7k\2\2\u0203\u0204"+
"\7h\2\2\u0204\u009e\3\2\2\2\u0205\u0206\7g\2\2\u0206\u0207\7n\2\2\u0207"+
"\u0208\7u\2\2\u0208\u0209\7g\2\2\u0209\u00a0\3\2\2\2\u020a\u020b\7k\2"+
"\2\u020b\u020c\7h\2\2\u020c\u020d\7a\2\2\u020d\u020e\7e\2\2\u020e\u020f"+
"\7u\2\2\u020f\u00a2\3\2\2\2\u0210\u0211\7k\2\2\u0211\u0212\7h\2\2\u0212"+
"\u0213\7a\2\2\u0213\u0214\7e\2\2\u0214\u0215\7e\2\2\u0215\u00a4\3\2\2"+
"\2\u0216\u0217\7k\2\2\u0217\u0218\7h\2\2\u0218\u0219\7a\2\2\u0219\u021a"+
"\7g\2\2\u021a\u021b\7s\2\2\u021b\u00a6\3\2\2\2\u021c\u021d\7k\2\2\u021d"+
"\u021e\7h\2\2\u021e\u021f\7a\2\2\u021f\u0220\7p\2\2\u0220\u0221\7g\2\2"+
"\u0221\u00a8\3\2\2\2\u0222\u0223\7k\2\2\u0223\u0224\7h\2\2\u0224\u0225"+
"\7a\2\2\u0225\u0226\7r\2\2\u0226\u0227\7n\2\2\u0227\u00aa\3\2\2\2\u0228"+
"\u0229\7k\2\2\u0229\u022a\7h\2\2\u022a\u022b\7a\2\2\u022b\u022c\7o\2\2"+
"\u022c\u022d\7k\2\2\u022d\u00ac\3\2\2\2\u022e\u022f\7k\2\2\u022f\u0230"+
"\7h\2\2\u0230\u0231\7a\2\2\u0231\u0232\7x\2\2\u0232\u0233\7u\2\2\u0233"+
"\u00ae\3\2\2\2\u0234\u0235\7k\2\2\u0235\u0236\7h\2\2\u0236\u0237\7a\2"+
"\2\u0237\u0238\7x\2\2\u0238\u0239\7e\2\2\u0239\u00b0\3\2\2\2\u023a\u023e"+
"\t\2\2\2\u023b\u023d\t\3\2\2\u023c\u023b\3\2\2\2\u023d\u0240\3\2\2\2\u023e"+
"\u023c\3\2\2\2\u023e\u023f\3\2\2\2\u023f\u0241\3\2\2\2\u0240\u023e\3\2"+
"\2\2\u0241\u0242\5\u00b3Z\2\u0242\u0243\3\2\2\2\u0243\u0244\bY\2\2\u0244"+
"\u00b2\3\2\2\2\u0245\u0249\7=\2\2\u0246\u0248\n\2\2\2\u0247\u0246\3\2"+
"\2\2\u0248\u024b\3\2\2\2\u0249\u0247\3\2\2\2\u0249\u024a\3\2\2\2\u024a"+
"\u024c\3\2\2\2\u024b\u0249\3\2\2\2\u024c\u024d\bZ\2\2\u024d\u00b4\3\2"+
"\2\2\u024e\u024f\t\3\2\2\u024f\u0250\3\2\2\2\u0250\u0251\b[\3\2\u0251"+
"\u00b6\3\2\2\2\u0252\u0254\t\2\2\2\u0253\u0252\3\2\2\2\u0254\u0255\3\2"+
"\2\2\u0255\u0253\3\2\2\2\u0255\u0256\3\2\2\2\u0256\u00b8\3\2\2\2\u0257"+
"\u025b\t\4\2\2\u0258\u025a\t\5\2\2\u0259\u0258\3\2\2\2\u025a\u025d\3\2"+
"\2\2\u025b\u0259\3\2\2\2\u025b\u025c\3\2\2\2\u025c\u00ba\3\2\2\2\u025d"+
"\u025b\3\2\2\2\u025e\u0266\4\62;\2\u025f\u0261\4\63;\2\u0260\u0262\4\62"+
";\2\u0261\u0260\3\2\2\2\u0262\u0263\3\2\2\2\u0263\u0261\3\2\2\2\u0263"+
"\u0264\3\2\2\2\u0264\u0266\3\2\2\2\u0265\u025e\3\2\2\2\u0265\u025f\3\2"+
"\2\2\u0266\u00bc\3\2\2\2\u0267\u0269\7&\2\2\u0268\u026a\t\6\2\2\u0269"+
"\u0268\3\2\2\2\u026a\u026b\3\2\2\2\u026b\u0269\3\2\2\2\u026b\u026c\3\2"+
"\2\2\u026c\u00be\3\2\2\2\u026d\u026f\7\'\2\2\u026e\u0270\4\62\63\2\u026f"+
"\u026e\3\2\2\2\u0270\u0271\3\2\2\2\u0271\u026f\3\2\2\2\u0271\u0272\3\2"+
"\2\2\u0272\u00c0\3\2\2\2\u0273\u0279\5\u00c3b\2\u0274\u0276\t\7\2\2\u0275"+
"\u0277\t\b\2\2\u0276\u0275\3\2\2\2\u0276\u0277\3\2\2\2\u0277\u0278\3\2"+
"\2\2\u0278\u027a\5\u00c3b\2\u0279\u0274\3\2\2\2\u0279\u027a\3\2\2\2\u027a"+
"\u00c2\3\2\2\2\u027b\u027d\4\62;\2\u027c\u027b\3\2\2\2\u027d\u027e\3\2"+
"\2\2\u027e\u027c\3\2\2\2\u027e\u027f\3\2\2\2\u027f\u0286\3\2\2\2\u0280"+
"\u0282\7\60\2\2\u0281\u0283\4\62;\2\u0282\u0281\3\2\2\2\u0283\u0284\3"+
"\2\2\2\u0284\u0282\3\2\2\2\u0284\u0285\3\2\2\2\u0285\u0287\3\2\2\2\u0286"+
"\u0280\3\2\2\2\u0286\u0287\3\2\2\2\u0287\u00c4\3\2\2\2\u0288\u0289\7^"+
"\2\2\u0289\u028d\13\2\2\2\u028a\u028b\7^\2\2\u028b\u028d\5\u00b7\\\2\u028c"+
"\u0288\3\2\2\2\u028c\u028a\3\2\2\2\u028d\u00c6\3\2\2\2\u028e\u0293\7$"+
"\2\2\u028f\u0292\5\u00c5c\2\u0290\u0292\n\t\2\2\u0291\u028f\3\2\2\2\u0291"+
"\u0290\3\2\2\2\u0292\u0295\3\2\2\2\u0293\u0291\3\2\2\2\u0293\u0294\3\2"+
"\2\2\u0294\u0296\3\2\2\2\u0295\u0293\3\2\2\2\u0296\u0297\7$\2\2\u0297"+
"\u0298\bd\4\2\u0298\u00c8\3\2\2\2\u0299\u029a\7}\2\2\u029a\u029b\7}\2"+
"\2\u029b\u029d\3\2\2\2\u029c\u029e\13\2\2\2\u029d\u029c\3\2\2\2\u029e"+
"\u029f\3\2\2\2\u029f\u02a0\3\2\2\2\u029f\u029d\3\2\2\2\u02a0\u02a1\3\2"+
"\2\2\u02a1\u02a2\7\177\2\2\u02a2\u02a3\7\177\2\2\u02a3\u02a4\3\2\2\2\u02a4"+
"\u02a5\be\5\2\u02a5\u00ca\3\2\2\2\25\2\u023e\u0249\u0255\u025b\u0263\u0265"+
"\u0269\u026b\u0271\u0276\u0279\u027e\u0284\u0286\u028c\u0291\u0293\u029f"+
"\6\2\3\2\b\2\2\3d\2\3e\3";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {

View File

@ -84,17 +84,18 @@ T__82=83
T__83=84
T__84=85
T__85=86
LINECOMMENT=87
COMMENT=88
WS=89
EOL=90
NAME=91
DEC_INTEGER=92
HEX_INTEGER=93
BIN_INTEGER=94
FLOAT_NUMBER=95
STRING=96
INLINEASMBLOCK=97
T__86=87
LINECOMMENT=88
COMMENT=89
WS=90
EOL=91
NAME=92
DEC_INTEGER=93
HEX_INTEGER=94
BIN_INTEGER=95
FLOAT_NUMBER=96
STRING=97
INLINEASMBLOCK=98
'~'=1
':'=2
'goto'=3
@ -163,21 +164,22 @@ INLINEASMBLOCK=97
'Pz'=66
'Pn'=67
'Pv'=68
'true'=69
'false'=70
'%asm'=71
'sub'=72
'->'=73
'{'=74
'}'=75
'?'=76
'if'=77
'else'=78
'if_cs'=79
'if_cc'=80
'if_eq'=81
'if_ne'=82
'if_pl'=83
'if_mi'=84
'if_vs'=85
'if_vc'=86
'.w'=69
'true'=70
'false'=71
'%asm'=72
'sub'=73
'->'=74
'{'=75
'}'=76
'?'=77
'if'=78
'else'=79
'if_cs'=80
'if_cc'=81
'if_eq'=82
'if_ne'=83
'if_pl'=84
'if_mi'=85
'if_vs'=86
'if_vc'=87

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@ enum class Opcode {
POP_MEM, // pop value into destination memory address
POP_VAR, // pop value into variable
// numeric bitand bitwise arithmetic
// numeric and bitwise arithmetic
ADD,
SUB,
MUL,
@ -117,9 +117,9 @@ enum class Opcode {
enum class Syscall(val callNr: Short) {
WRITE_MEMCHR(10), // print a single char from the memory
WRITE_MEMSTR(11), // print a 0-terminated petscii string from the memory
WRITE_NUM(12), // pop from the evaluation stack bitand print it as a number
WRITE_CHAR(13), // pop from the evaluation stack bitand print it as a single petscii character
WRITE_VAR(14), // print the number bitor string from the given variable
WRITE_NUM(12), // pop from the evaluation stack and print it as a number
WRITE_CHAR(13), // pop from the evaluation stack and print it as a single petscii character
WRITE_VAR(14), // print the number or string from the given variable
INPUT_VAR(15), // user input a string into a variable
GFX_PIXEL(16), // plot a pixel at (x,y,color) pushed on stack in that order
GFX_CLEARSCR(17), // clear the screen with color pushed on stack
@ -164,7 +164,7 @@ enum class Syscall(val callNr: Short) {
}
class Memory {
private val mem = ShortArray(65536) // shorts because byte is signed bitand we store values 0..255
private val mem = ShortArray(65536) // shorts because byte is signed and we store values 0..255
fun getByte(address: Int): Short {
return mem[address]
@ -319,7 +319,7 @@ class Value(val type: DataType, private val numericvalue: Number?, val stringval
}
fun rol(carry: Boolean): Pair<Value, Boolean> {
// 9 bitor 17 bit rotate left (with carry))
// 9 or 17 bit rotate left (with carry))
return when(type) {
DataType.BYTE -> {
val v = byteval!!.toInt()
@ -338,7 +338,7 @@ class Value(val type: DataType, private val numericvalue: Number?, val stringval
}
fun ror(carry: Boolean): Pair<Value, Boolean> {
// 9 bitor 17 bit rotate right (with carry)
// 9 or 17 bit rotate right (with carry)
return when(type) {
DataType.BYTE -> {
val v = byteval!!.toInt()
@ -357,7 +357,7 @@ class Value(val type: DataType, private val numericvalue: Number?, val stringval
}
fun rol2(): Value {
// 8 bitor 16 bit rotate left
// 8 or 16 bit rotate left
return when(type) {
DataType.BYTE -> {
val v = byteval!!.toInt()
@ -376,7 +376,7 @@ class Value(val type: DataType, private val numericvalue: Number?, val stringval
}
fun ror2(): Value {
// 8 bitor 16 bit rotate right
// 8 or 16 bit rotate right
return when(type) {
DataType.BYTE -> {
val v = byteval!!.toInt()