mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
simplified NumericLiteral to always just contain a Double instead of a Number for the value
This commit is contained in:
parent
964e8e0a17
commit
f48d6ca9f8
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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<<x) if both operands are integer.
|
||||
val leftDt = leftconst.inferType(program).getOr(DataType.UNDEFINED)
|
||||
when (leftconst.number.toDouble()) {
|
||||
when (leftconst.number) {
|
||||
0.0 -> {
|
||||
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)
|
||||
}
|
||||
|
@ -38,9 +38,9 @@ class VarConstantValueTypeAdjuster(private val program: Program, private val err
|
||||
}
|
||||
|
||||
override fun after(range: RangeExpr, parent: Node): Iterable<IAstModification> {
|
||||
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<Expression>()
|
||||
val array = Array(size) {fillvalue}.map { NumericLiteralValue(ArrayToElementTypes.getValue(decl.datatype), it.toDouble(), numericLv.position) }.toTypedArray<Expression>()
|
||||
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 {
|
||||
|
@ -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)
|
||||
|
@ -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 <operator> <expr>
|
||||
// remove assignments that have no effect (such as X=X+0)
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -44,7 +44,7 @@ internal fun Program.charLiteralsToUByteLiterals(enc: IStringEncoding) {
|
||||
override fun after(char: CharLiteral, parent: Node): Iterable<IAstModification> {
|
||||
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
|
||||
))
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -94,6 +94,13 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter)
|
||||
override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -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<IdentifierReference>() // make test fail
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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())
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -126,17 +126,17 @@ private val functionSignatures: List<FSignature> = 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<FSignature> = listOf(
|
||||
val BuiltinFunctions = functionSignatures.associateBy { it.name }
|
||||
|
||||
|
||||
private fun builtinMax(array: List<Number>): Number = array.maxByOrNull { it.toDouble() }!!
|
||||
private fun builtinMax(array: List<Double>): Double = array.maxByOrNull { it }!!
|
||||
|
||||
private fun builtinMin(array: List<Number>): Number = array.minByOrNull { it.toDouble() }!!
|
||||
private fun builtinMin(array: List<Double>): Double = array.minByOrNull { it }!!
|
||||
|
||||
private fun builtinSum(array: List<Number>): Number = array.sumOf { it.toDouble() }
|
||||
private fun builtinSum(array: List<Double>): Double = array.sumOf { it }
|
||||
|
||||
private fun builtinAny(array: List<Number>): Number = if(array.any { it.toDouble()!=0.0 }) 1 else 0
|
||||
private fun builtinAny(array: List<Double>): Double = if(array.any { it!=0.0 }) 1.0 else 0.0
|
||||
|
||||
private fun builtinAll(array: List<Number>): Number = if(array.all { it.toDouble()!=0.0 }) 1 else 0
|
||||
private fun builtinAll(array: List<Double>): Double = if(array.all { it!=0.0 }) 1.0 else 0.0
|
||||
|
||||
fun builtinFunctionReturnType(function: String, args: List<Expression>, program: Program): InferredTypes.InferredType {
|
||||
|
||||
@ -243,19 +243,18 @@ private fun oneDoubleArg(args: List<Expression>, 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<Expression>, position: Position, program: Program, function: (arg: Double)->Number): NumericLiteralValue {
|
||||
private fun oneDoubleArgOutputWord(args: List<Expression>, 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<Expression>, position: Position, program: Program, function: (arg: Int)->Number): NumericLiteralValue {
|
||||
private fun oneIntArgOutputInt(args: List<Expression>, 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<Expression>, position: Position, progr
|
||||
return numericLiteral(function(integer).toInt(), args[0].position)
|
||||
}
|
||||
|
||||
private fun collectionArg(args: List<Expression>, position: Position, program: Program, function: (arg: List<Number>)->Number): NumericLiteralValue {
|
||||
private fun collectionArg(args: List<Expression>, position: Position, program: Program, function: (arg: List<Double>)->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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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<Expression>, 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}")
|
||||
|
@ -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
|
||||
|
@ -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])
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user