mirror of
				https://github.com/irmen/prog8.git
				synced 2025-11-04 10:16:13 +00:00 
			
		
		
		
	work on longs
This commit is contained in:
		@@ -50,8 +50,10 @@ enum class BaseDataType {
 | 
				
			|||||||
val BaseDataType.isByte get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType.BYTE)
 | 
					val BaseDataType.isByte get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType.BYTE)
 | 
				
			||||||
val BaseDataType.isByteOrBool get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType.BYTE, BaseDataType.BOOL)
 | 
					val BaseDataType.isByteOrBool get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType.BYTE, BaseDataType.BOOL)
 | 
				
			||||||
val BaseDataType.isWord get() = this in arrayOf(BaseDataType.UWORD, BaseDataType.WORD)
 | 
					val BaseDataType.isWord get() = this in arrayOf(BaseDataType.UWORD, BaseDataType.WORD)
 | 
				
			||||||
 | 
					val BaseDataType.isLong get() = this == BaseDataType.LONG
 | 
				
			||||||
val BaseDataType.isInteger get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType.BYTE, BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG)
 | 
					val BaseDataType.isInteger get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType.BYTE, BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG)
 | 
				
			||||||
val BaseDataType.isIntegerOrBool get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType.BYTE, BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG, BaseDataType.BOOL)
 | 
					val BaseDataType.isIntegerOrBool get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType.BYTE, BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG, BaseDataType.BOOL)
 | 
				
			||||||
 | 
					val BaseDataType.isWordOrByteOrBool get() = this in arrayOf(BaseDataType.UBYTE, BaseDataType.BYTE, BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.BOOL)
 | 
				
			||||||
val BaseDataType.isNumeric get() = this == BaseDataType.FLOAT || this.isInteger
 | 
					val BaseDataType.isNumeric get() = this == BaseDataType.FLOAT || this.isInteger
 | 
				
			||||||
val BaseDataType.isNumericOrBool get() = this == BaseDataType.BOOL || this.isNumeric
 | 
					val BaseDataType.isNumericOrBool get() = this == BaseDataType.BOOL || this.isNumeric
 | 
				
			||||||
val BaseDataType.isSigned get() = this in arrayOf(BaseDataType.BYTE, BaseDataType.WORD, BaseDataType.LONG, BaseDataType.FLOAT)
 | 
					val BaseDataType.isSigned get() = this in arrayOf(BaseDataType.BYTE, BaseDataType.WORD, BaseDataType.LONG, BaseDataType.FLOAT)
 | 
				
			||||||
@@ -344,6 +346,7 @@ class DataType private constructor(val base: BaseDataType, val sub: BaseDataType
 | 
				
			|||||||
    val isUnsignedWord =  base == BaseDataType.UWORD
 | 
					    val isUnsignedWord =  base == BaseDataType.UWORD
 | 
				
			||||||
    val isSignedWord =  base == BaseDataType.WORD
 | 
					    val isSignedWord =  base == BaseDataType.WORD
 | 
				
			||||||
    val isInteger = base.isInteger
 | 
					    val isInteger = base.isInteger
 | 
				
			||||||
 | 
					    val isWordOrByteOrBool = base.isWordOrByteOrBool
 | 
				
			||||||
    val isIntegerOrBool = base.isIntegerOrBool
 | 
					    val isIntegerOrBool = base.isIntegerOrBool
 | 
				
			||||||
    val isNumeric = base.isNumeric
 | 
					    val isNumeric = base.isNumeric
 | 
				
			||||||
    val isNumericOrBool = base.isNumericOrBool
 | 
					    val isNumericOrBool = base.isNumericOrBool
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@ internal class NormalMemSizer(val floatsize: Int): IMemSizer {
 | 
				
			|||||||
            return when(dt.sub) {
 | 
					            return when(dt.sub) {
 | 
				
			||||||
                BaseDataType.BOOL, BaseDataType.UBYTE, BaseDataType.BYTE -> numElements
 | 
					                BaseDataType.BOOL, BaseDataType.UBYTE, BaseDataType.BYTE -> numElements
 | 
				
			||||||
                BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.STR -> numElements * 2
 | 
					                BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.STR -> numElements * 2
 | 
				
			||||||
 | 
					                BaseDataType.LONG -> numElements * 4
 | 
				
			||||||
                BaseDataType.FLOAT-> numElements * floatsize
 | 
					                BaseDataType.FLOAT-> numElements * floatsize
 | 
				
			||||||
                BaseDataType.UNDEFINED -> throw IllegalArgumentException("undefined has no memory size")
 | 
					                BaseDataType.UNDEFINED -> throw IllegalArgumentException("undefined has no memory size")
 | 
				
			||||||
                else -> throw IllegalArgumentException("invalid sub type")
 | 
					                else -> throw IllegalArgumentException("invalid sub type")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
 | 
				
			|||||||
        // we consider them NOT to be optimized into (possibly different) CPU registers.
 | 
					        // we consider them NOT to be optimized into (possibly different) CPU registers.
 | 
				
			||||||
        // Just load them in whatever the register spec says.
 | 
					        // Just load them in whatever the register spec says.
 | 
				
			||||||
        return when (params.size) {
 | 
					        return when (params.size) {
 | 
				
			||||||
            1 -> params[0].register == null && (params[0].type.isIntegerOrBool || params[0].type.isPointer)
 | 
					            1 -> params[0].register == null && (params[0].type.isWordOrByteOrBool || params[0].type.isPointer)
 | 
				
			||||||
            2 -> params[0].type.isByteOrBool && params[1].type.isByteOrBool && params[0].register == null && params[1].register == null
 | 
					            2 -> params[0].type.isByteOrBool && params[1].type.isByteOrBool && params[0].register == null && params[1].register == null
 | 
				
			||||||
            else -> false
 | 
					            else -> false
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,6 +46,7 @@ internal class IfElseAsmGen(private val program: PtProgram,
 | 
				
			|||||||
            return when {
 | 
					            return when {
 | 
				
			||||||
                rightDt.isByteOrBool -> translateIfByte(stmt, jumpAfterIf)
 | 
					                rightDt.isByteOrBool -> translateIfByte(stmt, jumpAfterIf)
 | 
				
			||||||
                rightDt.isWord || rightDt.isPointer -> translateIfWord(stmt, compareCond, jumpAfterIf)
 | 
					                rightDt.isWord || rightDt.isPointer -> translateIfWord(stmt, compareCond, jumpAfterIf)
 | 
				
			||||||
 | 
					                rightDt.isLong -> translateIfLong(stmt, compareCond, jumpAfterIf)
 | 
				
			||||||
                rightDt.isFloat -> translateIfFloat(stmt, compareCond, jumpAfterIf)
 | 
					                rightDt.isFloat -> translateIfFloat(stmt, compareCond, jumpAfterIf)
 | 
				
			||||||
                else -> throw AssemblyError("weird dt")
 | 
					                else -> throw AssemblyError("weird dt")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -575,6 +576,32 @@ internal class IfElseAsmGen(private val program: PtProgram,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun translateIfLong(stmt: PtIfElse, condition: PtBinaryExpression, jumpAfterIf: PtJump?) {
 | 
				
			||||||
 | 
					        val constValue = condition.right.asConstInteger()
 | 
				
			||||||
 | 
					        if(constValue==0) {
 | 
				
			||||||
 | 
					            // optimized comparisons with zero
 | 
				
			||||||
 | 
					            return when (condition.operator) {
 | 
				
			||||||
 | 
					                "==" -> longEqualsZero(condition.left, false, jumpAfterIf, stmt)
 | 
				
			||||||
 | 
					                "!=" -> longEqualsZero(condition.left, true, jumpAfterIf, stmt)
 | 
				
			||||||
 | 
					                "<" -> longLessZero(condition.left, false, jumpAfterIf, stmt)
 | 
				
			||||||
 | 
					                "<=" -> longLessZero(condition.left, true, jumpAfterIf, stmt)
 | 
				
			||||||
 | 
					                ">" -> longGreaterZero(condition.left, false, jumpAfterIf, stmt)
 | 
				
			||||||
 | 
					                ">=" -> longGreaterZero(condition.left, true, jumpAfterIf, stmt)
 | 
				
			||||||
 | 
					                else -> throw AssemblyError("expected comparison operator")
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return when (condition.operator) {
 | 
				
			||||||
 | 
					            "==" -> longEqualsValue(condition.left, condition.right, false, jumpAfterIf, stmt)
 | 
				
			||||||
 | 
					            "!=" -> longEqualsValue(condition.left, condition.right, true, jumpAfterIf, stmt)
 | 
				
			||||||
 | 
					            "<" -> TODO("long < 0")
 | 
				
			||||||
 | 
					            "<=" -> TODO("long <= 0")
 | 
				
			||||||
 | 
					            ">" -> TODO("long > 0")
 | 
				
			||||||
 | 
					            ">=" -> TODO("long >= 0")
 | 
				
			||||||
 | 
					            else -> throw AssemblyError("expected comparison operator")
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun translateIfWord(stmt: PtIfElse, condition: PtBinaryExpression, jumpAfterIf: PtJump?) {
 | 
					    private fun translateIfWord(stmt: PtIfElse, condition: PtBinaryExpression, jumpAfterIf: PtJump?) {
 | 
				
			||||||
        val signed = condition.left.type.isSigned
 | 
					        val signed = condition.left.type.isSigned
 | 
				
			||||||
        val constValue = condition.right.asConstInteger()
 | 
					        val constValue = condition.right.asConstInteger()
 | 
				
			||||||
@@ -606,7 +633,7 @@ internal class IfElseAsmGen(private val program: PtProgram,
 | 
				
			|||||||
    private fun wordGreaterEqualsZero(value: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
 | 
					    private fun wordGreaterEqualsZero(value: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
 | 
				
			||||||
        // special case for word>=0
 | 
					        // special case for word>=0
 | 
				
			||||||
        if(signed) {
 | 
					        if(signed) {
 | 
				
			||||||
            loadAndCmp0MSB(value)
 | 
					            loadAndCmp0MSB(value, false)
 | 
				
			||||||
            if (jump != null)
 | 
					            if (jump != null)
 | 
				
			||||||
                translateJumpElseBodies("bpl", "bmi", jump, stmt.elseScope)
 | 
					                translateJumpElseBodies("bpl", "bmi", jump, stmt.elseScope)
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
@@ -619,7 +646,7 @@ internal class IfElseAsmGen(private val program: PtProgram,
 | 
				
			|||||||
    private fun wordLessZero(value: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
 | 
					    private fun wordLessZero(value: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
 | 
				
			||||||
        // special case for word<0
 | 
					        // special case for word<0
 | 
				
			||||||
        if(signed) {
 | 
					        if(signed) {
 | 
				
			||||||
            loadAndCmp0MSB(value)
 | 
					            loadAndCmp0MSB(value, false)
 | 
				
			||||||
            if (jump != null)
 | 
					            if (jump != null)
 | 
				
			||||||
                translateJumpElseBodies("bmi", "bpl", jump, stmt.elseScope)
 | 
					                translateJumpElseBodies("bmi", "bpl", jump, stmt.elseScope)
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
@@ -894,23 +921,31 @@ _jump                       jmp  (${target.asmLabel})
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun loadAndCmp0MSB(value: PtExpression) {
 | 
					    private fun loadAndCmp0MSB(value: PtExpression, long: Boolean) {
 | 
				
			||||||
        when(value) {
 | 
					        when(value) {
 | 
				
			||||||
            is PtArrayIndexer -> {
 | 
					            is PtArrayIndexer -> {
 | 
				
			||||||
                if(value.variable==null)
 | 
					                if(value.variable==null)
 | 
				
			||||||
                    TODO("support for ptr indexing ${value.position}")
 | 
					                    TODO("support for ptr indexing ${value.position}")
 | 
				
			||||||
                val varname = asmgen.asmVariableName(value.variable!!)
 | 
					                val varname = asmgen.asmVariableName(value.variable!!)
 | 
				
			||||||
                asmgen.loadScaledArrayIndexIntoRegister(value, CpuRegister.Y)
 | 
					                asmgen.loadScaledArrayIndexIntoRegister(value, CpuRegister.Y)
 | 
				
			||||||
                if(value.splitWords)
 | 
					                if(value.splitWords) {
 | 
				
			||||||
 | 
					                    require(!long)
 | 
				
			||||||
                    asmgen.out("  lda  ${varname}_msb,y")
 | 
					                    asmgen.out("  lda  ${varname}_msb,y")
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else if(long)
 | 
				
			||||||
 | 
					                    asmgen.out("  lda  $varname+3,y")
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                    asmgen.out("  lda  $varname+1,y")
 | 
					                    asmgen.out("  lda  $varname+1,y")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            is PtIdentifier -> {
 | 
					            is PtIdentifier -> {
 | 
				
			||||||
                val varname = asmgen.asmVariableName(value)
 | 
					                val varname = asmgen.asmVariableName(value)
 | 
				
			||||||
 | 
					                if(long)
 | 
				
			||||||
 | 
					                    asmgen.out("  lda  $varname+3")
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
                    asmgen.out("  lda  $varname+1")
 | 
					                    asmgen.out("  lda  $varname+1")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            is PtAddressOf -> {
 | 
					            is PtAddressOf -> {
 | 
				
			||||||
 | 
					                require(!long)
 | 
				
			||||||
                if(value.isFromArrayElement) {
 | 
					                if(value.isFromArrayElement) {
 | 
				
			||||||
                    asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true)
 | 
					                    asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true)
 | 
				
			||||||
                    asmgen.out("  cpy  #0")
 | 
					                    asmgen.out("  cpy  #0")
 | 
				
			||||||
@@ -923,6 +958,7 @@ _jump                       jmp  (${target.asmLabel})
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else -> {
 | 
					            else -> {
 | 
				
			||||||
 | 
					                require(!long)
 | 
				
			||||||
                asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true)
 | 
					                asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true)
 | 
				
			||||||
                asmgen.out("  cpy  #0")
 | 
					                asmgen.out("  cpy  #0")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -1226,6 +1262,34 @@ _jump                       jmp  (${target.asmLabel})
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun longEqualsZero(value: PtExpression, notEquals: Boolean, jump: PtJump?, stmt: PtIfElse) {
 | 
				
			||||||
 | 
					        TODO("long == 0")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun longLessZero(value: PtExpression, lessEquals: Boolean, jump: PtJump?, stmt: PtIfElse) {
 | 
				
			||||||
 | 
					        if(lessEquals) {
 | 
				
			||||||
 | 
					            TODO("long <= 0")
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            loadAndCmp0MSB(value, true)
 | 
				
			||||||
 | 
					            if (jump != null)
 | 
				
			||||||
 | 
					                translateJumpElseBodies("bmi", "bpl", jump, stmt.elseScope)
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                translateIfElseBodies("bpl", stmt)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun longGreaterZero(value: PtExpression, lessEquals: Boolean, jump: PtJump?, stmt: PtIfElse) {
 | 
				
			||||||
 | 
					        if(lessEquals) {
 | 
				
			||||||
 | 
					            TODO("long >= 0")
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            loadAndCmp0MSB(value, true)
 | 
				
			||||||
 | 
					            if (jump != null)
 | 
				
			||||||
 | 
					                translateJumpElseBodies("bpl", "bmi", jump, stmt.elseScope)
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                translateIfElseBodies("bmi", stmt)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun wordEqualsZero(value: PtExpression, notEquals: Boolean, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
 | 
					    private fun wordEqualsZero(value: PtExpression, notEquals: Boolean, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // special case for (u)word == 0
 | 
					        // special case for (u)word == 0
 | 
				
			||||||
@@ -1303,6 +1367,16 @@ _jump                       jmp  (${target.asmLabel})
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun longEqualsValue(
 | 
				
			||||||
 | 
					        left: PtExpression,
 | 
				
			||||||
 | 
					        right: PtExpression,
 | 
				
			||||||
 | 
					        notEquals: Boolean,
 | 
				
			||||||
 | 
					        jump: PtJump?,
 | 
				
			||||||
 | 
					        stmt: PtIfElse
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        TODO("long == value")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun wordEqualsValue(
 | 
					    private fun wordEqualsValue(
 | 
				
			||||||
        left: PtExpression,
 | 
					        left: PtExpression,
 | 
				
			||||||
        right: PtExpression,
 | 
					        right: PtExpression,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -377,6 +377,7 @@ internal class ProgramAndVarsGen(
 | 
				
			|||||||
            dt.isSignedByte -> ".char"
 | 
					            dt.isSignedByte -> ".char"
 | 
				
			||||||
            dt.isUnsignedWord || dt.isPointer -> ".word"
 | 
					            dt.isUnsignedWord || dt.isPointer -> ".word"
 | 
				
			||||||
            dt.isSignedWord -> ".sint"
 | 
					            dt.isSignedWord -> ".sint"
 | 
				
			||||||
 | 
					            dt.isLong -> ".dint"
 | 
				
			||||||
            dt.isFloat -> ".byte"
 | 
					            dt.isFloat -> ".byte"
 | 
				
			||||||
            else -> {
 | 
					            else -> {
 | 
				
			||||||
                throw AssemblyError("weird dt")
 | 
					                throw AssemblyError("weird dt")
 | 
				
			||||||
@@ -418,14 +419,7 @@ internal class ProgramAndVarsGen(
 | 
				
			|||||||
            structtype.fields.withIndex().forEach { (index, field) ->
 | 
					            structtype.fields.withIndex().forEach { (index, field) ->
 | 
				
			||||||
                val dt = field.first
 | 
					                val dt = field.first
 | 
				
			||||||
                val varname = "f${index}"
 | 
					                val varname = "f${index}"
 | 
				
			||||||
                val type = when {
 | 
					                val type = asmTypeString(dt)
 | 
				
			||||||
                    dt.isBool || dt.isUnsignedByte -> ".byte"
 | 
					 | 
				
			||||||
                    dt.isSignedByte -> ".char"
 | 
					 | 
				
			||||||
                    dt.isUnsignedWord || dt.isPointer -> ".word"
 | 
					 | 
				
			||||||
                    dt.isSignedWord -> ".sint"
 | 
					 | 
				
			||||||
                    dt.isFloat -> ".byte"   // TODO check that float bytes are passed as an array parameter
 | 
					 | 
				
			||||||
                    else -> throw AssemblyError("weird dt")
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                asmgen.out("p8v_${field.second}  $type  \\$varname")        // note: struct field symbol prefixing done here because that is a lot simpler than fixing up all expressions in the AST
 | 
					                asmgen.out("p8v_${field.second}  $type  \\$varname")        // note: struct field symbol prefixing done here because that is a lot simpler than fixing up all expressions in the AST
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            asmgen.out("    .endstruct\n")
 | 
					            asmgen.out("    .endstruct\n")
 | 
				
			||||||
@@ -781,6 +775,7 @@ internal class ProgramAndVarsGen(
 | 
				
			|||||||
            dt.isSignedByte -> asmgen.out("${variable.name}\t.char  ?")
 | 
					            dt.isSignedByte -> asmgen.out("${variable.name}\t.char  ?")
 | 
				
			||||||
            dt.isUnsignedWord -> asmgen.out("${variable.name}\t.word  ?")
 | 
					            dt.isUnsignedWord -> asmgen.out("${variable.name}\t.word  ?")
 | 
				
			||||||
            dt.isSignedWord -> asmgen.out("${variable.name}\t.sint  ?")
 | 
					            dt.isSignedWord -> asmgen.out("${variable.name}\t.sint  ?")
 | 
				
			||||||
 | 
					            dt.isLong -> asmgen.out("${variable.name}\t.dint  ?")
 | 
				
			||||||
            dt.isFloat -> asmgen.out("${variable.name}\t.fill  ${compTarget.FLOAT_MEM_SIZE}")
 | 
					            dt.isFloat -> asmgen.out("${variable.name}\t.fill  ${compTarget.FLOAT_MEM_SIZE}")
 | 
				
			||||||
            dt.isSplitWordArray -> {
 | 
					            dt.isSplitWordArray -> {
 | 
				
			||||||
                alignVar(variable.align)
 | 
					                alignVar(variable.align)
 | 
				
			||||||
@@ -829,6 +824,7 @@ internal class ProgramAndVarsGen(
 | 
				
			|||||||
//            dt.isSignedByte -> asmgen.out("${variable.name}\t.char  $initialValue")
 | 
					//            dt.isSignedByte -> asmgen.out("${variable.name}\t.char  $initialValue")
 | 
				
			||||||
//            dt.isUnsignedWord -> asmgen.out("${variable.name}\t.word  ${initialValue.toHex()}")
 | 
					//            dt.isUnsignedWord -> asmgen.out("${variable.name}\t.word  ${initialValue.toHex()}")
 | 
				
			||||||
//            dt.isSignedWord -> asmgen.out("${variable.name}\t.sint  $initialValue")
 | 
					//            dt.isSignedWord -> asmgen.out("${variable.name}\t.sint  $initialValue")
 | 
				
			||||||
 | 
					//            dt.isLong -> asmgen.out("${variable.name}\t.dint  $initialValue")
 | 
				
			||||||
//            dt.isFloat -> {
 | 
					//            dt.isFloat -> {
 | 
				
			||||||
//                if(initialValue==0) {
 | 
					//                if(initialValue==0) {
 | 
				
			||||||
//                    asmgen.out("${variable.name}\t.byte  0,0,0,0,0  ; float")
 | 
					//                    asmgen.out("${variable.name}\t.byte  0,0,0,0,0  ; float")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -222,6 +222,7 @@ internal class AssignmentAsmGen(
 | 
				
			|||||||
                    BaseDataType.BOOL -> assignConstantByte(assign.target, if(num==0.0) 0 else 1)
 | 
					                    BaseDataType.BOOL -> assignConstantByte(assign.target, if(num==0.0) 0 else 1)
 | 
				
			||||||
                    BaseDataType.UBYTE, BaseDataType.BYTE -> assignConstantByte(assign.target, num.toInt())
 | 
					                    BaseDataType.UBYTE, BaseDataType.BYTE -> assignConstantByte(assign.target, num.toInt())
 | 
				
			||||||
                    BaseDataType.UWORD, BaseDataType.WORD -> assignConstantWord(assign.target, num.toInt())
 | 
					                    BaseDataType.UWORD, BaseDataType.WORD -> assignConstantWord(assign.target, num.toInt())
 | 
				
			||||||
 | 
					                    BaseDataType.LONG -> assignConstantLong(assign.target, num.toInt())
 | 
				
			||||||
                    BaseDataType.FLOAT -> assignConstantFloat(assign.target, num)
 | 
					                    BaseDataType.FLOAT -> assignConstantFloat(assign.target, num)
 | 
				
			||||||
                    BaseDataType.POINTER -> assignConstantWord(assign.target, num.toInt())
 | 
					                    BaseDataType.POINTER -> assignConstantWord(assign.target, num.toInt())
 | 
				
			||||||
                    else -> throw AssemblyError("weird numval type")
 | 
					                    else -> throw AssemblyError("weird numval type")
 | 
				
			||||||
@@ -244,6 +245,7 @@ internal class AssignmentAsmGen(
 | 
				
			|||||||
                        else
 | 
					                        else
 | 
				
			||||||
                            assignVariableWord(assign.target, variable, assign.source.datatype)
 | 
					                            assignVariableWord(assign.target, variable, assign.source.datatype)
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    targetDt.isLong -> assignVariableLong(assign.target, variable, assign.source.datatype)
 | 
				
			||||||
                    targetDt.isFloat -> assignVariableFloat(assign.target, variable)
 | 
					                    targetDt.isFloat -> assignVariableFloat(assign.target, variable)
 | 
				
			||||||
                    targetDt.isString -> assignVariableString(assign.target, variable)
 | 
					                    targetDt.isString -> assignVariableString(assign.target, variable)
 | 
				
			||||||
                    targetDt.isPointer -> assignVariableWord(assign.target, variable, assign.source.datatype)
 | 
					                    targetDt.isPointer -> assignVariableWord(assign.target, variable, assign.source.datatype)
 | 
				
			||||||
@@ -536,7 +538,7 @@ internal class AssignmentAsmGen(
 | 
				
			|||||||
    private fun assignPrefixExpr(assign: AsmAssignment, value: PtPrefix, scope: IPtSubroutine?) {
 | 
					    private fun assignPrefixExpr(assign: AsmAssignment, value: PtPrefix, scope: IPtSubroutine?) {
 | 
				
			||||||
        if(assign.target.array==null) {
 | 
					        if(assign.target.array==null) {
 | 
				
			||||||
            if(assign.source.datatype isAssignableTo assign.target.datatype || (assign.source.datatype.isBool && assign.target.datatype.isByte)) {
 | 
					            if(assign.source.datatype isAssignableTo assign.target.datatype || (assign.source.datatype.isBool && assign.target.datatype.isByte)) {
 | 
				
			||||||
                if(assign.source.datatype.isIntegerOrBool) {
 | 
					                if(assign.source.datatype.isWordOrByteOrBool) {
 | 
				
			||||||
                    val signed = assign.source.datatype.isSigned
 | 
					                    val signed = assign.source.datatype.isSigned
 | 
				
			||||||
                    if(assign.source.datatype.isByteOrBool) {
 | 
					                    if(assign.source.datatype.isByteOrBool) {
 | 
				
			||||||
                        assignExpressionToRegister(value.value, RegisterOrPair.A, signed)
 | 
					                        assignExpressionToRegister(value.value, RegisterOrPair.A, signed)
 | 
				
			||||||
@@ -2417,8 +2419,8 @@ $endLabel""")
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(targetDt.isInteger && valueDt.isIntegerOrBool && valueDt.isAssignableTo(targetDt)) {
 | 
					        if(targetDt.isInteger && valueDt.isByteOrBool && valueDt.isAssignableTo(targetDt)) {
 | 
				
			||||||
            require(targetDt.isWord && valueDt.isByteOrBool) {
 | 
					            require(targetDt.isWord) {
 | 
				
			||||||
                "should be byte to word assignment ${origTypeCastExpression.position}"
 | 
					                "should be byte to word assignment ${origTypeCastExpression.position}"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            when(target.kind) {
 | 
					            when(target.kind) {
 | 
				
			||||||
@@ -3003,6 +3005,28 @@ $endLabel""")
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun assignVariableLong(target: AsmAssignTarget, varName: String, sourceDt: DataType) {
 | 
				
			||||||
 | 
					        require(sourceDt.isLong)
 | 
				
			||||||
 | 
					        when(target.kind) {
 | 
				
			||||||
 | 
					            TargetStorageKind.VARIABLE -> {
 | 
				
			||||||
 | 
					                asmgen.out("""
 | 
				
			||||||
 | 
					                    lda  $varName
 | 
				
			||||||
 | 
					                    sta  ${target.asmVarname}
 | 
				
			||||||
 | 
					                    lda  $varName+1
 | 
				
			||||||
 | 
					                    sta  ${target.asmVarname}+1
 | 
				
			||||||
 | 
					                    lda  $varName+2
 | 
				
			||||||
 | 
					                    sta  ${target.asmVarname}+2
 | 
				
			||||||
 | 
					                    lda  $varName+3
 | 
				
			||||||
 | 
					                    sta  ${target.asmVarname}+3""")
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            TargetStorageKind.ARRAY -> TODO("assign long to array  ${target.position}")
 | 
				
			||||||
 | 
					            TargetStorageKind.MEMORY -> throw AssemblyError("memory is bytes not long ${target.position}")
 | 
				
			||||||
 | 
					            TargetStorageKind.REGISTER -> TODO("32 bits register assign? (we have no 32 bits registers right now) ${target.position}")
 | 
				
			||||||
 | 
					            TargetStorageKind.POINTER -> throw AssemblyError("can't assign long to pointer, pointers are 16 bits ${target.position}")
 | 
				
			||||||
 | 
					            TargetStorageKind.VOID -> { /* do nothing */ }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun assignVariableWord(target: AsmAssignTarget, varName: String, sourceDt: DataType) {
 | 
					    private fun assignVariableWord(target: AsmAssignTarget, varName: String, sourceDt: DataType) {
 | 
				
			||||||
        if(sourceDt.isSignedByte) {
 | 
					        if(sourceDt.isSignedByte) {
 | 
				
			||||||
            // need to sign extend
 | 
					            // need to sign extend
 | 
				
			||||||
@@ -3929,6 +3953,49 @@ $endLabel""")
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun assignConstantLong(target: AsmAssignTarget, long: Int) {
 | 
				
			||||||
 | 
					        if(long==0 && asmgen.isTargetCpu(CpuType.CPU65C02)) {
 | 
				
			||||||
 | 
					            // optimize setting zero value for this processor
 | 
				
			||||||
 | 
					            when(target.kind) {
 | 
				
			||||||
 | 
					                TargetStorageKind.VARIABLE -> {
 | 
				
			||||||
 | 
					                    asmgen.out("""
 | 
				
			||||||
 | 
					                        stz  ${target.asmVarname}
 | 
				
			||||||
 | 
					                        stz  ${target.asmVarname}+1
 | 
				
			||||||
 | 
					                        stz  ${target.asmVarname}+2
 | 
				
			||||||
 | 
					                        stz  ${target.asmVarname}+3""")
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                TargetStorageKind.ARRAY -> TODO("assign long zero to array ${target.position}")
 | 
				
			||||||
 | 
					                TargetStorageKind.MEMORY -> throw AssemblyError("memory is bytes not long ${target.position}")
 | 
				
			||||||
 | 
					                TargetStorageKind.REGISTER -> TODO("32 bits register assign? (we have no 32 bits registers right now) ${target.position}")
 | 
				
			||||||
 | 
					                TargetStorageKind.POINTER -> throw AssemblyError("can't assign long to pointer, pointers are 16 bits ${target.position}")
 | 
				
			||||||
 | 
					                TargetStorageKind.VOID -> { /* do nothing */ }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        when(target.kind) {
 | 
				
			||||||
 | 
					            TargetStorageKind.VARIABLE -> {
 | 
				
			||||||
 | 
					                fun store(hexbyte: String, offset: Int) {
 | 
				
			||||||
 | 
					                    if(asmgen.isTargetCpu(CpuType.CPU65C02) && hexbyte=="00") {
 | 
				
			||||||
 | 
					                        asmgen.out("  stz  ${target.asmVarname}+$offset")
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        asmgen.out("  lda  #$$hexbyte |  sta  ${target.asmVarname}+$offset")
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                val hex = long.toUInt().toString(16).padStart(8, '0')
 | 
				
			||||||
 | 
					                store(hex.substring(6,8), 0)
 | 
				
			||||||
 | 
					                store(hex.substring(4,6), 1)
 | 
				
			||||||
 | 
					                store(hex.substring(2,4), 2)
 | 
				
			||||||
 | 
					                store(hex.substring(0,2), 3)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            TargetStorageKind.ARRAY -> TODO("assign long $long to array ${target.position}")
 | 
				
			||||||
 | 
					            TargetStorageKind.MEMORY -> throw AssemblyError("memory is bytes not long ${target.position}")
 | 
				
			||||||
 | 
					            TargetStorageKind.REGISTER -> TODO("32 bits register assign? (we have no 32 bits registers right now) ${target.position}")
 | 
				
			||||||
 | 
					            TargetStorageKind.POINTER -> throw AssemblyError("can't assign long to pointer, pointers are 16 bits ${target.position}")
 | 
				
			||||||
 | 
					            TargetStorageKind.VOID -> { /* do nothing */ }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun assignConstantWord(target: AsmAssignTarget, word: Int) {
 | 
					    private fun assignConstantWord(target: AsmAssignTarget, word: Int) {
 | 
				
			||||||
        if(word==0 && asmgen.isTargetCpu(CpuType.CPU65C02)) {
 | 
					        if(word==0 && asmgen.isTargetCpu(CpuType.CPU65C02)) {
 | 
				
			||||||
            // optimize setting zero value for this processor
 | 
					            // optimize setting zero value for this processor
 | 
				
			||||||
@@ -4627,6 +4694,31 @@ $endLabel""")
 | 
				
			|||||||
                    TargetStorageKind.VOID -> { /* do nothing */ }
 | 
					                    TargetStorageKind.VOID -> { /* do nothing */ }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            datatype.isLong -> {
 | 
				
			||||||
 | 
					                when(target.kind) {
 | 
				
			||||||
 | 
					                    TargetStorageKind.VARIABLE -> {
 | 
				
			||||||
 | 
					                        asmgen.out("""
 | 
				
			||||||
 | 
					                            lda  #0
 | 
				
			||||||
 | 
					                            sec
 | 
				
			||||||
 | 
					                            sbc  ${target.asmVarname}
 | 
				
			||||||
 | 
					                            sta  ${target.asmVarname}
 | 
				
			||||||
 | 
					                            lda  #0
 | 
				
			||||||
 | 
					                            sbc  ${target.asmVarname}+1
 | 
				
			||||||
 | 
					                            sta  ${target.asmVarname}+1
 | 
				
			||||||
 | 
					                            lda  #0
 | 
				
			||||||
 | 
					                            sbc  ${target.asmVarname}+2
 | 
				
			||||||
 | 
					                            sta  ${target.asmVarname}+2
 | 
				
			||||||
 | 
					                            lda  #0
 | 
				
			||||||
 | 
					                            sbc  ${target.asmVarname}+3
 | 
				
			||||||
 | 
					                            sta  ${target.asmVarname}+3""")
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    TargetStorageKind.ARRAY -> TODO(" - long array ${target.position}")
 | 
				
			||||||
 | 
					                    TargetStorageKind.MEMORY -> throw AssemblyError("memory is bytes not long ${target.position}")
 | 
				
			||||||
 | 
					                    TargetStorageKind.REGISTER -> TODO("32 bits register assign? (we have no 32 bits registers right now) ${target.position}")
 | 
				
			||||||
 | 
					                    TargetStorageKind.POINTER -> throw AssemblyError("can't assign long to pointer, pointers are 16 bits ${target.position}")
 | 
				
			||||||
 | 
					                    TargetStorageKind.VOID -> { /* do nothing */ }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            datatype.isFloat -> {
 | 
					            datatype.isFloat -> {
 | 
				
			||||||
                when (target.kind) {
 | 
					                when (target.kind) {
 | 
				
			||||||
                    TargetStorageKind.REGISTER -> {
 | 
					                    TargetStorageKind.REGISTER -> {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -106,6 +106,17 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
 | 
				
			|||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    target.datatype.isLong -> {
 | 
				
			||||||
 | 
					                        when(value.kind) {
 | 
				
			||||||
 | 
					                            SourceStorageKind.LITERALBOOLEAN -> inplacemodificationLongWithLiteralval(target.asmVarname, operator, value.boolean!!.asInt())
 | 
				
			||||||
 | 
					                            SourceStorageKind.LITERALNUMBER -> inplacemodificationLongWithLiteralval(target.asmVarname, operator, value.number!!.number.toInt())
 | 
				
			||||||
 | 
					                            SourceStorageKind.VARIABLE -> inplacemodificationLongWithVariable(target.asmVarname, operator, value.asmVarname)
 | 
				
			||||||
 | 
					                            SourceStorageKind.EXPRESSION -> TODO("inplace modify long with expression ${target.position}")
 | 
				
			||||||
 | 
					                            SourceStorageKind.REGISTER -> TODO("32 bits register inplace modification? ${target.position}")
 | 
				
			||||||
 | 
					                            SourceStorageKind.ARRAY -> TODO("inplace modify long with array ${target.position}")
 | 
				
			||||||
 | 
					                            SourceStorageKind.MEMORY -> TODO("memread into long ${target.position}")
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    target.datatype.isFloat -> {
 | 
					                    target.datatype.isFloat -> {
 | 
				
			||||||
                        when(value.kind) {
 | 
					                        when(value.kind) {
 | 
				
			||||||
                            SourceStorageKind.LITERALBOOLEAN -> inplacemodificationFloatWithLiteralval(target.asmVarname, operator, value.boolean!!.asInt().toDouble())
 | 
					                            SourceStorageKind.LITERALBOOLEAN -> inplacemodificationFloatWithLiteralval(target.asmVarname, operator, value.boolean!!.asInt().toDouble())
 | 
				
			||||||
@@ -523,6 +534,132 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun inplacemodificationLongWithVariable(targetVar: String, operator: String, sourceVar: String) {
 | 
				
			||||||
 | 
					        when(operator) {
 | 
				
			||||||
 | 
					            "+" -> {
 | 
				
			||||||
 | 
					                asmgen.out("""
 | 
				
			||||||
 | 
					                    clc
 | 
				
			||||||
 | 
					                    lda  $targetVar
 | 
				
			||||||
 | 
					                    adc  $sourceVar
 | 
				
			||||||
 | 
					                    sta  $targetVar
 | 
				
			||||||
 | 
					                    lda  $targetVar+1
 | 
				
			||||||
 | 
					                    adc  $sourceVar+1
 | 
				
			||||||
 | 
					                    sta  $targetVar+1
 | 
				
			||||||
 | 
					                    lda  $targetVar+2
 | 
				
			||||||
 | 
					                    adc  $sourceVar+2
 | 
				
			||||||
 | 
					                    sta  $targetVar+2
 | 
				
			||||||
 | 
					                    lda  $targetVar+3
 | 
				
			||||||
 | 
					                    adc  $sourceVar+3
 | 
				
			||||||
 | 
					                    sta  $targetVar+3""")
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            "-" -> {
 | 
				
			||||||
 | 
					                asmgen.out("""
 | 
				
			||||||
 | 
					                    sec
 | 
				
			||||||
 | 
					                    lda  $targetVar
 | 
				
			||||||
 | 
					                    sbc  $sourceVar
 | 
				
			||||||
 | 
					                    sta  $targetVar
 | 
				
			||||||
 | 
					                    lda  $targetVar+1
 | 
				
			||||||
 | 
					                    sbc  $sourceVar+1
 | 
				
			||||||
 | 
					                    sta  $targetVar+1
 | 
				
			||||||
 | 
					                    lda  $targetVar+2
 | 
				
			||||||
 | 
					                    sbc  $sourceVar+2
 | 
				
			||||||
 | 
					                    sta  $targetVar+2
 | 
				
			||||||
 | 
					                    lda  $targetVar+3
 | 
				
			||||||
 | 
					                    sbc  $sourceVar+3
 | 
				
			||||||
 | 
					                    sta  $targetVar+3""")
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else -> {
 | 
				
			||||||
 | 
					                TODO("Not yet implemented")
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun inplacemodificationLongWithLiteralval(variable: String, operator: String, value: Int) {
 | 
				
			||||||
 | 
					        when(operator) {
 | 
				
			||||||
 | 
					            "+" -> {
 | 
				
			||||||
 | 
					                when(value) {
 | 
				
			||||||
 | 
					                    0 -> {}
 | 
				
			||||||
 | 
					                    1 -> {
 | 
				
			||||||
 | 
					                        asmgen.out("""
 | 
				
			||||||
 | 
					                            inc  $variable
 | 
				
			||||||
 | 
					                            bne  +
 | 
				
			||||||
 | 
					                            inc  $variable+1
 | 
				
			||||||
 | 
					                            bne  +
 | 
				
			||||||
 | 
					                            inc  $variable+2
 | 
				
			||||||
 | 
					                            bne  +
 | 
				
			||||||
 | 
					                            inc  $variable+3
 | 
				
			||||||
 | 
					+""")
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else -> {
 | 
				
			||||||
 | 
					                        if(value in 1..255) {
 | 
				
			||||||
 | 
					                            TODO("optimized inplace long += $value")
 | 
				
			||||||
 | 
					                        } else if(value in 1..65535) {
 | 
				
			||||||
 | 
					                            TODO("optimized inplace long += $value")
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
 | 
					                            val hex = value.toUInt().toString(16).padStart(8, '0')
 | 
				
			||||||
 | 
					                            asmgen.out("""
 | 
				
			||||||
 | 
					                                clc
 | 
				
			||||||
 | 
					                                lda  $variable
 | 
				
			||||||
 | 
					                                adc  #$${hex.substring(6,8)}
 | 
				
			||||||
 | 
					                                sta  $variable
 | 
				
			||||||
 | 
					                                lda  $variable+1
 | 
				
			||||||
 | 
					                                adc  #$${hex.substring(4, 6)}
 | 
				
			||||||
 | 
					                                sta  $variable+1
 | 
				
			||||||
 | 
					                                lda  $variable+2
 | 
				
			||||||
 | 
					                                adc  #$${hex.substring(2, 4)}
 | 
				
			||||||
 | 
					                                sta  $variable+2
 | 
				
			||||||
 | 
					                                lda  $variable+3
 | 
				
			||||||
 | 
					                                adc  #$${hex.take(2)}
 | 
				
			||||||
 | 
					                                sta  $variable+3""")
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            "-" -> {
 | 
				
			||||||
 | 
					                when(value) {
 | 
				
			||||||
 | 
					                    0 -> {}
 | 
				
			||||||
 | 
					                    1 -> {
 | 
				
			||||||
 | 
					                        asmgen.out("""
 | 
				
			||||||
 | 
					                            lda  $variable
 | 
				
			||||||
 | 
					                            bne  +
 | 
				
			||||||
 | 
					                            dec  $variable+1
 | 
				
			||||||
 | 
					                            bne  +
 | 
				
			||||||
 | 
					                            dec  $variable+2
 | 
				
			||||||
 | 
					                            bne  +
 | 
				
			||||||
 | 
					                            dec  $variable+3
 | 
				
			||||||
 | 
					+                           dec  $variable""")
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else -> {
 | 
				
			||||||
 | 
					                        if(value in 1..255) {
 | 
				
			||||||
 | 
					                            TODO("optimized inplace long += $value")
 | 
				
			||||||
 | 
					                        } else if(value in 1..65535) {
 | 
				
			||||||
 | 
					                            TODO("optimized inplace long += $value")
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
 | 
					                            val hex = value.toUInt().toString(16).padStart(8, '0')
 | 
				
			||||||
 | 
					                            asmgen.out("""
 | 
				
			||||||
 | 
					                                sec
 | 
				
			||||||
 | 
					                                lda  $variable
 | 
				
			||||||
 | 
					                                sbc  #$${hex.substring(6,8)}
 | 
				
			||||||
 | 
					                                sta  $variable
 | 
				
			||||||
 | 
					                                lda  $variable+1
 | 
				
			||||||
 | 
					                                sbc  #$${hex.substring(4, 6)}
 | 
				
			||||||
 | 
					                                sta  $variable+1
 | 
				
			||||||
 | 
					                                lda  $variable+2
 | 
				
			||||||
 | 
					                                sbc  #$${hex.substring(2, 4)}
 | 
				
			||||||
 | 
					                                sta  $variable+2
 | 
				
			||||||
 | 
					                                lda  $variable+3
 | 
				
			||||||
 | 
					                                sbc  #$${hex.take(2)}
 | 
				
			||||||
 | 
					                                sta  $variable+3""")
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else -> {
 | 
				
			||||||
 | 
					                TODO("inplace long $operator $value")
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun tryIndexedIncDec(array: PtArrayIndexer, operator: String): Boolean {
 | 
					    private fun tryIndexedIncDec(array: PtArrayIndexer, operator: String): Boolean {
 | 
				
			||||||
        val arrayVar = array.variable
 | 
					        val arrayVar = array.variable
 | 
				
			||||||
        if(arrayVar==null) {
 | 
					        if(arrayVar==null) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,12 +12,14 @@ internal object DummyMemsizer : IMemSizer {
 | 
				
			|||||||
            return when(dt.sub) {
 | 
					            return when(dt.sub) {
 | 
				
			||||||
                BaseDataType.BOOL, BaseDataType.BYTE, BaseDataType.UBYTE -> numElements
 | 
					                BaseDataType.BOOL, BaseDataType.BYTE, BaseDataType.UBYTE -> numElements
 | 
				
			||||||
                BaseDataType.UWORD, BaseDataType.WORD -> numElements*2
 | 
					                BaseDataType.UWORD, BaseDataType.WORD -> numElements*2
 | 
				
			||||||
 | 
					                BaseDataType.LONG -> numElements*4
 | 
				
			||||||
                BaseDataType.FLOAT -> numElements*5
 | 
					                BaseDataType.FLOAT -> numElements*5
 | 
				
			||||||
                else -> throw IllegalArgumentException("invalid sub type")
 | 
					                else -> throw IllegalArgumentException("invalid sub type")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return when {
 | 
					        return when {
 | 
				
			||||||
            dt.isByteOrBool -> 1 * (numElements ?: 1)
 | 
					            dt.isByteOrBool -> 1 * (numElements ?: 1)
 | 
				
			||||||
 | 
					            dt.isLong -> 4 * (numElements ?: 1)
 | 
				
			||||||
            dt.isFloat -> 5 * (numElements ?: 1)
 | 
					            dt.isFloat -> 5 * (numElements ?: 1)
 | 
				
			||||||
            else -> 2 * (numElements ?: 1)
 | 
					            else -> 2 * (numElements ?: 1)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -446,7 +446,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
 | 
				
			|||||||
                else (it as PtNumber).number.toInt()
 | 
					                else (it as PtNumber).number.toInt()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            when {
 | 
					            when {
 | 
				
			||||||
                elementDt.isIntegerOrBool -> {
 | 
					                elementDt.isWordOrByteOrBool -> {
 | 
				
			||||||
                    if (elementDt.isByteOrBool) require(haystack.size in 0..PtContainmentCheck.MAX_SIZE_FOR_INLINE_CHECKS_BYTE)
 | 
					                    if (elementDt.isByteOrBool) require(haystack.size in 0..PtContainmentCheck.MAX_SIZE_FOR_INLINE_CHECKS_BYTE)
 | 
				
			||||||
                    if (elementDt.isWord) require(haystack.size in 0..PtContainmentCheck.MAX_SIZE_FOR_INLINE_CHECKS_WORD)
 | 
					                    if (elementDt.isWord) require(haystack.size in 0..PtContainmentCheck.MAX_SIZE_FOR_INLINE_CHECKS_WORD)
 | 
				
			||||||
                    val gottemLabel = codeGen.createLabelName()
 | 
					                    val gottemLabel = codeGen.createLabelName()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,12 +10,14 @@ internal object DummyMemsizer : IMemSizer {
 | 
				
			|||||||
            return when(dt.sub) {
 | 
					            return when(dt.sub) {
 | 
				
			||||||
                BaseDataType.BOOL, BaseDataType.BYTE, BaseDataType.UBYTE -> numElements
 | 
					                BaseDataType.BOOL, BaseDataType.BYTE, BaseDataType.UBYTE -> numElements
 | 
				
			||||||
                BaseDataType.UWORD, BaseDataType.WORD -> numElements*2
 | 
					                BaseDataType.UWORD, BaseDataType.WORD -> numElements*2
 | 
				
			||||||
 | 
					                BaseDataType.LONG -> numElements*4
 | 
				
			||||||
                BaseDataType.FLOAT -> numElements*5
 | 
					                BaseDataType.FLOAT -> numElements*5
 | 
				
			||||||
                else -> throw IllegalArgumentException("invalid sub type")
 | 
					                else -> throw IllegalArgumentException("invalid sub type")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return when {
 | 
					        return when {
 | 
				
			||||||
            dt.isByteOrBool -> 1 * (numElements ?: 1)
 | 
					            dt.isByteOrBool -> 1 * (numElements ?: 1)
 | 
				
			||||||
 | 
					            dt.isLong -> 4 * (numElements ?: 1)
 | 
				
			||||||
            dt.isFloat -> 5 * (numElements ?: 1)
 | 
					            dt.isFloat -> 5 * (numElements ?: 1)
 | 
				
			||||||
            else -> 2 * (numElements ?: 1)
 | 
					            else -> 2 * (numElements ?: 1)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -228,22 +228,85 @@ asmsub  str_w  (word value @ AY) clobbers(X) -> str @AY  {
 | 
				
			|||||||
	}}
 | 
						}}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
asmsub  str_l  (uword msw @ R0, uword lsw @ R1) clobbers(X) -> str @AY  {
 | 
					sub  str_l  (long value) -> str  {
 | 
				
			||||||
	; ---- convert the long in R0:R1 into decimal string form, without left padding 0s
 | 
						; ---- convert the long value into decimal string form, without left padding 0s
 | 
				
			||||||
 | 
					        ; source: https://codebase64.net/doku.php?id=base:32_bit_hexadecimal_to_decimal_conversion
 | 
				
			||||||
 | 
					        bool negative
 | 
				
			||||||
 | 
					        if value<0 {
 | 
				
			||||||
 | 
					            negative = true
 | 
				
			||||||
 | 
					            value = -value
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        %asm {{
 | 
					        %asm {{
 | 
				
			||||||
	    lda  #'?'
 | 
					        jsr hex2dec
 | 
				
			||||||
	    sta  string_out
 | 
					
 | 
				
			||||||
	    lda  #'?'
 | 
					        ldx  #0
 | 
				
			||||||
	    sta  string_out+1
 | 
					-       lda  result,x
 | 
				
			||||||
 | 
					        bne  +
 | 
				
			||||||
 | 
					        inx             ; skip leading zeros
 | 
				
			||||||
 | 
					        cpx  #9
 | 
				
			||||||
 | 
					        bne  -
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ; convert to petscii numbers and return ptr to first nonzero
 | 
				
			||||||
 | 
					+       stx  P8ZP_SCRATCH_B1
 | 
				
			||||||
 | 
					        inc  P8ZP_SCRATCH_B1
 | 
				
			||||||
 | 
					-       lda  result,x
 | 
				
			||||||
 | 
					        ora  #$30
 | 
				
			||||||
 | 
					        sta  result,x
 | 
				
			||||||
 | 
					        inx
 | 
				
			||||||
 | 
					        cpx  #10
 | 
				
			||||||
 | 
					        bne  -
 | 
				
			||||||
        lda  #0
 | 
					        lda  #0
 | 
				
			||||||
	    sta  string_out+2
 | 
					        sta  result,x
 | 
				
			||||||
	    ; TODO implement this!
 | 
					        ; sign needed?
 | 
				
			||||||
	    sta  string_out
 | 
					        lda  negative
 | 
				
			||||||
	    lda  #<string_out
 | 
					        beq  +
 | 
				
			||||||
	    ldy  #>string_out
 | 
					        dec  P8ZP_SCRATCH_B1
 | 
				
			||||||
 | 
					        ldx  P8ZP_SCRATCH_B1
 | 
				
			||||||
 | 
					        lda  #'-'
 | 
				
			||||||
 | 
					        sta  result_sign,x
 | 
				
			||||||
 | 
					+       lda  #<result_sign
 | 
				
			||||||
 | 
					        ldy  #>result_sign
 | 
				
			||||||
 | 
					        clc
 | 
				
			||||||
 | 
					        adc  P8ZP_SCRATCH_B1
 | 
				
			||||||
 | 
					        bcc  +
 | 
				
			||||||
 | 
					        iny
 | 
				
			||||||
 | 
					+       rts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ; converts 10 digits (32 bit values have max. 10 decimal digits)
 | 
				
			||||||
 | 
					hex2dec
 | 
				
			||||||
 | 
					        ldx  #9
 | 
				
			||||||
 | 
					l3      jsr  div10
 | 
				
			||||||
 | 
					        sta  result,x
 | 
				
			||||||
 | 
					        dex
 | 
				
			||||||
 | 
					        bpl  l3
 | 
				
			||||||
        rts
 | 
					        rts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ; divides a 32 bit value by 10
 | 
				
			||||||
 | 
					        ; remainder is returned in akku
 | 
				
			||||||
 | 
					div10
 | 
				
			||||||
 | 
					        ldy  #32         ; 32 bits
 | 
				
			||||||
 | 
					        lda  #0
 | 
				
			||||||
 | 
					        clc
 | 
				
			||||||
 | 
					l4      rol
 | 
				
			||||||
 | 
					        cmp  #10
 | 
				
			||||||
 | 
					        bcc  skip
 | 
				
			||||||
 | 
					        sbc  #10
 | 
				
			||||||
 | 
					skip    rol  value
 | 
				
			||||||
 | 
					        rol  value+1
 | 
				
			||||||
 | 
					        rol  value+2
 | 
				
			||||||
 | 
					        rol  value+3
 | 
				
			||||||
 | 
					        dey
 | 
				
			||||||
 | 
					        bpl  l4
 | 
				
			||||||
 | 
					        rts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .section BSS
 | 
				
			||||||
 | 
					result_sign  .byte  ?   ; room for the '-' sign
 | 
				
			||||||
 | 
					result  .fill  10
 | 
				
			||||||
 | 
					        .byte  ?        ; string 0 terminator
 | 
				
			||||||
 | 
					    .send
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }}
 | 
					        }}
 | 
				
			||||||
}
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; ---- string conversion to numbers -----
 | 
					; ---- string conversion to numbers -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -165,9 +165,9 @@ _allzero    lda  #'0'
 | 
				
			|||||||
        }}
 | 
					        }}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sub  print_l (long value)   {
 | 
					    sub print_l(long value) {
 | 
				
			||||||
        ; ---- print the (signed) long in decimal form, without left padding 0's
 | 
					        ; prints a 32 bit value to the screen
 | 
				
			||||||
        print(conv.str_l(msw(value), lsw(value)))
 | 
					        print(conv.str_l(value))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    asmsub  input_chars  (^^ubyte buffer @ AY) clobbers(A) -> ubyte @ Y  {
 | 
					    asmsub  input_chars  (^^ubyte buffer @ AY) clobbers(A) -> ubyte @ Y  {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -269,7 +269,7 @@ class AstPreprocessor(val program: Program,
 | 
				
			|||||||
                        .filter { it.name !in namesInSub && it.name !in existingAliases }
 | 
					                        .filter { it.name !in namesInSub && it.name !in existingAliases }
 | 
				
			||||||
                        .forEach {
 | 
					                        .forEach {
 | 
				
			||||||
                            if (it.registerOrPair in Cx16VirtualRegisters) {
 | 
					                            if (it.registerOrPair in Cx16VirtualRegisters) {
 | 
				
			||||||
                                if(it.type.isIntegerOrBool) {
 | 
					                                if(it.type.isWordOrByteOrBool) {
 | 
				
			||||||
                                    val mappedParamVar = VarDecl.fromParameter(it)
 | 
					                                    val mappedParamVar = VarDecl.fromParameter(it)
 | 
				
			||||||
                                    mods += IAstModification.InsertFirst(mappedParamVar, subroutine)
 | 
					                                    mods += IAstModification.InsertFirst(mappedParamVar, subroutine)
 | 
				
			||||||
                                } else {
 | 
					                                } else {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,12 +28,14 @@ internal object DummyMemsizer : IMemSizer {
 | 
				
			|||||||
            return when(dt.sub) {
 | 
					            return when(dt.sub) {
 | 
				
			||||||
                BaseDataType.BOOL, BaseDataType.BYTE, BaseDataType.UBYTE -> numElements
 | 
					                BaseDataType.BOOL, BaseDataType.BYTE, BaseDataType.UBYTE -> numElements
 | 
				
			||||||
                BaseDataType.UWORD, BaseDataType.WORD -> numElements*2
 | 
					                BaseDataType.UWORD, BaseDataType.WORD -> numElements*2
 | 
				
			||||||
 | 
					                BaseDataType.LONG -> numElements*4
 | 
				
			||||||
                BaseDataType.FLOAT -> numElements*5
 | 
					                BaseDataType.FLOAT -> numElements*5
 | 
				
			||||||
                else -> throw IllegalArgumentException("invalid sub type")
 | 
					                else -> throw IllegalArgumentException("invalid sub type")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return when {
 | 
					        return when {
 | 
				
			||||||
            dt.isByteOrBool -> 1 * (numElements ?: 1)
 | 
					            dt.isByteOrBool -> 1 * (numElements ?: 1)
 | 
				
			||||||
 | 
					            dt.isLong -> 4 * (numElements ?: 1)
 | 
				
			||||||
            dt.isFloat -> 5 * (numElements ?: 1)
 | 
					            dt.isFloat -> 5 * (numElements ?: 1)
 | 
				
			||||||
            else -> 2 * (numElements ?: 1)
 | 
					            else -> 2 * (numElements ?: 1)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,39 +1,76 @@
 | 
				
			|||||||
%import textio
 | 
					%import textio
 | 
				
			||||||
 | 
					%zeropage basicsafe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
main {
 | 
					main {
 | 
				
			||||||
    long bignum = 12345678
 | 
					    long bignum = 12345678
 | 
				
			||||||
    long bignum2 = -999999
 | 
					    long bignum2 = -999999
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct Node {
 | 
					;    struct Node {
 | 
				
			||||||
        ubyte id
 | 
					;        ubyte id
 | 
				
			||||||
        str name
 | 
					;        str name
 | 
				
			||||||
        long array
 | 
					;        long array
 | 
				
			||||||
        bool flag
 | 
					;        bool flag
 | 
				
			||||||
        long counter
 | 
					;        long counter
 | 
				
			||||||
    }
 | 
					;    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sub start() {
 | 
					    sub start() {
 | 
				
			||||||
        ^^Node test = []
 | 
					        txt.print_l(-1999888777)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        bignum++
 | 
					 | 
				
			||||||
        bignum2--
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        txt.print_l(bignum)
 | 
					 | 
				
			||||||
        txt.spc()
 | 
					        txt.spc()
 | 
				
			||||||
 | 
					        txt.print_l(-999)
 | 
				
			||||||
 | 
					        txt.spc()
 | 
				
			||||||
 | 
					        txt.print_l(-42)
 | 
				
			||||||
 | 
					        txt.spc()
 | 
				
			||||||
 | 
					        txt.print_l(0)
 | 
				
			||||||
 | 
					        txt.spc()
 | 
				
			||||||
 | 
					        txt.print_l(bignum)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					        txt.print_l(bignum2)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					        txt.print_l(-bignum2)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					        bignum2 = -bignum2
 | 
				
			||||||
 | 
					        bignum2++
 | 
				
			||||||
 | 
					        bignum2++
 | 
				
			||||||
 | 
					        txt.print_l(bignum2)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					        bignum2--
 | 
				
			||||||
 | 
					        bignum2--
 | 
				
			||||||
 | 
					        txt.print_l(bignum2)
 | 
				
			||||||
 | 
					        txt.spc()
 | 
				
			||||||
 | 
					        txt.print_l(bignum)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					        bignum2 += bignum
 | 
				
			||||||
 | 
					        txt.print_l(bignum2)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					        bignum2 -= bignum
 | 
				
			||||||
        txt.print_l(bignum2)
 | 
					        txt.print_l(bignum2)
 | 
				
			||||||
        txt.nl()
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        str output = "...................."
 | 
					;        ^^Node test = []
 | 
				
			||||||
        txt.print(conv.str_l(bignum))
 | 
					;
 | 
				
			||||||
        txt.nl()
 | 
					;        bignum++
 | 
				
			||||||
 | 
					;        bignum2--
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bignum = 999999
 | 
					;        txt.print_l(bignum)
 | 
				
			||||||
        bignum--                        ; TODO this works in the current VM...
 | 
					;        txt.spc()
 | 
				
			||||||
        bignum = -888888
 | 
					;        txt.print_l(bignum2)
 | 
				
			||||||
 | 
					;        txt.nl()
 | 
				
			||||||
        test.counter = 0
 | 
					;
 | 
				
			||||||
        test.counter ++                 ; TODO ... why doesn't this? (requires plusMinusMultAnyLong routine)
 | 
					;        str output = "...................."
 | 
				
			||||||
        test.counter = bignum2
 | 
					;        txt.print_l(bignum)
 | 
				
			||||||
        test.counter --
 | 
					;        txt.spc()
 | 
				
			||||||
 | 
					;        txt.print(conv.str_l(bignum))
 | 
				
			||||||
 | 
					;        txt.nl()
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					;        bignum = 999999
 | 
				
			||||||
 | 
					;        bignum--                        ; TODO this works in the current VM...
 | 
				
			||||||
 | 
					;        bignum = -888888
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					;        test.counter = 0
 | 
				
			||||||
 | 
					;        test.counter ++                 ; TODO ... why doesn't this? (requires plusMinusMultAnyLong routine)
 | 
				
			||||||
 | 
					;        test.counter = bignum2
 | 
				
			||||||
 | 
					;        test.counter --
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,7 +41,7 @@ sealed interface IPtSubroutine {
 | 
				
			|||||||
                        val others = returns.drop(1).map { type ->
 | 
					                        val others = returns.drop(1).map { type ->
 | 
				
			||||||
                            when {
 | 
					                            when {
 | 
				
			||||||
                                type.isFloat -> RegisterOrStatusflag(availableFloatRegisters.removeLastOrNull()!!, null) to type
 | 
					                                type.isFloat -> RegisterOrStatusflag(availableFloatRegisters.removeLastOrNull()!!, null) to type
 | 
				
			||||||
                                type.isIntegerOrBool -> RegisterOrStatusflag(availableIntegerRegisters.removeLastOrNull()!!, null) to type
 | 
					                                type.isWordOrByteOrBool -> RegisterOrStatusflag(availableIntegerRegisters.removeLastOrNull()!!, null) to type
 | 
				
			||||||
                                else -> throw AssemblyError("unsupported return type $type")
 | 
					                                else -> throw AssemblyError("unsupported return type $type")
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2942,7 +2942,17 @@ class VirtualMachine(irProgram: IRProgram) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun plusMinusMultAnyLongInplace(operator: String, reg1: Int, address: Int) {
 | 
					    private fun plusMinusMultAnyLongInplace(operator: String, reg1: Int, address: Int) {
 | 
				
			||||||
        TODO("Not yet implemented")
 | 
					        val memvalue = memory.getSL(address)
 | 
				
			||||||
 | 
					        val operand = registers.getSL(reg1)
 | 
				
			||||||
 | 
					        val result: Int
 | 
				
			||||||
 | 
					        when(operator) {
 | 
				
			||||||
 | 
					            "+" -> result = memvalue + operand
 | 
				
			||||||
 | 
					            "-" -> result = memvalue - operand
 | 
				
			||||||
 | 
					            "*" -> result = memvalue * operand
 | 
				
			||||||
 | 
					            else -> throw IllegalArgumentException("operator word $operator")
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        memory.setSL(address, result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun plusMinusMultAnyLongSigned(operator: String, reg1: Int, reg2: Int) {
 | 
					    private fun plusMinusMultAnyLongSigned(operator: String, reg1: Int, reg2: Int) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user