simplified NumericLiteral to always just contain a Double instead of a Number for the value

This commit is contained in:
Irmen de Jong
2021-11-16 23:52:30 +01:00
parent 964e8e0a17
commit f48d6ca9f8
29 changed files with 350 additions and 387 deletions

View File

@@ -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}")

View File

@@ -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