diff --git a/codeGeneration/src/prog8/compiler/target/c64/C64MachineDefinition.kt b/codeGeneration/src/prog8/compiler/target/c64/C64MachineDefinition.kt index d5aebc664..00df2a552 100644 --- a/codeGeneration/src/prog8/compiler/target/c64/C64MachineDefinition.kt +++ b/codeGeneration/src/prog8/compiler/target/c64/C64MachineDefinition.kt @@ -89,7 +89,7 @@ object C64MachineDefinition: IMachineDefinition { if (options.zeropage == ZeropageType.FULL) { free.addAll(0x04..0xf9) free.add(0xff) - free.removeAll(listOf(0xa0, 0xa1, 0xa2, 0x91, 0xc0, 0xc5, 0xcb, 0xf5, 0xf6)) // these are updated by IRQ + free.removeAll(setOf(0xa0, 0xa1, 0xa2, 0x91, 0xc0, 0xc5, 0xcb, 0xf5, 0xf6)) // these are updated by IRQ } else { if (options.zeropage == ZeropageType.KERNALSAFE || options.zeropage == ZeropageType.FLOATSAFE) { free.addAll(listOf( @@ -111,7 +111,7 @@ object C64MachineDefinition: IMachineDefinition { if (options.zeropage == ZeropageType.FLOATSAFE) { // remove the zeropage locations used for floating point operations from the free list - free.removeAll(listOf( + free.removeAll(setOf( 0x22, 0x23, 0x24, 0x25, 0x10, 0x11, 0x12, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt index 17590cbdb..687f9cc61 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt @@ -523,14 +523,14 @@ class AsmGen(private val program: Program, return if (targetScope !== identScope) { val scopedName = getScopedSymbolNameForTarget(identifier.nameInSource.last(), target) if (target is Label) { - // make labels locally scoped in the asm. Is slightly problematic, see github issue #62 + // make labels locally scoped in the asm. Is slightly problematic, see GitHub issue #62 val last = scopedName.removeLast() scopedName.add("_$last") } fixNameSymbols(scopedName.joinToString(".")) } else { if (target is Label) { - // make labels locally scoped in the asm. Is slightly problematic, see github issue #62 + // make labels locally scoped in the asm. Is slightly problematic, see GitHub issue #62 val scopedName = identifier.nameInSource.toMutableList() val last = scopedName.removeLast() scopedName.add("_$last") @@ -1283,7 +1283,7 @@ $repeatLabel lda $counterVar } private fun translate(stmt: Label) { - // underscore prefix to make sure it's a local label. Is slightly problematic, see github issue #62 + // underscore prefix to make sure it's a local label. Is slightly problematic, see GitHub issue #62 out("_${stmt.name}") } @@ -1401,7 +1401,7 @@ $label nop""") } } - internal fun translate(ret: Return, withRts: Boolean=true) { + private fun translate(ret: Return, withRts: Boolean=true) { ret.value?.let { returnvalue -> val sub = ret.definingSubroutine!! val returnType = sub.returntypes.single() @@ -1611,7 +1611,7 @@ $label nop""") } } - if (rightConstVal!=null && rightConstVal.number.toDouble() == 0.0) + if (rightConstVal!=null && rightConstVal.number == 0.0) jumpIfZeroOrNot(left, operator, jumpIfFalseLabel) else jumpIfComparison(left, operator, right, jumpIfFalseLabel, leftConstVal, rightConstVal) @@ -1791,7 +1791,7 @@ $label nop""") } else if(left is IdentifierReference && rightConstVal!=null) { val leftName = asmVariableName(left) - val rightName = getFloatAsmConst(rightConstVal.number.toDouble()) + val rightName = getFloatAsmConst(rightConstVal.number) out(""" lda #<$rightName ldy #>$rightName @@ -1836,7 +1836,7 @@ $label nop""") } else if(left is IdentifierReference && rightConstVal!=null) { val leftName = asmVariableName(left) - val rightName = getFloatAsmConst(rightConstVal.number.toDouble()) + val rightName = getFloatAsmConst(rightConstVal.number) out(""" lda #<$rightName ldy #>$rightName @@ -1878,7 +1878,7 @@ $label nop""") } else if(left is IdentifierReference && rightConstVal!=null) { val leftName = asmVariableName(left) - val rightName = getFloatAsmConst(rightConstVal.number.toDouble()) + val rightName = getFloatAsmConst(rightConstVal.number) out(""" lda #<$leftName ldy #>$leftName @@ -1923,7 +1923,7 @@ $label nop""") } else if(left is IdentifierReference && rightConstVal!=null) { val leftName = asmVariableName(left) - val rightName = getFloatAsmConst(rightConstVal.number.toDouble()) + val rightName = getFloatAsmConst(rightConstVal.number) out(""" lda #<$leftName ldy #>$leftName @@ -2821,7 +2821,7 @@ $label nop""") } else { if (left is IdentifierReference) { val name = asmVariableName(left) - when(rightConstVal.number.toDouble()) + when(rightConstVal.number) { 0.0 -> { out(""" @@ -2860,7 +2860,7 @@ $label nop""") } else if(left is IdentifierReference && rightConstVal!=null) { val leftName = asmVariableName(left) - val rightName = getFloatAsmConst(rightConstVal.number.toDouble()) + val rightName = getFloatAsmConst(rightConstVal.number) out(""" lda #<$leftName ldy #>$leftName @@ -2905,7 +2905,7 @@ $label nop""") } else { if (left is IdentifierReference) { val name = asmVariableName(left) - when(rightConstVal.number.toDouble()) + when(rightConstVal.number) { 0.0 -> { out(""" @@ -2945,7 +2945,7 @@ $label nop""") } else if(left is IdentifierReference && rightConstVal!=null) { val leftName = asmVariableName(left) - val rightName = getFloatAsmConst(rightConstVal.number.toDouble()) + val rightName = getFloatAsmConst(rightConstVal.number) out(""" lda #<$leftName ldy #>$leftName diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt index fe387306f..86f2afe9e 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt @@ -89,7 +89,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val throw AssemblyError("callfar done on bank 0 which is reserved for the kernal") val argAddrArg = fcall.args[2] - if(argAddrArg.constValue(program)?.number == 0) { + if(argAddrArg.constValue(program)?.number == 0.0) { asmgen.out(""" jsr cx16.jsrfar .word ${address.toHex()} @@ -134,7 +134,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val throw AssemblyError("callrom bank must be <32") val argAddrArg = fcall.args[2] - if(argAddrArg.constValue(program)?.number == 0) { + if(argAddrArg.constValue(program)?.number == 0.0) { asmgen.out(""" lda $01 pha diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt index 31a530466..bd9434ec1 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt @@ -220,7 +220,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge dex """) DataType.FLOAT -> { - val floatConst = asmgen.getFloatAsmConst(expr.number.toDouble()) + val floatConst = asmgen.getFloatAsmConst(expr.number) asmgen.out(" lda #<$floatConst | ldy #>$floatConst | jsr floats.push_float") } else -> throw AssemblyError("weird type") diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/ForLoopsAsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/ForLoopsAsmGen.kt index e3b1f150a..5e6334306 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/ForLoopsAsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/ForLoopsAsmGen.kt @@ -43,7 +43,7 @@ internal class ForLoopsAsmGen(private val program: Program, private val asmgen: val stepsize=range.step.constValue(program)!!.number.toInt() if(stepsize < -1) { - val limit = range.to.constValue(program)?.number?.toDouble() + val limit = range.to.constValue(program)?.number if(limit==0.0) throw AssemblyError("for unsigned loop variable it's not possible to count down with step != -1 from a non-const value to exactly zero due to value wrapping") } diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt index ba8ec5587..b04e2013f 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt @@ -40,9 +40,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen // simple case: assign a constant number val num = assign.source.number!!.number when (assign.target.datatype) { - DataType.UBYTE, DataType.BYTE -> assignConstantByte(assign.target, num.toShort()) + DataType.UBYTE, DataType.BYTE -> assignConstantByte(assign.target, num.toInt().toShort()) DataType.UWORD, DataType.WORD -> assignConstantWord(assign.target, num.toInt()) - DataType.FLOAT -> assignConstantFloat(assign.target, num.toDouble()) + DataType.FLOAT -> assignConstantFloat(assign.target, num) else -> throw AssemblyError("weird numval type") } } diff --git a/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt b/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt index 73669273f..9270b1116 100644 --- a/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt +++ b/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt @@ -73,8 +73,7 @@ X = BinExpr X = LeftExpr // we can see if we can unwrap the binary expression by working on a new temporary variable // (that has the type of the expression), and then finally doing the typecast. // Once it's outside the typecast, the regular splitting can commence. - val tempDt = origExpr.inferType(program).getOr(DataType.UNDEFINED) - val tempVar = when(tempDt) { + val tempVar = when(val tempDt = origExpr.inferType(program).getOr(DataType.UNDEFINED)) { DataType.UBYTE -> listOf("prog8_lib", "retval_interm_ub") DataType.BYTE -> listOf("prog8_lib", "retval_interm_b") DataType.UWORD -> listOf("prog8_lib", "retval_interm_uw") diff --git a/codeOptimizers/src/prog8/optimizer/ConstExprEvaluator.kt b/codeOptimizers/src/prog8/optimizer/ConstExprEvaluator.kt index 8ed3e6b52..999aa4260 100644 --- a/codeOptimizers/src/prog8/optimizer/ConstExprEvaluator.kt +++ b/codeOptimizers/src/prog8/optimizer/ConstExprEvaluator.kt @@ -46,14 +46,14 @@ class ConstExprEvaluator { left.number.toInt().ushr(amount.number.toInt()) else left.number.toInt().shr(amount.number.toInt()) - return NumericLiteralValue(left.type, result, left.position) + return NumericLiteralValue(left.type, result.toDouble(), left.position) } private fun shiftedleft(left: NumericLiteralValue, amount: NumericLiteralValue): Expression { if(left.type !in IntegerDatatypes || amount.type !in IntegerDatatypes) throw ExpressionError("cannot compute $left << $amount", left.position) val result = left.number.toInt().shl(amount.number.toInt()) - return NumericLiteralValue(left.type, result, left.position) + return NumericLiteralValue(left.type, result.toDouble(), left.position) } private fun logicalxor(left: NumericLiteralValue, right: NumericLiteralValue): NumericLiteralValue { @@ -61,12 +61,12 @@ class ConstExprEvaluator { return when (left.type) { in IntegerDatatypes -> when (right.type) { in IntegerDatatypes -> NumericLiteralValue.fromBoolean((left.number.toInt() != 0) xor (right.number.toInt() != 0), left.position) - DataType.FLOAT -> NumericLiteralValue.fromBoolean((left.number.toInt() != 0) xor (right.number.toDouble() != 0.0), left.position) + DataType.FLOAT -> NumericLiteralValue.fromBoolean((left.number.toInt() != 0) xor (right.number != 0.0), left.position) else -> throw ExpressionError(error, left.position) } DataType.FLOAT -> when (right.type) { - in IntegerDatatypes -> NumericLiteralValue.fromBoolean((left.number.toDouble() != 0.0) xor (right.number.toInt() != 0), left.position) - DataType.FLOAT -> NumericLiteralValue.fromBoolean((left.number.toDouble() != 0.0) xor (right.number.toDouble() != 0.0), left.position) + in IntegerDatatypes -> NumericLiteralValue.fromBoolean((left.number != 0.0) xor (right.number.toInt() != 0), left.position) + DataType.FLOAT -> NumericLiteralValue.fromBoolean((left.number != 0.0) xor (right.number != 0.0), left.position) else -> throw ExpressionError(error, left.position) } else -> throw ExpressionError(error, left.position) @@ -78,12 +78,12 @@ class ConstExprEvaluator { return when (left.type) { in IntegerDatatypes -> when (right.type) { in IntegerDatatypes -> NumericLiteralValue.fromBoolean(left.number.toInt() != 0 || right.number.toInt() != 0, left.position) - DataType.FLOAT -> NumericLiteralValue.fromBoolean(left.number.toInt() != 0 || right.number.toDouble() != 0.0, left.position) + DataType.FLOAT -> NumericLiteralValue.fromBoolean(left.number.toInt() != 0 || right.number != 0.0, left.position) else -> throw ExpressionError(error, left.position) } DataType.FLOAT -> when (right.type) { - in IntegerDatatypes -> NumericLiteralValue.fromBoolean(left.number.toDouble() != 0.0 || right.number.toInt() != 0, left.position) - DataType.FLOAT -> NumericLiteralValue.fromBoolean(left.number.toDouble() != 0.0 || right.number.toDouble() != 0.0, left.position) + in IntegerDatatypes -> NumericLiteralValue.fromBoolean(left.number != 0.0 || right.number.toInt() != 0, left.position) + DataType.FLOAT -> NumericLiteralValue.fromBoolean(left.number != 0.0 || right.number != 0.0, left.position) else -> throw ExpressionError(error, left.position) } else -> throw ExpressionError(error, left.position) @@ -95,12 +95,12 @@ class ConstExprEvaluator { return when (left.type) { in IntegerDatatypes -> when (right.type) { in IntegerDatatypes -> NumericLiteralValue.fromBoolean(left.number.toInt() != 0 && right.number.toInt() != 0, left.position) - DataType.FLOAT -> NumericLiteralValue.fromBoolean(left.number.toInt() != 0 && right.number.toDouble() != 0.0, left.position) + DataType.FLOAT -> NumericLiteralValue.fromBoolean(left.number.toInt() != 0 && right.number != 0.0, left.position) else -> throw ExpressionError(error, left.position) } DataType.FLOAT -> when (right.type) { - in IntegerDatatypes -> NumericLiteralValue.fromBoolean(left.number.toDouble() != 0.0 && right.number.toInt() != 0, left.position) - DataType.FLOAT -> NumericLiteralValue.fromBoolean(left.number.toDouble() != 0.0 && right.number.toDouble() != 0.0, left.position) + in IntegerDatatypes -> NumericLiteralValue.fromBoolean(left.number != 0.0 && right.number.toInt() != 0, left.position) + DataType.FLOAT -> NumericLiteralValue.fromBoolean(left.number != 0.0 && right.number != 0.0, left.position) else -> throw ExpressionError(error, left.position) } else -> throw ExpressionError(error, left.position) @@ -110,11 +110,11 @@ class ConstExprEvaluator { private fun bitwisexor(left: NumericLiteralValue, right: NumericLiteralValue): NumericLiteralValue { if(left.type== DataType.UBYTE) { if(right.type in IntegerDatatypes) { - return NumericLiteralValue(DataType.UBYTE, (left.number.toInt() xor (right.number.toInt() and 255)).toShort(), left.position) + return NumericLiteralValue(DataType.UBYTE, (left.number.toInt() xor (right.number.toInt() and 255)).toDouble(), left.position) } } else if(left.type== DataType.UWORD) { if(right.type in IntegerDatatypes) { - return NumericLiteralValue(DataType.UWORD, left.number.toInt() xor right.number.toInt(), left.position) + return NumericLiteralValue(DataType.UWORD, (left.number.toInt() xor right.number.toInt()).toDouble(), left.position) } } throw ExpressionError("cannot calculate $left ^ $right", left.position) @@ -123,11 +123,11 @@ class ConstExprEvaluator { private fun bitwiseor(left: NumericLiteralValue, right: NumericLiteralValue): NumericLiteralValue { if(left.type== DataType.UBYTE) { if(right.type in IntegerDatatypes) { - return NumericLiteralValue(DataType.UBYTE, (left.number.toInt() or (right.number.toInt() and 255)).toShort(), left.position) + return NumericLiteralValue(DataType.UBYTE, (left.number.toInt() or (right.number.toInt() and 255)).toDouble(), left.position) } } else if(left.type== DataType.UWORD) { if(right.type in IntegerDatatypes) { - return NumericLiteralValue(DataType.UWORD, left.number.toInt() or right.number.toInt(), left.position) + return NumericLiteralValue(DataType.UWORD, (left.number.toInt() or right.number.toInt()).toDouble(), left.position) } } throw ExpressionError("cannot calculate $left | $right", left.position) @@ -136,11 +136,11 @@ class ConstExprEvaluator { private fun bitwiseand(left: NumericLiteralValue, right: NumericLiteralValue): NumericLiteralValue { if(left.type== DataType.UBYTE) { if(right.type in IntegerDatatypes) { - return NumericLiteralValue(DataType.UBYTE, (left.number.toInt() and (right.number.toInt() and 255)).toShort(), left.position) + return NumericLiteralValue(DataType.UBYTE, (left.number.toInt() and (right.number.toInt() and 255)).toDouble(), left.position) } } else if(left.type== DataType.UWORD) { if(right.type in IntegerDatatypes) { - return NumericLiteralValue(DataType.UWORD, left.number.toInt() and right.number.toInt(), left.position) + return NumericLiteralValue(DataType.UWORD, (left.number.toInt() and right.number.toInt()).toDouble(), left.position) } } throw ExpressionError("cannot calculate $left & $right", left.position) @@ -151,12 +151,12 @@ class ConstExprEvaluator { return when (left.type) { in IntegerDatatypes -> when (right.type) { in IntegerDatatypes -> NumericLiteralValue.optimalNumeric(left.number.toInt().toDouble().pow(right.number.toInt()), left.position) - DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number.toInt().toDouble().pow(right.number.toDouble()), left.position) + DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number.toInt().toDouble().pow(right.number), left.position) else -> throw ExpressionError(error, left.position) } DataType.FLOAT -> when (right.type) { - in IntegerDatatypes -> NumericLiteralValue(DataType.FLOAT, left.number.toDouble().pow(right.number.toInt()), left.position) - DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number.toDouble().pow(right.number.toDouble()), left.position) + in IntegerDatatypes -> NumericLiteralValue(DataType.FLOAT, left.number.pow(right.number.toInt()), left.position) + DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number.pow(right.number), left.position) else -> throw ExpressionError(error, left.position) } else -> throw ExpressionError(error, left.position) @@ -168,12 +168,12 @@ class ConstExprEvaluator { return when (left.type) { in IntegerDatatypes -> when (right.type) { in IntegerDatatypes -> NumericLiteralValue.optimalInteger(left.number.toInt() + right.number.toInt(), left.position) - DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number.toInt() + right.number.toDouble(), left.position) + DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number.toInt() + right.number, left.position) else -> throw ExpressionError(error, left.position) } DataType.FLOAT -> when (right.type) { - in IntegerDatatypes -> NumericLiteralValue(DataType.FLOAT, left.number.toDouble() + right.number.toInt(), left.position) - DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number.toDouble() + right.number.toDouble(), left.position) + in IntegerDatatypes -> NumericLiteralValue(DataType.FLOAT, left.number + right.number.toInt(), left.position) + DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number + right.number, left.position) else -> throw ExpressionError(error, left.position) } else -> throw ExpressionError(error, left.position) @@ -185,12 +185,12 @@ class ConstExprEvaluator { return when (left.type) { in IntegerDatatypes -> when (right.type) { in IntegerDatatypes -> NumericLiteralValue.optimalInteger(left.number.toInt() - right.number.toInt(), left.position) - DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number.toInt() - right.number.toDouble(), left.position) + DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number.toInt() - right.number, left.position) else -> throw ExpressionError(error, left.position) } DataType.FLOAT -> when (right.type) { - in IntegerDatatypes -> NumericLiteralValue(DataType.FLOAT, left.number.toDouble() - right.number.toInt(), left.position) - DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number.toDouble() - right.number.toDouble(), left.position) + in IntegerDatatypes -> NumericLiteralValue(DataType.FLOAT, left.number - right.number.toInt(), left.position) + DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number - right.number, left.position) else -> throw ExpressionError(error, left.position) } else -> throw ExpressionError(error, left.position) @@ -202,12 +202,12 @@ class ConstExprEvaluator { return when (left.type) { in IntegerDatatypes -> when (right.type) { in IntegerDatatypes -> NumericLiteralValue.optimalInteger(left.number.toInt() * right.number.toInt(), left.position) - DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number.toInt() * right.number.toDouble(), left.position) + DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number.toInt() * right.number, left.position) else -> throw ExpressionError(error, left.position) } DataType.FLOAT -> when (right.type) { - in IntegerDatatypes -> NumericLiteralValue(DataType.FLOAT, left.number.toDouble() * right.number.toInt(), left.position) - DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number.toDouble() * right.number.toDouble(), left.position) + in IntegerDatatypes -> NumericLiteralValue(DataType.FLOAT, left.number * right.number.toInt(), left.position) + DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, left.number * right.number, left.position) else -> throw ExpressionError(error, left.position) } else -> throw ExpressionError(error, left.position) @@ -227,19 +227,19 @@ class ConstExprEvaluator { NumericLiteralValue.optimalInteger(result, left.position) } DataType.FLOAT -> { - if(right.number.toDouble()==0.0) divideByZeroError(right.position) - NumericLiteralValue(DataType.FLOAT, left.number.toInt() / right.number.toDouble(), left.position) + if(right.number==0.0) divideByZeroError(right.position) + NumericLiteralValue(DataType.FLOAT, left.number.toInt() / right.number, left.position) } else -> throw ExpressionError(error, left.position) } DataType.FLOAT -> when (right.type) { in IntegerDatatypes -> { if(right.number.toInt()==0) divideByZeroError(right.position) - NumericLiteralValue(DataType.FLOAT, left.number.toDouble() / right.number.toInt(), left.position) + NumericLiteralValue(DataType.FLOAT, left.number / right.number.toInt(), left.position) } DataType.FLOAT -> { - if(right.number.toDouble()==0.0) divideByZeroError(right.position) - NumericLiteralValue(DataType.FLOAT, left.number.toDouble() / right.number.toDouble(), left.position) + if(right.number ==0.0) divideByZeroError(right.position) + NumericLiteralValue(DataType.FLOAT, left.number / right.number, left.position) } else -> throw ExpressionError(error, left.position) } @@ -256,19 +256,19 @@ class ConstExprEvaluator { NumericLiteralValue.optimalNumeric(left.number.toInt().toDouble() % right.number.toInt().toDouble(), left.position) } DataType.FLOAT -> { - if(right.number.toDouble()==0.0) divideByZeroError(right.position) - NumericLiteralValue(DataType.FLOAT, left.number.toInt() % right.number.toDouble(), left.position) + if(right.number ==0.0) divideByZeroError(right.position) + NumericLiteralValue(DataType.FLOAT, left.number.toInt() % right.number, left.position) } else -> throw ExpressionError(error, left.position) } DataType.FLOAT -> when (right.type) { in IntegerDatatypes -> { if(right.number.toInt()==0) divideByZeroError(right.position) - NumericLiteralValue(DataType.FLOAT, left.number.toDouble() % right.number.toInt(), left.position) + NumericLiteralValue(DataType.FLOAT, left.number % right.number.toInt(), left.position) } DataType.FLOAT -> { - if(right.number.toDouble()==0.0) divideByZeroError(right.position) - NumericLiteralValue(DataType.FLOAT, left.number.toDouble() % right.number.toDouble(), left.position) + if(right.number ==0.0) divideByZeroError(right.position) + NumericLiteralValue(DataType.FLOAT, left.number % right.number, left.position) } else -> throw ExpressionError(error, left.position) } diff --git a/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt b/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt index 608844607..b83aabc9d 100644 --- a/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt +++ b/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt @@ -40,7 +40,7 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() { } DataType.FLOAT -> { listOf(IAstModification.ReplaceNode(expr, - NumericLiteralValue(DataType.FLOAT, -subexpr.number.toDouble(), subexpr.position), + NumericLiteralValue(DataType.FLOAT, -subexpr.number, subexpr.position), parent)) } else -> throw ExpressionError("can only take negative of int or float", subexpr.position) @@ -48,29 +48,29 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() { "~" -> when (subexpr.type) { DataType.BYTE -> { listOf(IAstModification.ReplaceNode(expr, - NumericLiteralValue(DataType.BYTE, subexpr.number.toInt().inv(), subexpr.position), + NumericLiteralValue(DataType.BYTE, subexpr.number.toInt().inv().toDouble(), subexpr.position), parent)) } DataType.UBYTE -> { listOf(IAstModification.ReplaceNode(expr, - NumericLiteralValue(DataType.UBYTE, subexpr.number.toInt().inv() and 255, subexpr.position), + NumericLiteralValue(DataType.UBYTE, (subexpr.number.toInt().inv() and 255).toDouble(), subexpr.position), parent)) } DataType.WORD -> { listOf(IAstModification.ReplaceNode(expr, - NumericLiteralValue(DataType.WORD, subexpr.number.toInt().inv(), subexpr.position), + NumericLiteralValue(DataType.WORD, subexpr.number.toInt().inv().toDouble(), subexpr.position), parent)) } DataType.UWORD -> { listOf(IAstModification.ReplaceNode(expr, - NumericLiteralValue(DataType.UWORD, subexpr.number.toInt().inv() and 65535, subexpr.position), + NumericLiteralValue(DataType.UWORD, (subexpr.number.toInt().inv() and 65535).toDouble(), subexpr.position), parent)) } else -> throw ExpressionError("can only take bitwise inversion of int", subexpr.position) } "not" -> { listOf(IAstModification.ReplaceNode(expr, - NumericLiteralValue.fromBoolean(subexpr.number.toDouble() == 0.0, subexpr.position), + NumericLiteralValue.fromBoolean(subexpr.number == 0.0, subexpr.position), parent)) } else -> throw ExpressionError(expr.operator, subexpr.position) @@ -106,18 +106,18 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() { // optimize away 1 ** x into just 1 and 0 ** x into just 0 // optimize 2 ** x into (1< { - val value = NumericLiteralValue(leftDt, 0, expr.position) + val value = NumericLiteralValue(leftDt, 0.0, expr.position) modifications += IAstModification.ReplaceNode(expr, value, parent) } 1.0 -> { - val value = NumericLiteralValue(leftDt, 1, expr.position) + val value = NumericLiteralValue(leftDt, 1.0, expr.position) modifications += IAstModification.ReplaceNode(expr, value, parent) } 2.0 -> { if(rightconst!=null) { - val value = NumericLiteralValue(leftDt, 2.0.pow(rightconst.number.toDouble()), expr.position) + val value = NumericLiteralValue(leftDt, 2.0.pow(rightconst.number), expr.position) modifications += IAstModification.ReplaceNode(expr, value, parent) } else { val rightDt = expr.right.inferType(program).getOr(DataType.UNDEFINED) @@ -128,7 +128,7 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() { is VarDecl -> parent.datatype else -> leftDt } - val one = NumericLiteralValue(targetDt, 1, expr.position) + val one = NumericLiteralValue(targetDt, 1.0, expr.position) val shift = BinaryExpression(one, "<<", expr.right, expr.position) modifications += IAstModification.ReplaceNode(expr, shift, parent) } diff --git a/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt b/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt index f64f053be..699364c19 100644 --- a/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt +++ b/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt @@ -38,9 +38,9 @@ class VarConstantValueTypeAdjuster(private val program: Program, private val err } override fun after(range: RangeExpr, parent: Node): Iterable { - val from = range.from.constValue(program)?.number?.toDouble() - val to = range.to.constValue(program)?.number?.toDouble() - val step = range.step.constValue(program)?.number?.toDouble() + val from = range.from.constValue(program)?.number + val to = range.to.constValue(program)?.number + val step = range.step.constValue(program)?.number if(from==null) { if(!range.from.inferType(program).isInteger) @@ -132,7 +132,7 @@ internal class ConstantIdentifierReplacer(private val program: Program, private // vardecl: for scalar float vars, promote constant integer initialization values to floats val litval = decl.value as? NumericLiteralValue if (litval!=null && litval.type in IntegerDatatypes) { - val newValue = NumericLiteralValue(DataType.FLOAT, litval.number.toDouble(), litval.position) + val newValue = NumericLiteralValue(DataType.FLOAT, litval.number, litval.position) return listOf(IAstModification.ReplaceNode(decl.value!!, newValue, decl)) } } @@ -148,11 +148,11 @@ internal class ConstantIdentifierReplacer(private val program: Program, private val eltType = rangeExpr.inferType(program).getOr(DataType.UBYTE) val newValue = if(eltType in ByteDatatypes) { ArrayLiteralValue(InferredTypes.InferredType.known(decl.datatype), - constRange.map { NumericLiteralValue(eltType, it.toShort(), decl.value!!.position) }.toTypedArray(), + constRange.map { NumericLiteralValue(eltType, it.toDouble(), decl.value!!.position) }.toTypedArray(), position = decl.value!!.position) } else { ArrayLiteralValue(InferredTypes.InferredType.known(decl.datatype), - constRange.map { NumericLiteralValue(eltType, it, decl.value!!.position) }.toTypedArray(), + constRange.map { NumericLiteralValue(eltType, it.toDouble(), decl.value!!.position) }.toTypedArray(), position = decl.value!!.position) } return listOf(IAstModification.ReplaceNode(decl.value!!, newValue, decl)) @@ -185,7 +185,7 @@ internal class ConstantIdentifierReplacer(private val program: Program, private else -> {} } // create the array itself, filled with the fillvalue. - val array = Array(size) {fillvalue}.map { NumericLiteralValue(ArrayToElementTypes.getValue(decl.datatype), it, numericLv.position) }.toTypedArray() + val array = Array(size) {fillvalue}.map { NumericLiteralValue(ArrayToElementTypes.getValue(decl.datatype), it.toDouble(), numericLv.position) }.toTypedArray() val refValue = ArrayLiteralValue(InferredTypes.InferredType.known(decl.datatype), array, position = numericLv.position) return listOf(IAstModification.ReplaceNode(decl.value!!, refValue, decl)) } @@ -210,7 +210,7 @@ internal class ConstantIdentifierReplacer(private val program: Program, private val size = decl.arraysize?.constIndex() ?: return noModifications if(rangeExpr==null && numericLv!=null) { // arraysize initializer is a single int, and we know the size. - val fillvalue = numericLv.number.toDouble() + val fillvalue = numericLv.number if (fillvalue < compTarget.machine.FLOAT_MAX_NEGATIVE || fillvalue > compTarget.machine.FLOAT_MAX_POSITIVE) errors.err("float value overflow", numericLv.position) else { diff --git a/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt b/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt index 832a7a099..b759e2115 100644 --- a/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt +++ b/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt @@ -21,9 +21,6 @@ import kotlin.math.pow some of these may already be present: -*(&X) => X -X % 1 => 0 -X / 1 => X X ^ -1 => ~x X >= 1 => X > 0 X < 1 => X <= 0 @@ -164,7 +161,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { val x = expr.right val y = determineY(x, leftBinExpr) if (y != null) { - val yPlus1 = BinaryExpression(y, "+", NumericLiteralValue(leftDt, 1, y.position), y.position) + val yPlus1 = BinaryExpression(y, "+", NumericLiteralValue(leftDt, 1.0, y.position), y.position) val newExpr = BinaryExpression(x, "*", yPlus1, x.position) return listOf(IAstModification.ReplaceNode(expr, newExpr, parent)) } @@ -174,7 +171,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { val x = expr.right val y = determineY(x, leftBinExpr) if (y != null) { - val yMinus1 = BinaryExpression(y, "-", NumericLiteralValue(leftDt, 1, y.position), y.position) + val yMinus1 = BinaryExpression(y, "-", NumericLiteralValue(leftDt, 1.0, y.position), y.position) val newExpr = BinaryExpression(x, "*", yMinus1, x.position) return listOf(IAstModification.ReplaceNode(expr, newExpr, parent)) } @@ -194,14 +191,14 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { } } - if(expr.operator == ">=" && rightVal?.number == 0) { + if(expr.operator == ">=" && rightVal?.number == 0.0) { if (leftDt == DataType.UBYTE || leftDt == DataType.UWORD) { // unsigned >= 0 --> true return listOf(IAstModification.ReplaceNode(expr, NumericLiteralValue.fromBoolean(true, expr.position), parent)) } } - if(expr.operator == "<" && rightVal?.number == 0) { + if(expr.operator == "<" && rightVal?.number == 0.0) { if (leftDt == DataType.UBYTE || leftDt == DataType.UWORD) { // unsigned < 0 --> false return listOf(IAstModification.ReplaceNode(expr, NumericLiteralValue.fromBoolean(false, expr.position), parent)) @@ -271,8 +268,14 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { expr.right else if (rightVal != null && !rightVal.asBooleanValue) expr.left - else - null + else { + if(rightIDt.isBytes && (rightVal?.number==-1.0 || rightVal?.number==255.0)) + PrefixExpression("~", expr.left, expr.left.position) + else if(rightIDt.isWords && (rightVal?.number==-1.0 || rightVal?.number==65535.0)) + PrefixExpression("~", expr.left, expr.left.position) + else + null + } } "&" -> { if (leftVal != null && !leftVal.asBooleanValue) @@ -324,7 +327,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { // useless msb() of byte value that was typecasted to word, replace with 0 return listOf(IAstModification.ReplaceNode( functionCall, - NumericLiteralValue(valueDt.getOr(DataType.UBYTE), 0, arg.expression.position), + NumericLiteralValue(valueDt.getOr(DataType.UBYTE), 0.0, arg.expression.position), parent)) } } else { @@ -333,7 +336,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { // useless msb() of byte value, replace with 0 return listOf(IAstModification.ReplaceNode( functionCall, - NumericLiteralValue(argDt.getOr(DataType.UBYTE), 0, arg.position), + NumericLiteralValue(argDt.getOr(DataType.UBYTE), 0.0, arg.position), parent)) } } @@ -366,7 +369,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { if (rightVal2 != null) { // right value is a constant, see if we can optimize val rightConst: NumericLiteralValue = rightVal2 - when (rightConst.number.toDouble()) { + when (rightConst.number) { 0.0 -> { // left return expr2.left @@ -375,7 +378,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { } // no need to check for left val constant (because of associativity) - val rnum = rightVal?.number?.toDouble() + val rnum = rightVal?.number if(rnum!=null && rnum<0.0) { expr.operator = "-" expr.right = NumericLiteralValue(rightVal.type, -rnum, rightVal.position) @@ -396,7 +399,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { if (rightVal != null) { // right value is a constant, see if we can optimize - val rnum = rightVal.number.toDouble() + val rnum = rightVal.number if (rnum == 0.0) { // left return expr.left @@ -410,7 +413,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { } if (leftVal != null) { // left value is a constant, see if we can optimize - when (leftVal.number.toDouble()) { + when (leftVal.number) { 0.0 -> { // -right return PrefixExpression("-", expr.right, expr.position) @@ -429,7 +432,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { if (rightVal != null) { // right value is a constant, see if we can optimize val rightConst: NumericLiteralValue = rightVal - when (rightConst.number.toDouble()) { + when (rightConst.number) { -3.0 -> { // -1/(left*left*left) return BinaryExpression(NumericLiteralValue(DataType.FLOAT, -1.0, expr.position), "/", @@ -449,7 +452,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { } 0.0 -> { // 1 - return NumericLiteralValue(rightConst.type, 1, expr.position) + return NumericLiteralValue(rightConst.type, 1.0, expr.position) } 0.5 -> { // sqrt(left) @@ -471,18 +474,18 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { } if (leftVal != null) { // left value is a constant, see if we can optimize - when (leftVal.number.toDouble()) { + when (leftVal.number) { -1.0 -> { // -1 return NumericLiteralValue(DataType.FLOAT, -1.0, expr.position) } 0.0 -> { // 0 - return NumericLiteralValue(leftVal.type, 0, expr.position) + return NumericLiteralValue(leftVal.type, 0.0, expr.position) } 1.0 -> { //1 - return NumericLiteralValue(leftVal.type, 1, expr.position) + return NumericLiteralValue(leftVal.type, 1.0, expr.position) } } @@ -504,7 +507,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { val idt = expr.inferType(program) if(!idt.isKnown) throw FatalAstException("unknown dt") - return NumericLiteralValue(idt.getOr(DataType.UNDEFINED), 0, expr.position) + return NumericLiteralValue(idt.getOr(DataType.UNDEFINED), 0.0, expr.position) } else if (cv in powersOfTwo) { expr.operator = "&" expr.right = NumericLiteralValue.optimalInteger(cv!!.toInt()-1, expr.position) @@ -524,7 +527,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { if (rightVal != null) { // right value is a constant, see if we can optimize val rightConst: NumericLiteralValue = rightVal - val cv = rightConst.number.toDouble() + val cv = rightConst.number val leftIDt = expr.left.inferType(program) if (!leftIDt.isKnown) return null @@ -559,22 +562,22 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { } if (leftDt == DataType.UBYTE) { - if (abs(rightConst.number.toDouble()) >= 256.0) { - return NumericLiteralValue(DataType.UBYTE, 0, expr.position) + if (abs(rightConst.number) >= 256.0) { + return NumericLiteralValue(DataType.UBYTE, 0.0, expr.position) } } else if (leftDt == DataType.UWORD) { - if (abs(rightConst.number.toDouble()) >= 65536.0) { - return NumericLiteralValue(DataType.UBYTE, 0, expr.position) + if (abs(rightConst.number) >= 65536.0) { + return NumericLiteralValue(DataType.UBYTE, 0.0, expr.position) } } } if (leftVal != null) { // left value is a constant, see if we can optimize - when (leftVal.number.toDouble()) { + when (leftVal.number) { 0.0 -> { // 0 - return NumericLiteralValue(leftVal.type, 0, expr.position) + return NumericLiteralValue(leftVal.type, 0.0, expr.position) } } } @@ -591,14 +594,14 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { // right value is a constant, see if we can optimize val leftValue: Expression = expr2.left val rightConst: NumericLiteralValue = rightVal2 - when (val cv = rightConst.number.toDouble()) { + when (val cv = rightConst.number) { -1.0 -> { // -left return PrefixExpression("-", leftValue, expr.position) } 0.0 -> { // 0 - return NumericLiteralValue(rightConst.type, 0, expr.position) + return NumericLiteralValue(rightConst.type, 0.0, expr.position) } 1.0 -> { // left @@ -639,12 +642,12 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { when (val targetDt = targetIDt.getOr(DataType.UNDEFINED)) { DataType.UBYTE, DataType.BYTE -> { if (amount >= 8) { - return NumericLiteralValue(targetDt, 0, expr.position) + return NumericLiteralValue(targetDt, 0.0, expr.position) } } DataType.UWORD, DataType.WORD -> { if (amount >= 16) { - return NumericLiteralValue(targetDt, 0, expr.position) + return NumericLiteralValue(targetDt, 0.0, expr.position) } else if (amount >= 8) { val lsb = FunctionCall(IdentifierReference(listOf("lsb"), expr.position), mutableListOf(expr.left), expr.position) if (amount == 8) { @@ -691,7 +694,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { val msb = FunctionCall(IdentifierReference(listOf("msb"), expr.position), mutableListOf(expr.left), expr.position) if (amount == 8) { // mkword(0, msb(v)) - val zero = NumericLiteralValue(DataType.UBYTE, 0, expr.position) + val zero = NumericLiteralValue(DataType.UBYTE, 0.0, expr.position) return FunctionCall(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(zero, msb), expr.position) } return TypecastExpression(BinaryExpression(msb, ">>", NumericLiteralValue.optimalInteger(amount - 8, expr.position), expr.position), DataType.UWORD, true, expr.position) diff --git a/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt b/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt index 1976f2e94..8cb049c7e 100644 --- a/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt +++ b/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt @@ -82,7 +82,7 @@ class StatementOptimizer(private val program: Program, val firstCharEncoded = compTarget.encodeString(string.value, string.altEncoding)[0] val chrout = FunctionCallStatement( IdentifierReference(listOf("txt", "chrout"), pos), - mutableListOf(NumericLiteralValue(DataType.UBYTE, firstCharEncoded.toInt(), pos)), + mutableListOf(NumericLiteralValue(DataType.UBYTE, firstCharEncoded.toDouble(), pos)), functionCallStatement.void, pos ) return listOf(IAstModification.ReplaceNode(functionCallStatement, chrout, parent)) @@ -90,12 +90,12 @@ class StatementOptimizer(private val program: Program, val firstTwoCharsEncoded = compTarget.encodeString(string.value.take(2), string.altEncoding) val chrout1 = FunctionCallStatement( IdentifierReference(listOf("txt", "chrout"), pos), - mutableListOf(NumericLiteralValue(DataType.UBYTE, firstTwoCharsEncoded[0].toInt(), pos)), + mutableListOf(NumericLiteralValue(DataType.UBYTE, firstTwoCharsEncoded[0].toDouble(), pos)), functionCallStatement.void, pos ) val chrout2 = FunctionCallStatement( IdentifierReference(listOf("txt", "chrout"), pos), - mutableListOf(NumericLiteralValue(DataType.UBYTE, firstTwoCharsEncoded[1].toInt(), pos)), + mutableListOf(NumericLiteralValue(DataType.UBYTE, firstTwoCharsEncoded[1].toDouble(), pos)), functionCallStatement.void, pos ) return listOf( @@ -196,7 +196,7 @@ class StatementOptimizer(private val program: Program, if(size==1) { // loop over string of length 1 -> just assign the single character val character = compTarget.encodeString(sv.value, sv.altEncoding)[0] - val byte = NumericLiteralValue(DataType.UBYTE, character, iterable.position) + val byte = NumericLiteralValue(DataType.UBYTE, character.toDouble(), iterable.position) val scope = AnonymousScope(mutableListOf(), forLoop.position) scope.statements.add(Assignment(AssignTarget(forLoop.loopVar, null, null, forLoop.position), byte, forLoop.position)) scope.statements.addAll(forLoop.body.statements) @@ -358,7 +358,7 @@ class StatementOptimizer(private val program: Program, val targetDt = targetIDt.getOr(DataType.UNDEFINED) val bexpr=assignment.value as? BinaryExpression if(bexpr!=null) { - val rightCv = bexpr.right.constValue(program)?.number?.toDouble() + val rightCv = bexpr.right.constValue(program)?.number if (rightCv != null && assignment.target isSameAs bexpr.left) { // assignments of the form: X = X // remove assignments that have no effect (such as X=X+0) diff --git a/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt b/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt index 04f0689ac..708bf1cc0 100644 --- a/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt +++ b/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt @@ -112,7 +112,7 @@ class UnusedCodeRemover(private val program: Program, errors.warn("removing unused variable '${decl.name}'", decl.position) return listOf(IAstModification.Remove(decl, parent as IStatementContainer)) } else { - // if all usages are just an assignment to this vardecl + // if all usages are just an assignment to this vardecl, // and it is in regular RAM, then remove the var as well including all assignments val assignTargets = usages.mapNotNull { if(it.parent is AssignTarget) diff --git a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt index 6f3e84ba0..4b4b82dee 100644 --- a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt +++ b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt @@ -206,8 +206,8 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o return listOf(IAstModification.ReplaceNode(ifStatement.condition, booleanExpr, ifStatement)) } - if((binExpr.left as? NumericLiteralValue)?.number==0 && - (binExpr.right as? NumericLiteralValue)?.number!=0) + if((binExpr.left as? NumericLiteralValue)?.number==0.0 && + (binExpr.right as? NumericLiteralValue)?.number!=0.0) throw FatalAstException("0==X should have been swapped to if X==0") // simplify the conditional expression, introduce simple assignments if required. @@ -302,8 +302,8 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o return listOf(IAstModification.ReplaceNode(untilLoop.condition, booleanExpr, untilLoop)) } - if((binExpr.left as? NumericLiteralValue)?.number==0 && - (binExpr.right as? NumericLiteralValue)?.number!=0) + if((binExpr.left as? NumericLiteralValue)?.number==0.0 && + (binExpr.right as? NumericLiteralValue)?.number!=0.0) throw FatalAstException("0==X should have been swapped to if X==0") // simplify the conditional expression, introduce simple assignments if required. @@ -339,8 +339,8 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o return listOf(IAstModification.ReplaceNode(whileLoop.condition, booleanExpr, whileLoop)) } - if((binExpr.left as? NumericLiteralValue)?.number==0 && - (binExpr.right as? NumericLiteralValue)?.number!=0) + if((binExpr.left as? NumericLiteralValue)?.number==0.0 && + (binExpr.right as? NumericLiteralValue)?.number!=0.0) throw FatalAstException("0==X should have been swapped to if X==0") // TODO simplify the conditional expression, introduce simple assignments if required. diff --git a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt index e8309bb6c..5eacad6c0 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt @@ -44,7 +44,7 @@ internal fun Program.charLiteralsToUByteLiterals(enc: IStringEncoding) { override fun after(char: CharLiteral, parent: Node): Iterable { return listOf(IAstModification.ReplaceNode( char, - NumericLiteralValue(DataType.UBYTE, enc.encodeString(char.value.toString(), char.altEncoding)[0].toInt(), char.position), + NumericLiteralValue(DataType.UBYTE, enc.encodeString(char.value.toString(), char.altEncoding)[0].toDouble(), char.position), parent )) } diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 7da0b1ed4..b8b85c402 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -197,7 +197,7 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport // generating the wrong results later fun wrapped(expr: Expression): Expression = - BinaryExpression(expr, "!=", NumericLiteralValue(DataType.UBYTE, 0, expr.position), expr.position) + BinaryExpression(expr, "!=", NumericLiteralValue(DataType.UBYTE, 0.0, expr.position), expr.position) fun isLogicalExpr(expr: Expression?): Boolean { if(expr is BinaryExpression && expr.operator in (logicalOperators + comparisonOperators)) diff --git a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt index c30808428..9a87b52c2 100644 --- a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt +++ b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt @@ -94,6 +94,13 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter) override fun after(assignment: Assignment, parent: Node): Iterable { if(assignment.parent!==parent) throw FatalAstException("parent node mismatch at $assignment") + + val nextAssign = assignment.nextSibling() as? Assignment + if(nextAssign!=null && nextAssign.target.isSameAs(assignment.target, program)) { + if(nextAssign.value isSameAs assignment.value) + return listOf(IAstModification.Remove(assignment, parent as IStatementContainer)) + } + return noModifications } diff --git a/compiler/test/TestCompilerOnCharLit.kt b/compiler/test/TestCompilerOnCharLit.kt index ed46e5c36..5c02e0f48 100644 --- a/compiler/test/TestCompilerOnCharLit.kt +++ b/compiler/test/TestCompilerOnCharLit.kt @@ -43,7 +43,7 @@ class TestCompilerOnCharLit: FunSpec({ } val arg = funCall.args[0] as NumericLiteralValue arg.type shouldBe DataType.UBYTE - arg.number.toShort() shouldBe platform.encodeString("\n", false)[0] + arg.number shouldBe platform.encodeString("\n", false)[0] } test("testCharVarAsRomsubArg") { @@ -83,7 +83,7 @@ class TestCompilerOnCharLit: FunSpec({ } val initializerValue = assignInitialValue.value as NumericLiteralValue initializerValue.type shouldBe DataType.UBYTE - initializerValue.number.toShort() shouldBe platform.encodeString("\n", false)[0] + initializerValue.number shouldBe platform.encodeString("\n", false)[0] } test("testCharConstAsRomsubArg") { @@ -108,10 +108,10 @@ class TestCompilerOnCharLit: FunSpec({ val decl = arg.targetVarDecl(program)!! decl.type shouldBe VarDeclType.CONST decl.datatype shouldBe DataType.UBYTE - (decl.value as NumericLiteralValue).number.toShort() shouldBe platform.encodeString("\n", false)[0] + (decl.value as NumericLiteralValue).number shouldBe platform.encodeString("\n", false)[0] } is NumericLiteralValue -> { - arg.number.toShort() shouldBe platform.encodeString("\n", false)[0] + arg.number shouldBe platform.encodeString("\n", false)[0] } else -> fail("invalid arg type") // funCall.args[0] shouldBe instanceOf() // make test fail } diff --git a/compiler/test/TestNumericLiteralValue.kt b/compiler/test/TestNumericLiteralValue.kt index 87d62c0e5..70f2bcc84 100644 --- a/compiler/test/TestNumericLiteralValue.kt +++ b/compiler/test/TestNumericLiteralValue.kt @@ -19,7 +19,7 @@ class TestNumericLiteralValue: FunSpec({ val dummyPos = Position("test", 0, 0, 0) test("testIdentity") { - val v = NumericLiteralValue(DataType.UWORD, 12345, dummyPos) + val v = NumericLiteralValue(DataType.UWORD, 12345.0, dummyPos) (v==v) shouldBe true (v != v) shouldBe false (v <= v) shouldBe true @@ -27,48 +27,56 @@ class TestNumericLiteralValue: FunSpec({ (v < v ) shouldBe false (v > v ) shouldBe false - sameValueAndType(NumericLiteralValue(DataType.UWORD, 12345, dummyPos), NumericLiteralValue(DataType.UWORD, 12345, dummyPos)) shouldBe true + sameValueAndType(NumericLiteralValue(DataType.UWORD, 12345.0, dummyPos), NumericLiteralValue(DataType.UWORD, 12345.0, dummyPos)) shouldBe true + } + + test("test rounding") { + NumericLiteralValue(DataType.BYTE, -2.345, dummyPos).number shouldBe -2.0 + NumericLiteralValue(DataType.BYTE, -2.6, dummyPos).number shouldBe -3.0 + NumericLiteralValue(DataType.UWORD, 2222.345, dummyPos).number shouldBe 2222.0 + NumericLiteralValue(DataType.UWORD, 2222.6, dummyPos).number shouldBe 2223.0 + NumericLiteralValue(DataType.FLOAT, 123.456, dummyPos).number shouldBe 123.456 } test("testEqualsAndNotEquals") { - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) == NumericLiteralValue(DataType.UBYTE, 100, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) == NumericLiteralValue(DataType.UWORD, 100, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) == NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UWORD, 254, dummyPos) == NumericLiteralValue(DataType.UBYTE, 254, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UWORD, 12345, dummyPos) == NumericLiteralValue(DataType.UWORD, 12345, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UWORD, 12345, dummyPos) == NumericLiteralValue(DataType.FLOAT, 12345.0, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos) == NumericLiteralValue(DataType.UBYTE, 100, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.FLOAT, 22239.0, dummyPos) == NumericLiteralValue(DataType.UWORD, 22239, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) == NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) == NumericLiteralValue(DataType.UWORD, 100.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) == NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UWORD, 254.0, dummyPos) == NumericLiteralValue(DataType.UBYTE, 254.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UWORD, 12345.0, dummyPos) == NumericLiteralValue(DataType.UWORD, 12345.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UWORD, 12345.0, dummyPos) == NumericLiteralValue(DataType.FLOAT, 12345.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos) == NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.FLOAT, 22239.0, dummyPos) == NumericLiteralValue(DataType.UWORD, 22239.0, dummyPos)) shouldBe true (NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos) == NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos)) shouldBe true - sameValueAndType(NumericLiteralValue(DataType.UBYTE, 100, dummyPos), NumericLiteralValue(DataType.UBYTE, 100, dummyPos)) shouldBe true - sameValueAndType(NumericLiteralValue(DataType.UBYTE, 100, dummyPos), NumericLiteralValue(DataType.UWORD, 100, dummyPos)) shouldBe false - sameValueAndType(NumericLiteralValue(DataType.UBYTE, 100, dummyPos), NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos)) shouldBe false - sameValueAndType(NumericLiteralValue(DataType.UWORD, 254, dummyPos), NumericLiteralValue(DataType.UBYTE, 254, dummyPos)) shouldBe false - sameValueAndType(NumericLiteralValue(DataType.UWORD, 12345, dummyPos), NumericLiteralValue(DataType.UWORD, 12345, dummyPos)) shouldBe true - sameValueAndType(NumericLiteralValue(DataType.UWORD, 12345, dummyPos), NumericLiteralValue(DataType.FLOAT, 12345.0, dummyPos)) shouldBe false - sameValueAndType(NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos), NumericLiteralValue(DataType.UBYTE, 100, dummyPos)) shouldBe false - sameValueAndType(NumericLiteralValue(DataType.FLOAT, 22239.0, dummyPos), NumericLiteralValue(DataType.UWORD, 22239, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos), NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos)) shouldBe true + sameValueAndType(NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos), NumericLiteralValue(DataType.UWORD, 100.0, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos), NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.UWORD, 254.0, dummyPos), NumericLiteralValue(DataType.UBYTE, 254.0, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.UWORD, 12345.0, dummyPos), NumericLiteralValue(DataType.UWORD, 12345.0, dummyPos)) shouldBe true + sameValueAndType(NumericLiteralValue(DataType.UWORD, 12345.0, dummyPos), NumericLiteralValue(DataType.FLOAT, 12345.0, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos), NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.FLOAT, 22239.0, dummyPos), NumericLiteralValue(DataType.UWORD, 22239.0, dummyPos)) shouldBe false sameValueAndType(NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos), NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) != NumericLiteralValue(DataType.UBYTE, 101, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) != NumericLiteralValue(DataType.UWORD, 101, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) != NumericLiteralValue(DataType.FLOAT, 101.0, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UWORD, 245, dummyPos) != NumericLiteralValue(DataType.UBYTE, 246, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UWORD, 12345, dummyPos) != NumericLiteralValue(DataType.UWORD, 12346, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UWORD, 12345, dummyPos) != NumericLiteralValue(DataType.FLOAT, 12346.0, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos) != NumericLiteralValue(DataType.UBYTE, 9, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos) != NumericLiteralValue(DataType.UWORD, 9, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) != NumericLiteralValue(DataType.UBYTE, 101.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) != NumericLiteralValue(DataType.UWORD, 101.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) != NumericLiteralValue(DataType.FLOAT, 101.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UWORD, 245.0, dummyPos) != NumericLiteralValue(DataType.UBYTE, 246.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UWORD, 12345.0, dummyPos) != NumericLiteralValue(DataType.UWORD, 12346.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UWORD, 12345.0, dummyPos) != NumericLiteralValue(DataType.FLOAT, 12346.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos) != NumericLiteralValue(DataType.UBYTE, 9.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos) != NumericLiteralValue(DataType.UWORD, 9.0, dummyPos)) shouldBe true (NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos) != NumericLiteralValue(DataType.FLOAT, 9.0, dummyPos)) shouldBe true - sameValueAndType(NumericLiteralValue(DataType.UBYTE, 100, dummyPos), NumericLiteralValue(DataType.UBYTE, 101, dummyPos)) shouldBe false - sameValueAndType(NumericLiteralValue(DataType.UBYTE, 100, dummyPos), NumericLiteralValue(DataType.UWORD, 101, dummyPos)) shouldBe false - sameValueAndType(NumericLiteralValue(DataType.UBYTE, 100, dummyPos), NumericLiteralValue(DataType.FLOAT, 101.0, dummyPos)) shouldBe false - sameValueAndType(NumericLiteralValue(DataType.UWORD, 245, dummyPos), NumericLiteralValue(DataType.UBYTE, 246, dummyPos)) shouldBe false - sameValueAndType(NumericLiteralValue(DataType.UWORD, 12345, dummyPos), NumericLiteralValue(DataType.UWORD, 12346, dummyPos)) shouldBe false - sameValueAndType(NumericLiteralValue(DataType.UWORD, 12345, dummyPos), NumericLiteralValue(DataType.FLOAT, 12346.0, dummyPos)) shouldBe false - sameValueAndType(NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos), NumericLiteralValue(DataType.UBYTE, 9, dummyPos)) shouldBe false - sameValueAndType(NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos), NumericLiteralValue(DataType.UWORD, 9, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos), NumericLiteralValue(DataType.UBYTE, 101.0, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos), NumericLiteralValue(DataType.UWORD, 101.0, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos), NumericLiteralValue(DataType.FLOAT, 101.0, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.UWORD, 245.0, dummyPos), NumericLiteralValue(DataType.UBYTE, 246.0, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.UWORD, 12345.0, dummyPos), NumericLiteralValue(DataType.UWORD, 12346.0, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.UWORD, 12345.0, dummyPos), NumericLiteralValue(DataType.FLOAT, 12346.0, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos), NumericLiteralValue(DataType.UBYTE, 9.0, dummyPos)) shouldBe false + sameValueAndType(NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos), NumericLiteralValue(DataType.UWORD, 9.0, dummyPos)) shouldBe false sameValueAndType(NumericLiteralValue(DataType.FLOAT, 9.99, dummyPos), NumericLiteralValue(DataType.FLOAT, 9.0, dummyPos)) shouldBe false @@ -81,13 +89,13 @@ class TestNumericLiteralValue: FunSpec({ (StringLiteralValue("hello", true, dummyPos) != StringLiteralValue("bye", true, dummyPos)) shouldBe true (StringLiteralValue("hello", true, dummyPos) != StringLiteralValue("hello", false, dummyPos)) shouldBe true - val lvOne = NumericLiteralValue(DataType.UBYTE, 1, dummyPos) - val lvTwo = NumericLiteralValue(DataType.UBYTE, 2, dummyPos) - val lvThree = NumericLiteralValue(DataType.UBYTE, 3, dummyPos) - val lvOneR = NumericLiteralValue(DataType.UBYTE, 1, dummyPos) - val lvTwoR = NumericLiteralValue(DataType.UBYTE, 2, dummyPos) - val lvThreeR = NumericLiteralValue(DataType.UBYTE, 3, dummyPos) - val lvFour= NumericLiteralValue(DataType.UBYTE, 4, dummyPos) + val lvOne = NumericLiteralValue(DataType.UBYTE, 1.0, dummyPos) + val lvTwo = NumericLiteralValue(DataType.UBYTE, 2.0, dummyPos) + val lvThree = NumericLiteralValue(DataType.UBYTE, 3.0, dummyPos) + val lvOneR = NumericLiteralValue(DataType.UBYTE, 1.0, dummyPos) + val lvTwoR = NumericLiteralValue(DataType.UBYTE, 2.0, dummyPos) + val lvThreeR = NumericLiteralValue(DataType.UBYTE, 3.0, dummyPos) + val lvFour= NumericLiteralValue(DataType.UBYTE, 4.0, dummyPos) val lv1 = ArrayLiteralValue(InferredTypes.InferredType.known(DataType.ARRAY_UB), arrayOf(lvOne, lvTwo, lvThree), dummyPos) val lv2 = ArrayLiteralValue(InferredTypes.InferredType.known(DataType.ARRAY_UB), arrayOf(lvOneR, lvTwoR, lvThreeR), dummyPos) val lv3 = ArrayLiteralValue(InferredTypes.InferredType.known(DataType.ARRAY_UB), arrayOf(lvOneR, lvTwoR, lvFour), dummyPos) @@ -96,38 +104,38 @@ class TestNumericLiteralValue: FunSpec({ } test("testGreaterThan") { - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) > NumericLiteralValue(DataType.UBYTE, 99, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UWORD, 254, dummyPos) > NumericLiteralValue(DataType.UWORD, 253, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) > NumericLiteralValue(DataType.UBYTE, 99.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UWORD, 254.0, dummyPos) > NumericLiteralValue(DataType.UWORD, 253.0, dummyPos)) shouldBe true (NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos) > NumericLiteralValue(DataType.FLOAT, 99.9, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) >= NumericLiteralValue(DataType.UBYTE, 100, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UWORD, 254, dummyPos) >= NumericLiteralValue(DataType.UWORD, 254, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) >= NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UWORD, 254.0, dummyPos) >= NumericLiteralValue(DataType.UWORD, 254.0, dummyPos)) shouldBe true (NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos) >= NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) > NumericLiteralValue(DataType.UBYTE, 100, dummyPos)) shouldBe false - (NumericLiteralValue(DataType.UWORD, 254, dummyPos) > NumericLiteralValue(DataType.UWORD, 254, dummyPos)) shouldBe false + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) > NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos)) shouldBe false + (NumericLiteralValue(DataType.UWORD, 254.0, dummyPos) > NumericLiteralValue(DataType.UWORD, 254.0, dummyPos)) shouldBe false (NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos) > NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos)) shouldBe false - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) >= NumericLiteralValue(DataType.UBYTE, 101, dummyPos)) shouldBe false - (NumericLiteralValue(DataType.UWORD, 254, dummyPos) >= NumericLiteralValue(DataType.UWORD, 255, dummyPos)) shouldBe false + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) >= NumericLiteralValue(DataType.UBYTE, 101.0, dummyPos)) shouldBe false + (NumericLiteralValue(DataType.UWORD, 254.0, dummyPos) >= NumericLiteralValue(DataType.UWORD, 255.0, dummyPos)) shouldBe false (NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos) >= NumericLiteralValue(DataType.FLOAT, 100.1, dummyPos)) shouldBe false } test("testLessThan") { - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) < NumericLiteralValue(DataType.UBYTE, 101, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UWORD, 254, dummyPos) < NumericLiteralValue(DataType.UWORD, 255, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) < NumericLiteralValue(DataType.UBYTE, 101.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UWORD, 254.0, dummyPos) < NumericLiteralValue(DataType.UWORD, 255.0, dummyPos)) shouldBe true (NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos) < NumericLiteralValue(DataType.FLOAT, 100.1, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) <= NumericLiteralValue(DataType.UBYTE, 100, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UWORD, 254, dummyPos) <= NumericLiteralValue(DataType.UWORD, 254, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) <= NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos)) shouldBe true + (NumericLiteralValue(DataType.UWORD, 254.0, dummyPos) <= NumericLiteralValue(DataType.UWORD, 254.0, dummyPos)) shouldBe true (NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos) <= NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos)) shouldBe true - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) < NumericLiteralValue(DataType.UBYTE, 100, dummyPos)) shouldBe false - (NumericLiteralValue(DataType.UWORD, 254, dummyPos) < NumericLiteralValue(DataType.UWORD, 254, dummyPos)) shouldBe false + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) < NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos)) shouldBe false + (NumericLiteralValue(DataType.UWORD, 254.0, dummyPos) < NumericLiteralValue(DataType.UWORD, 254.0, dummyPos)) shouldBe false (NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos) < NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos)) shouldBe false - (NumericLiteralValue(DataType.UBYTE, 100, dummyPos) <= NumericLiteralValue(DataType.UBYTE, 99, dummyPos)) shouldBe false - (NumericLiteralValue(DataType.UWORD, 254, dummyPos) <= NumericLiteralValue(DataType.UWORD, 253, dummyPos)) shouldBe false + (NumericLiteralValue(DataType.UBYTE, 100.0, dummyPos) <= NumericLiteralValue(DataType.UBYTE, 99.0, dummyPos)) shouldBe false + (NumericLiteralValue(DataType.UWORD, 254.0, dummyPos) <= NumericLiteralValue(DataType.UWORD, 253.0, dummyPos)) shouldBe false (NumericLiteralValue(DataType.FLOAT, 100.0, dummyPos) <= NumericLiteralValue(DataType.FLOAT, 99.9, dummyPos)) shouldBe false } diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index 694d375ab..3c87e248f 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -75,7 +75,7 @@ class TestOptimization: FunSpec({ } test("testGeneratedConstvalueInheritsProperParentLinkage") { - val number = NumericLiteralValue(DataType.UBYTE, 11, Position.DUMMY) + val number = NumericLiteralValue(DataType.UBYTE, 11.0, Position.DUMMY) val tc = TypecastExpression(number, DataType.BYTE, false, Position.DUMMY) val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) tc.linkParents(ParentSentinel) diff --git a/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt b/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt index 585b3beb4..5309db836 100644 --- a/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt +++ b/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt @@ -262,7 +262,10 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program: } override fun visit(numLiteral: NumericLiteralValue) { - output(numLiteral.number.toString()) + if(numLiteral.type==DataType.FLOAT) + output(numLiteral.number.toString()) + else + output(numLiteral.number.toInt().toString()) } override fun visit(char: CharLiteral) { diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt index a86edfab1..0cdb8da29 100644 --- a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt +++ b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt @@ -13,7 +13,7 @@ import kotlin.io.path.isRegularFile /***************** Antlr Extension methods to create AST ****************/ -private data class NumericLiteral(val number: Number, val datatype: DataType) +private data class NumericLiteral(val number: Double, val datatype: DataType) private fun ParserRuleContext.toPosition() : Position { @@ -396,7 +396,7 @@ private fun Prog8ANTLRParser.IntegerliteralContext.toAst(): NumericLiteral { } else -> throw FatalAstException("invalid radix") } - return NumericLiteral(integer, datatype) + return NumericLiteral(integer.toDouble(), datatype) } val terminal: TerminalNode = children[0] as TerminalNode val integerPart = this.intpart.text @@ -420,11 +420,11 @@ private fun Prog8ANTLRParser.ExpressionContext.toAst() : Expression { val intLit = litval.integerliteral()?.toAst() when { intLit!=null -> when(intLit.datatype) { - DataType.UBYTE -> NumericLiteralValue(DataType.UBYTE, intLit.number.toShort(), litval.toPosition()) - DataType.BYTE -> NumericLiteralValue(DataType.BYTE, intLit.number.toShort(), litval.toPosition()) - DataType.UWORD -> NumericLiteralValue(DataType.UWORD, intLit.number.toInt(), litval.toPosition()) - DataType.WORD -> NumericLiteralValue(DataType.WORD, intLit.number.toInt(), litval.toPosition()) - DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, intLit.number.toDouble(), litval.toPosition()) + DataType.UBYTE -> NumericLiteralValue(DataType.UBYTE, intLit.number, litval.toPosition()) + DataType.BYTE -> NumericLiteralValue(DataType.BYTE, intLit.number, litval.toPosition()) + DataType.UWORD -> NumericLiteralValue(DataType.UWORD, intLit.number, litval.toPosition()) + DataType.WORD -> NumericLiteralValue(DataType.WORD, intLit.number, litval.toPosition()) + DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, intLit.number, litval.toPosition()) else -> throw FatalAstException("invalid datatype for numeric literal") } litval.floatliteral()!=null -> NumericLiteralValue(DataType.FLOAT, litval.floatliteral().toAst(), litval.toPosition()) @@ -455,7 +455,7 @@ private fun Prog8ANTLRParser.ExpressionContext.toAst() : Expression { if (rangefrom!=null && rangeto!=null) { val defaultstep = if(rto.text == "to") 1 else -1 - val step = rangestep?.toAst() ?: NumericLiteralValue(DataType.UBYTE, defaultstep, toPosition()) + val step = rangestep?.toAst() ?: NumericLiteralValue(DataType.UBYTE, defaultstep.toDouble(), toPosition()) return RangeExpr(rangefrom.toAst(), rangeto.toAst(), step, toPosition()) } diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt index 5d2654fee..2dae978ac 100644 --- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt +++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt @@ -8,6 +8,7 @@ import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstVisitor import prog8.compilerinterface.IMemSizer import java.util.* +import kotlin.math.round val associativeOperators = setOf("+", "*", "&", "|", "^", "or", "and", "xor", "==", "!=") @@ -381,43 +382,46 @@ class DirectMemoryRead(var addressExpression: Expression, override val position: } class NumericLiteralValue(val type: DataType, // only numerical types allowed - val number: Number, // can be byte, word or float depending on the type + numbervalue: Double, // can be byte, word or float depending on the type override val position: Position) : Expression() { override lateinit var parent: Node + val number: Double = if(type==DataType.FLOAT) numbervalue else round(numbervalue) override val isSimple = true fun copy() = NumericLiteralValue(type, number, position) companion object { fun fromBoolean(bool: Boolean, position: Position) = - NumericLiteralValue(DataType.UBYTE, if (bool) 1 else 0, position) + NumericLiteralValue(DataType.UBYTE, if (bool) 1.0 else 0.0, position) fun optimalNumeric(value: Number, position: Position): NumericLiteralValue { return if(value is Double) { NumericLiteralValue(DataType.FLOAT, value, position) } else { - when (val intval = value.toInt()) { - in 0..255 -> NumericLiteralValue(DataType.UBYTE, intval, position) - in -128..127 -> NumericLiteralValue(DataType.BYTE, intval, position) - in 0..65535 -> NumericLiteralValue(DataType.UWORD, intval, position) - in -32768..32767 -> NumericLiteralValue(DataType.WORD, intval, position) - else -> NumericLiteralValue(DataType.FLOAT, intval.toDouble(), position) + val dvalue = value.toDouble() + when (value.toInt()) { + in 0..255 -> NumericLiteralValue(DataType.UBYTE, dvalue, position) + in -128..127 -> NumericLiteralValue(DataType.BYTE, dvalue, position) + in 0..65535 -> NumericLiteralValue(DataType.UWORD, dvalue, position) + in -32768..32767 -> NumericLiteralValue(DataType.WORD, dvalue, position) + else -> NumericLiteralValue(DataType.FLOAT, dvalue, position) } } } fun optimalInteger(value: Int, position: Position): NumericLiteralValue { + val dvalue = value.toDouble() return when (value) { - in 0..255 -> NumericLiteralValue(DataType.UBYTE, value, position) - in -128..127 -> NumericLiteralValue(DataType.BYTE, value, position) - in 0..65535 -> NumericLiteralValue(DataType.UWORD, value, position) - in -32768..32767 -> NumericLiteralValue(DataType.WORD, value, position) - else -> throw FatalAstException("integer overflow: $value") + in 0..255 -> NumericLiteralValue(DataType.UBYTE, dvalue, position) + in -128..127 -> NumericLiteralValue(DataType.BYTE, dvalue, position) + in 0..65535 -> NumericLiteralValue(DataType.UWORD, dvalue, position) + in -32768..32767 -> NumericLiteralValue(DataType.WORD, dvalue, position) + else -> throw FatalAstException("integer overflow: $dvalue") } } } - val asBooleanValue: Boolean = number.toDouble() != 0.0 + val asBooleanValue: Boolean = number != 0.0 override fun linkParents(parent: Node) { this.parent = parent @@ -442,13 +446,13 @@ class NumericLiteralValue(val type: DataType, // only numerical types allowed override fun equals(other: Any?): Boolean { if(other==null || other !is NumericLiteralValue) return false - return number.toDouble()==other.number.toDouble() + return number==other.number } - operator fun compareTo(other: NumericLiteralValue): Int = number.toDouble().compareTo(other.number.toDouble()) + operator fun compareTo(other: NumericLiteralValue): Int = number.compareTo(other.number) class CastValue(val isValid: Boolean, private val value: NumericLiteralValue?) { - fun valueOrZero() = if(isValid) value!! else NumericLiteralValue(DataType.UBYTE, 0, Position.DUMMY) + fun valueOrZero() = if(isValid) value!! else NumericLiteralValue(DataType.UBYTE, 0.0, Position.DUMMY) fun linkParent(parent: Node) { value?.linkParents(parent) } @@ -463,55 +467,54 @@ class NumericLiteralValue(val type: DataType, // only numerical types allowed private fun internalCast(targettype: DataType): CastValue { if(type==targettype) return CastValue(true, this) - val numval = number.toDouble() when(type) { DataType.UBYTE -> { - if(targettype== DataType.BYTE && numval <= 127) - return CastValue(true, NumericLiteralValue(targettype, number.toShort(), position)) + if(targettype== DataType.BYTE && number <= 127) + return CastValue(true, NumericLiteralValue(targettype, number, position)) if(targettype== DataType.WORD || targettype== DataType.UWORD) - return CastValue(true, NumericLiteralValue(targettype, number.toInt(), position)) + return CastValue(true, NumericLiteralValue(targettype, number, position)) if(targettype== DataType.FLOAT) - return CastValue(true, NumericLiteralValue(targettype, number.toDouble(), position)) + return CastValue(true, NumericLiteralValue(targettype, number, position)) } DataType.BYTE -> { - if(targettype== DataType.UBYTE && numval >= 0) - return CastValue(true, NumericLiteralValue(targettype, number.toShort(), position)) - if(targettype== DataType.UWORD && numval >= 0) - return CastValue(true, NumericLiteralValue(targettype, number.toInt(), position)) + if(targettype== DataType.UBYTE && number >= 0) + return CastValue(true, NumericLiteralValue(targettype, number, position)) + if(targettype== DataType.UWORD && number >= 0) + return CastValue(true, NumericLiteralValue(targettype, number, position)) if(targettype== DataType.WORD) - return CastValue(true, NumericLiteralValue(targettype, number.toInt(), position)) + return CastValue(true, NumericLiteralValue(targettype, number, position)) if(targettype== DataType.FLOAT) - return CastValue(true, NumericLiteralValue(targettype, number.toDouble(), position)) + return CastValue(true, NumericLiteralValue(targettype, number, position)) } DataType.UWORD -> { - if(targettype== DataType.BYTE && numval <= 127) - return CastValue(true, NumericLiteralValue(targettype, number.toShort(), position)) - if(targettype== DataType.UBYTE && numval <= 255) - return CastValue(true, NumericLiteralValue(targettype, number.toShort(), position)) - if(targettype== DataType.WORD && numval <= 32767) - return CastValue(true, NumericLiteralValue(targettype, number.toInt(), position)) + if(targettype== DataType.BYTE && number <= 127) + return CastValue(true, NumericLiteralValue(targettype, number, position)) + if(targettype== DataType.UBYTE && number <= 255) + return CastValue(true, NumericLiteralValue(targettype, number, position)) + if(targettype== DataType.WORD && number <= 32767) + return CastValue(true, NumericLiteralValue(targettype, number, position)) if(targettype== DataType.FLOAT) - return CastValue(true, NumericLiteralValue(targettype, number.toDouble(), position)) + return CastValue(true, NumericLiteralValue(targettype, number, position)) } DataType.WORD -> { - if(targettype== DataType.BYTE && numval >= -128 && numval <=127) - return CastValue(true, NumericLiteralValue(targettype, number.toShort(), position)) - if(targettype== DataType.UBYTE && numval >= 0 && numval <= 255) - return CastValue(true, NumericLiteralValue(targettype, number.toShort(), position)) - if(targettype== DataType.UWORD && numval >=0) - return CastValue(true, NumericLiteralValue(targettype, number.toInt(), position)) + if(targettype== DataType.BYTE && number >= -128 && number <=127) + return CastValue(true, NumericLiteralValue(targettype, number, position)) + if(targettype== DataType.UBYTE && number >= 0 && number <= 255) + return CastValue(true, NumericLiteralValue(targettype, number, position)) + if(targettype== DataType.UWORD && number >=0) + return CastValue(true, NumericLiteralValue(targettype, number, position)) if(targettype== DataType.FLOAT) - return CastValue(true, NumericLiteralValue(targettype, number.toDouble(), position)) + return CastValue(true, NumericLiteralValue(targettype, number, position)) } DataType.FLOAT -> { - if (targettype == DataType.BYTE && numval >= -128 && numval <=127) - return CastValue(true, NumericLiteralValue(targettype, number.toShort(), position)) - if (targettype == DataType.UBYTE && numval >=0 && numval <= 255) - return CastValue(true, NumericLiteralValue(targettype, number.toShort(), position)) - if (targettype == DataType.WORD && numval >= -32768 && numval <= 32767) - return CastValue(true, NumericLiteralValue(targettype, number.toInt(), position)) - if (targettype == DataType.UWORD && numval >=0 && numval <= 65535) - return CastValue(true, NumericLiteralValue(targettype, number.toInt(), position)) + if (targettype == DataType.BYTE && number >= -128 && number <=127) + return CastValue(true, NumericLiteralValue(targettype, number, position)) + if (targettype == DataType.UBYTE && number >=0 && number <= 255) + return CastValue(true, NumericLiteralValue(targettype, number, position)) + if (targettype == DataType.WORD && number >= -32768 && number <= 32767) + return CastValue(true, NumericLiteralValue(targettype, number, position)) + if (targettype == DataType.UWORD && number >=0 && number <= 65535) + return CastValue(true, NumericLiteralValue(targettype, number, position)) } else -> {} } @@ -537,7 +540,7 @@ class CharLiteral(val value: Char, override fun referencesIdentifier(vararg scopedName: String) = false override fun constValue(program: Program): NumericLiteralValue { val bytevalue = program.encoding.encodeString(value.toString(), altEncoding).single() - return NumericLiteralValue(DataType.UBYTE, bytevalue, position) + return NumericLiteralValue(DataType.UBYTE, bytevalue.toDouble(), position) } override fun accept(visitor: IAstVisitor) = visitor.visit(this) override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent) @@ -620,14 +623,6 @@ class ArrayLiteralValue(val type: InferredTypes.InferredType, // inferred be return type==other.type && value.contentEquals(other.value) } - fun memsize(memsizer: IMemSizer): Int { - if(type.isKnown) { - val eltType = ArrayToElementTypes.getValue(type.getOr(DataType.UNDEFINED)) - return memsizer.memorySize(eltType) * value.size - } - else throw IllegalArgumentException("array datatype is not yet known") - } - fun guessDatatype(program: Program): InferredTypes.InferredType { // Educated guess of the desired array literal's datatype. // If it's inside a for loop, assume the data type of the loop variable is what we want. diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index 30860df81..53f338d10 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -207,10 +207,10 @@ open class VarDecl(val type: VarDeclType, } fun defaultZero(dt: DataType, position: Position) = when(dt) { - DataType.UBYTE -> NumericLiteralValue(DataType.UBYTE, 0, position) - DataType.BYTE -> NumericLiteralValue(DataType.BYTE, 0, position) - DataType.UWORD, DataType.STR -> NumericLiteralValue(DataType.UWORD, 0, position) - DataType.WORD -> NumericLiteralValue(DataType.WORD, 0, position) + DataType.UBYTE -> NumericLiteralValue(DataType.UBYTE, 0.0, position) + DataType.BYTE -> NumericLiteralValue(DataType.BYTE, 0.0, position) + DataType.UWORD, DataType.STR -> NumericLiteralValue(DataType.UWORD, 0.0, position) + DataType.WORD -> NumericLiteralValue(DataType.WORD, 0.0, position) DataType.FLOAT -> NumericLiteralValue(DataType.FLOAT, 0.0, position) else -> throw FatalAstException("can only determine default zero value for a numeric type") } diff --git a/compilerAst/src/prog8/parser/SourceCode.kt b/compilerAst/src/prog8/parser/SourceCode.kt index db452fe2d..ddbf51bd7 100644 --- a/compilerAst/src/prog8/parser/SourceCode.kt +++ b/compilerAst/src/prog8/parser/SourceCode.kt @@ -132,7 +132,7 @@ sealed class SourceCode { val inpStr = object {}.javaClass.getResourceAsStream(normalized)!! // CharStreams.fromStream() doesn't allow us to set the stream name properly, so we use a lower level api val channel = Channels.newChannel(inpStr) - return CharStreams.fromChannel(channel, StandardCharsets.UTF_8, 4096, CodingErrorAction.REPLACE, origin, -1); + return CharStreams.fromChannel(channel, StandardCharsets.UTF_8, 4096, CodingErrorAction.REPLACE, origin, -1) } override fun readText(): String { diff --git a/compilerAst/test/TestProg8Parser.kt b/compilerAst/test/TestProg8Parser.kt index b9bfb7c58..8d542e1a4 100644 --- a/compilerAst/test/TestProg8Parser.kt +++ b/compilerAst/test/TestProg8Parser.kt @@ -540,8 +540,8 @@ class TestProg8Parser: FunSpec( { } test("testLiteralValueComparisons") { - val ten = NumericLiteralValue(DataType.UWORD, 10, Position.DUMMY) - val nine = NumericLiteralValue(DataType.UBYTE, 9, Position.DUMMY) + val ten = NumericLiteralValue(DataType.UWORD, 10.0, Position.DUMMY) + val nine = NumericLiteralValue(DataType.UBYTE, 9.0, Position.DUMMY) ten shouldBe ten nine shouldNotBe ten (ten != ten) shouldBe false diff --git a/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt b/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt index 1eb5b9b38..849d44beb 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt @@ -126,17 +126,17 @@ private val functionSignatures: List = listOf( FSignature("atan" , true, listOf(FParam("rads", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArg(a, p, prg, Math::atan) }, FSignature("ln" , true, listOf(FParam("value", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArg(a, p, prg, Math::log) }, FSignature("log2" , true, listOf(FParam("value", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArg(a, p, prg, ::log2) }, - FSignature("sqrt16" , true, listOf(FParam("value", arrayOf(DataType.UWORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { sqrt(it.toDouble()).toInt() } }, + FSignature("sqrt16" , true, listOf(FParam("value", arrayOf(DataType.UWORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { sqrt(it.toDouble()) } }, FSignature("sqrt" , true, listOf(FParam("value", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArg(a, p, prg, Math::sqrt) }, FSignature("rad" , true, listOf(FParam("value", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArg(a, p, prg, Math::toRadians) }, FSignature("deg" , true, listOf(FParam("value", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArg(a, p, prg, Math::toDegrees) }, - FSignature("round" , true, listOf(FParam("value", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArgOutputWord(a, p, prg, Math::round) }, + FSignature("round" , true, listOf(FParam("value", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArgOutputWord(a, p, prg, ::round) }, FSignature("floor" , true, listOf(FParam("value", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArgOutputWord(a, p, prg, Math::floor) }, FSignature("ceil" , true, listOf(FParam("value", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArgOutputWord(a, p, prg, Math::ceil) }, FSignature("any" , true, listOf(FParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, prg -> collectionArg(a, p, prg, ::builtinAny) }, FSignature("all" , true, listOf(FParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, prg -> collectionArg(a, p, prg, ::builtinAll) }, - FSignature("lsb" , true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { x: Int -> x and 255 } }, - FSignature("msb" , true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { x: Int -> x ushr 8 and 255} }, + FSignature("lsb" , true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { x: Int -> (x and 255).toDouble() } }, + FSignature("msb" , true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { x: Int -> (x ushr 8 and 255).toDouble()} }, FSignature("mkword" , true, listOf(FParam("msb", arrayOf(DataType.UBYTE)), FParam("lsb", arrayOf(DataType.UBYTE))), DataType.UWORD, ::builtinMkword), FSignature("peek" , true, listOf(FParam("address", arrayOf(DataType.UWORD))), DataType.UBYTE), FSignature("peekw" , true, listOf(FParam("address", arrayOf(DataType.UWORD))), DataType.UWORD), @@ -155,15 +155,15 @@ private val functionSignatures: List = listOf( val BuiltinFunctions = functionSignatures.associateBy { it.name } -private fun builtinMax(array: List): Number = array.maxByOrNull { it.toDouble() }!! +private fun builtinMax(array: List): Double = array.maxByOrNull { it }!! -private fun builtinMin(array: List): Number = array.minByOrNull { it.toDouble() }!! +private fun builtinMin(array: List): Double = array.minByOrNull { it }!! -private fun builtinSum(array: List): Number = array.sumOf { it.toDouble() } +private fun builtinSum(array: List): Double = array.sumOf { it } -private fun builtinAny(array: List): Number = if(array.any { it.toDouble()!=0.0 }) 1 else 0 +private fun builtinAny(array: List): Double = if(array.any { it!=0.0 }) 1.0 else 0.0 -private fun builtinAll(array: List): Number = if(array.all { it.toDouble()!=0.0 }) 1 else 0 +private fun builtinAll(array: List): Double = if(array.all { it!=0.0 }) 1.0 else 0.0 fun builtinFunctionReturnType(function: String, args: List, program: Program): InferredTypes.InferredType { @@ -243,19 +243,18 @@ private fun oneDoubleArg(args: List, position: Position, program: Pr if(args.size!=1) throw SyntaxError("built-in function requires one floating point argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val float = constval.number.toDouble() + val float = constval.number return numericLiteral(function(float), args[0].position) } -private fun oneDoubleArgOutputWord(args: List, position: Position, program: Program, function: (arg: Double)->Number): NumericLiteralValue { +private fun oneDoubleArgOutputWord(args: List, position: Position, program: Program, function: (arg: Double)->Double): NumericLiteralValue { if(args.size!=1) throw SyntaxError("built-in function requires one floating point argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val float = constval.number.toDouble() - return NumericLiteralValue(DataType.WORD, function(float).toInt(), args[0].position) + return NumericLiteralValue(DataType.WORD, function(constval.number), args[0].position) } -private fun oneIntArgOutputInt(args: List, position: Position, program: Program, function: (arg: Int)->Number): NumericLiteralValue { +private fun oneIntArgOutputInt(args: List, position: Position, program: Program, function: (arg: Int)->Double): NumericLiteralValue { if(args.size!=1) throw SyntaxError("built-in function requires one integer argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() @@ -266,7 +265,7 @@ private fun oneIntArgOutputInt(args: List, position: Position, progr return numericLiteral(function(integer).toInt(), args[0].position) } -private fun collectionArg(args: List, position: Position, program: Program, function: (arg: List)->Number): NumericLiteralValue { +private fun collectionArg(args: List, position: Position, program: Program, function: (arg: List)->Double): NumericLiteralValue { if(args.size!=1) throw SyntaxError("builtin function requires one non-scalar argument", position) @@ -287,7 +286,7 @@ private fun builtinAbs(args: List, position: Position, program: Prog val constval = args[0].constValue(program) ?: throw NotConstArgumentException() return when (constval.type) { in IntegerDatatypes -> numericLiteral(abs(constval.number.toInt()), args[0].position) - DataType.FLOAT -> numericLiteral(abs(constval.number.toDouble()), args[0].position) + DataType.FLOAT -> numericLiteral(abs(constval.number), args[0].position) else -> throw SyntaxError("abs requires one numeric argument", position) } } @@ -311,7 +310,7 @@ private fun builtinSizeof(args: List, position: Position, program: P numericLiteral(program.memsizer.memorySize(elementDt) * length, position) } dt istype DataType.STR -> throw SyntaxError("sizeof str is undefined, did you mean len?", position) - else -> NumericLiteralValue(DataType.UBYTE, program.memsizer.memorySize(dt.getOr(DataType.UNDEFINED)), position) + else -> NumericLiteralValue(DataType.UBYTE, program.memsizer.memorySize(dt.getOr(DataType.UNDEFINED)).toDouble(), position) } } else { throw SyntaxError("sizeof invalid argument type", position) @@ -359,7 +358,7 @@ private fun builtinMkword(args: List, position: Position, program: P val constMsb = args[0].constValue(program) ?: throw NotConstArgumentException() val constLsb = args[1].constValue(program) ?: throw NotConstArgumentException() val result = (constMsb.number.toInt() shl 8) or constLsb.number.toInt() - return NumericLiteralValue(DataType.UWORD, result, position) + return NumericLiteralValue(DataType.UWORD, result.toDouble(), position) } @Suppress("UNUSED_PARAMETER") @@ -367,8 +366,8 @@ private fun builtinSin8(args: List, position: Position, program: Pro if (args.size != 1) throw SyntaxError("sin8 requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() /256.0 * 2.0 * PI - return NumericLiteralValue(DataType.BYTE, (127.0 * sin(rad)).toInt().toShort(), position) + val rad = constval.number /256.0 * 2.0 * PI + return NumericLiteralValue(DataType.BYTE, 127.0 * sin(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -376,8 +375,8 @@ private fun builtinSin8u(args: List, position: Position, program: Pr if (args.size != 1) throw SyntaxError("sin8u requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() /256.0 * 2.0 * PI - return NumericLiteralValue(DataType.UBYTE, (128.0 + 127.5 * sin(rad)).toInt().toShort(), position) + val rad = constval.number /256.0 * 2.0 * PI + return NumericLiteralValue(DataType.UBYTE, 128.0 + 127.5 * sin(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -385,8 +384,8 @@ private fun builtinSinR8(args: List, position: Position, program: Pr if (args.size != 1) throw SyntaxError("sinr8 requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() / 180.0 * 2.0 * PI - return NumericLiteralValue(DataType.BYTE, (127.0 * sin(rad)).toInt().toShort(), position) + val rad = constval.number / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.BYTE, 127.0 * sin(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -394,8 +393,8 @@ private fun builtinSinR8u(args: List, position: Position, program: P if (args.size != 1) throw SyntaxError("sinr8u requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() / 180.0 * 2.0 * PI - return NumericLiteralValue(DataType.UBYTE, (128.0 + 127.5 * sin(rad)).toInt().toShort(), position) + val rad = constval.number / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.UBYTE, 128.0 + 127.5 * sin(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -403,8 +402,8 @@ private fun builtinCos8(args: List, position: Position, program: Pro if (args.size != 1) throw SyntaxError("cos8 requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() /256.0 * 2.0 * PI - return NumericLiteralValue(DataType.BYTE, (127.0 * cos(rad)).toInt().toShort(), position) + val rad = constval.number /256.0 * 2.0 * PI + return NumericLiteralValue(DataType.BYTE, 127.0 * cos(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -412,8 +411,8 @@ private fun builtinCos8u(args: List, position: Position, program: Pr if (args.size != 1) throw SyntaxError("cos8u requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() /256.0 * 2.0 * PI - return NumericLiteralValue(DataType.UBYTE, (128.0 + 127.5 * cos(rad)).toInt().toShort(), position) + val rad = constval.number /256.0 * 2.0 * PI + return NumericLiteralValue(DataType.UBYTE, 128.0 + 127.5 * cos(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -421,8 +420,8 @@ private fun builtinCosR8(args: List, position: Position, program: Pr if (args.size != 1) throw SyntaxError("cosr8 requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() / 180.0 * 2.0 * PI - return NumericLiteralValue(DataType.BYTE, (127.0 * cos(rad)).toInt().toShort(), position) + val rad = constval.number / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.BYTE, 127.0 * cos(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -430,8 +429,8 @@ private fun builtinCosR8u(args: List, position: Position, program: P if (args.size != 1) throw SyntaxError("cosr8u requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() / 180.0 * 2.0 * PI - return NumericLiteralValue(DataType.UBYTE, (128.0 + 127.5 * cos(rad)).toInt().toShort(), position) + val rad = constval.number / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.UBYTE, 128.0 + 127.5 * cos(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -439,8 +438,8 @@ private fun builtinSin16(args: List, position: Position, program: Pr if (args.size != 1) throw SyntaxError("sin16 requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() /256.0 * 2.0 * PI - return NumericLiteralValue(DataType.WORD, (32767.0 * sin(rad)).toInt(), position) + val rad = constval.number /256.0 * 2.0 * PI + return NumericLiteralValue(DataType.WORD, 32767.0 * sin(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -448,8 +447,8 @@ private fun builtinSin16u(args: List, position: Position, program: P if (args.size != 1) throw SyntaxError("sin16u requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() /256.0 * 2.0 * PI - return NumericLiteralValue(DataType.UWORD, (32768.0 + 32767.5 * sin(rad)).toInt(), position) + val rad = constval.number /256.0 * 2.0 * PI + return NumericLiteralValue(DataType.UWORD, 32768.0 + 32767.5 * sin(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -457,8 +456,8 @@ private fun builtinSinR16(args: List, position: Position, program: P if (args.size != 1) throw SyntaxError("sinr16 requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() / 180.0 * 2.0 * PI - return NumericLiteralValue(DataType.WORD, (32767.0 * sin(rad)).toInt(), position) + val rad = constval.number / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.WORD, 32767.0 * sin(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -466,8 +465,8 @@ private fun builtinSinR16u(args: List, position: Position, program: if (args.size != 1) throw SyntaxError("sinr16u requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() / 180.0 * 2.0 * PI - return NumericLiteralValue(DataType.UWORD, (32768.0 + 32767.5 * sin(rad)).toInt(), position) + val rad = constval.number / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.UWORD, 32768.0 + 32767.5 * sin(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -475,8 +474,8 @@ private fun builtinCos16(args: List, position: Position, program: Pr if (args.size != 1) throw SyntaxError("cos16 requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() /256.0 * 2.0 * PI - return NumericLiteralValue(DataType.WORD, (32767.0 * cos(rad)).toInt(), position) + val rad = constval.number /256.0 * 2.0 * PI + return NumericLiteralValue(DataType.WORD, 32767.0 * cos(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -484,8 +483,8 @@ private fun builtinCos16u(args: List, position: Position, program: P if (args.size != 1) throw SyntaxError("cos16u requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() /256.0 * 2.0 * PI - return NumericLiteralValue(DataType.UWORD, (32768.0 + 32767.5 * cos(rad)).toInt(), position) + val rad = constval.number /256.0 * 2.0 * PI + return NumericLiteralValue(DataType.UWORD, 32768.0 + 32767.5 * cos(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -493,8 +492,8 @@ private fun builtinCosR16(args: List, position: Position, program: P if (args.size != 1) throw SyntaxError("cosr16 requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() / 180.0 * 2.0 * PI - return NumericLiteralValue(DataType.WORD, (32767.0 * cos(rad)).toInt(), position) + val rad = constval.number / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.WORD, 32767.0 * cos(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -502,8 +501,8 @@ private fun builtinCosR16u(args: List, position: Position, program: if (args.size != 1) throw SyntaxError("cosr16u requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - val rad = constval.number.toDouble() / 180.0 * 2.0 * PI - return NumericLiteralValue(DataType.UWORD, (32768.0 + 32767.5 * cos(rad)).toInt(), position) + val rad = constval.number / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.UWORD, 32768.0 + 32767.5 * cos(rad), position) } @Suppress("UNUSED_PARAMETER") @@ -511,7 +510,7 @@ private fun builtinSgn(args: List, position: Position, program: Prog if (args.size != 1) throw SyntaxError("sgn requires one argument", position) val constval = args[0].constValue(program) ?: throw NotConstArgumentException() - return NumericLiteralValue(DataType.BYTE, constval.number.toDouble().sign.toInt().toShort(), position) + return NumericLiteralValue(DataType.BYTE, constval.number.sign, position) } private fun numericLiteral(value: Number, position: Position): NumericLiteralValue { @@ -525,7 +524,7 @@ private fun numericLiteral(value: Number, position: Position): NumericLiteralVal return when(tweakedValue) { is Int -> NumericLiteralValue.optimalInteger(value.toInt(), position) is Short -> NumericLiteralValue.optimalInteger(value.toInt(), position) - is Byte -> NumericLiteralValue(DataType.UBYTE, value.toShort(), position) + is Byte -> NumericLiteralValue(DataType.UBYTE, value.toDouble(), position) is Double -> NumericLiteralValue(DataType.FLOAT, value.toDouble(), position) is Float -> NumericLiteralValue(DataType.FLOAT, value.toDouble(), position) else -> throw FatalAstException("invalid number type ${value::class}") diff --git a/compilerInterfaces/src/prog8/compilerinterface/Zeropage.kt b/compilerInterfaces/src/prog8/compilerinterface/Zeropage.kt index 06183ed38..961cad586 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/Zeropage.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/Zeropage.kt @@ -23,7 +23,7 @@ abstract class Zeropage(protected val options: CompilationOptions) { for (reserved in options.zpReserved) reserve(reserved) - free.removeAll(listOf(SCRATCH_B1, SCRATCH_REG, SCRATCH_W1, SCRATCH_W1 + 1, SCRATCH_W2, SCRATCH_W2 + 1)) + free.removeAll(setOf(SCRATCH_B1, SCRATCH_REG, SCRATCH_W1, SCRATCH_W1 + 1, SCRATCH_W2, SCRATCH_W2 + 1)) } fun availableBytes() = if(options.zeropage== ZeropageType.DONTUSE) 0 else free.size diff --git a/examples/test.p8 b/examples/test.p8 index 1c5a0f2e1..ad290db0a 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,78 +3,27 @@ main { sub start() { - ubyte xx=10 - txt.print("if\n") - if xx-2 { - txt.print("in if\n") - } + ubyte xx = 1.234 + ubyte yy = 2.234 + uword aw - txt.print("\nwhile\n") - xx=6 - while xx-2 { - xx-- - txt.print_ub(xx) - txt.spc() - } + ; TODO: bitwise operations with a negative constant number -> replace the number by its positive 2 complement - txt.print("\nuntil\n") - xx=2 - do { - xx++ - txt.print_ub(xx) - txt.spc() - } until xx+2==10 - txt.print("\ndone") + aw = xx ^ 65535 + aw = ~xx + yy = xx ^ 255 + yy = ~xx + +; *(&X) => X +; X % 1 => 0 +; X / 1 => X +; X ^ -1 => ~x +; X >= 1 => X > 0 +; X < 1 => X <= 0 + + txt.print_ub(yy) + txt.print_uw(aw) - repeat { - } } - - -; if not iteration_in_progress or not num_bytes -; return - -; word xx=0 -; word[] xarr = [1,2,3] -; ubyte ai -; -; if not @($c000) { -; txt.print("xx is zero\n") -; } -; -; while not xarr[ai] { -; xx ++ -; } -; -; do { -; xx-- -; } until not xarr[ai] -; -; if not xarr[ai] { -; txt.print("xx is zero\n") -; } - -; ubyte yy=$30 -; ubyte zz=9 -; sys.memset(xx+200, yy*2, ~yy) -; -; -; if yy & %10000 { -; yy++ -; } -; -; @($c030) = 10 -; @(~xx) *= 2 -; txt.print_ub(@($c030)) -; -; float f1 = 1111.11 -; float f2 = 2222.22 -; float[] fa = [2222.22, 3333.33] -; -; swap(f1, fa[1]) -; floats.print_f(f1) -; txt.nl() -; floats.print_f(fa[1]) - }