diff --git a/codeCore/src/prog8/code/core/BuiltinFunctions.kt b/codeCore/src/prog8/code/core/BuiltinFunctions.kt index cf9f9a57c..bb7f8cfe6 100644 --- a/codeCore/src/prog8/code/core/BuiltinFunctions.kt +++ b/codeCore/src/prog8/code/core/BuiltinFunctions.kt @@ -93,6 +93,8 @@ val BuiltinFunctions: Map = mapOf( "lsb" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE), "msb" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE), "mkword" to FSignature(true, listOf(FParam("msb", arrayOf(DataType.UBYTE)), FParam("lsb", arrayOf(DataType.UBYTE))), DataType.UWORD), + "min" to FSignature(true, listOf(), null), + "max" to FSignature(true, listOf(), null), "min__byte" to FSignature(true, listOf(FParam("val1", arrayOf(DataType.BYTE)), FParam("val2", arrayOf(DataType.BYTE))), DataType.BYTE), "min__ubyte" to FSignature(true, listOf(FParam("val1", arrayOf(DataType.UBYTE)), FParam("val2", arrayOf(DataType.UBYTE))), DataType.UBYTE), "min__word" to FSignature(true, listOf(FParam("val1", arrayOf(DataType.WORD)), FParam("val2", arrayOf(DataType.WORD))), DataType.WORD), diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index 4c27e8503..972aa2d64 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -844,7 +844,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, val targetReg = AsmAssignTarget.fromRegisters(resultRegister!!, signed, fcall.position, fcall.definingISub(), asmgen) asmgen.assignRegister(RegisterOrPair.A, targetReg) } - } else { + } else if(fcall.type in WordDatatypes) { asmgen.assignExpressionToVariable(fcall.args[0], "P8ZP_SCRATCH_W1", fcall.type) // left asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W2", fcall.type) // right if(signed) { @@ -885,6 +885,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, val targetReg = AsmAssignTarget.fromRegisters(resultRegister!!, signed, fcall.position, fcall.definingISub(), asmgen) asmgen.assignRegister(RegisterOrPair.AY, targetReg) } + } else { + throw AssemblyError("min float not supported") } } @@ -904,7 +906,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, val targetReg = AsmAssignTarget.fromRegisters(resultRegister!!, signed, fcall.position, fcall.definingISub(), asmgen) asmgen.assignRegister(RegisterOrPair.A, targetReg) } - } else { + } else if(fcall.type in WordDatatypes) { asmgen.assignExpressionToVariable(fcall.args[0], "P8ZP_SCRATCH_W1", fcall.type) // left asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W2", fcall.type) // right if(signed) { @@ -945,6 +947,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, val targetReg = AsmAssignTarget.fromRegisters(resultRegister!!, signed, fcall.position, fcall.definingISub(), asmgen) asmgen.assignRegister(RegisterOrPair.AY, targetReg) } + } else { + throw AssemblyError("max float not supported") } } diff --git a/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt b/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt index 7765daac8..f2419f796 100644 --- a/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt +++ b/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt @@ -89,7 +89,8 @@ class VarConstantValueTypeAdjuster(private val program: Program, private val err else "${funcName}__uword" } else if(t1.isNumeric && t2.isNumeric) { - replaceFunc = "${funcName}__float" + errors.err("min/max not supported for floats", functionCallExpr.position) + return noModifications } else { errors.err("expected numeric arguments", functionCallExpr.position) return noModifications diff --git a/compiler/res/prog8lib/floats_functions.p8 b/compiler/res/prog8lib/floats_functions.p8 index cf88643c2..9e57ad017 100644 --- a/compiler/res/prog8lib/floats_functions.p8 +++ b/compiler/res/prog8lib/floats_functions.p8 @@ -237,4 +237,18 @@ sub rndseedf(float seed) { }} } + +sub minf(float f1, float f2) -> float { + if f1 float { + if f1>f2 + return f1 + return f2 +} + } diff --git a/compiler/src/prog8/compiler/BuiltinFunctions.kt b/compiler/src/prog8/compiler/BuiltinFunctions.kt index 7bb987d8c..1ce314673 100644 --- a/compiler/src/prog8/compiler/BuiltinFunctions.kt +++ b/compiler/src/prog8/compiler/BuiltinFunctions.kt @@ -29,7 +29,7 @@ internal val constEvaluatorsForBuiltinFuncs: Map "max__ubyte" to ::builtinMaxUByte, "max__byte" to ::builtinMaxByte, "max__uword" to ::builtinMaxUWord, - "max__word" to ::builtinMaxWord, + "max__word" to ::builtinMaxWord ) private fun builtinAny(array: List): Double = if(array.any { it!=0.0 }) 1.0 else 0.0 diff --git a/docs/source/index.rst b/docs/source/index.rst index 7d3e61018..6ccf78b10 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -71,7 +71,7 @@ Language features - Floating point math also supported on select compiler targets (C64, Cx16 and virtual). - Strings can contain escaped characters but also many symbols directly if they have a PETSCII equivalent, such as "♠♥♣♦π▚●○╳". Characters like ^, _, \\, {, } and | are also accepted and converted to the closest PETSCII equivalents. - High-level code optimizations, such as const-folding (zero-allocation constants that are optimized away in expressions), expression and statement simplifications/rewriting. -- Many built-in functions, such as ``sin``, ``cos``, ``abs``, ``sqrt``, ``msb``, ``rol``, ``ror``, ``sort`` and ``reverse`` +- Many built-in functions, such as ``sin``, ``cos``, ``abs``, ``sqrt``, ``msb``, ``min``, ``max``, ``rol``, ``ror``, ``sort`` and ``reverse`` - Programs can be run multiple times without reloading because of automatic variable (re)initializations. - Supports the sixteen 'virtual' 16-bit registers R0 .. R15 from the Commander X16, also on the other machines. - If you only use standard Kernal and core prog8 library routines, it is possible to compile the *exact same program* for different machines (just change the compilation target flag)! diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index 2762fe82d..035166097 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -252,6 +252,12 @@ ln(x) log2(x) Base 2 logarithm. +minf(x, y) + returns the smallest of x and y. + +maxf(x, y) + returns the largest of x and y. + rad(x) Degrees to radians. diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 0690b7163..8617abbbb 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -765,6 +765,12 @@ abs (x) Absolute value of an integer. Value returned is an unsigned word. For floating point numbers, use ``floats.fabs()`` instead. +min (x, y) + Returns the smallest of x and y. Supported for integer types only, for floats use ``floats.minf()`` instead. + +max (x, y) + Returns the largest of x and y. Supported for integer types only, for floats use ``floats.maxf()`` instead. + sgn (x) Get the sign of the value. Result is -1, 0 or 1 (negative, zero, positive). diff --git a/docs/source/todo.rst b/docs/source/todo.rst index f85097abb..4b6dc73df 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,21 +1,12 @@ TODO ==== -- try to reintroduce builtin functions max/maxw/min/minw that take 2 args and return the largest/smallest of them. - This is a major change because it will likely break existing code that is now using min and max as variable names. - Add "polymorphism" that translates min -> min__ubyte etc etc. - Also add optimization that changes the word variant to byte variant if the operands are bytes. - Add to docs. - -- add polymorphism to other builtin functions as well! Fix docs. - -- once 9.0 is stable, upgrade other programs (assem, shell, etc) to it. - -... - - For 9.0 major changes ^^^^^^^^^^^^^^^^^^^^^ +- DONE: added min() max() builtin functions +- DONE: added 'cbm' block in the syslib module that now contains all CBM compatible kernal routines and variables +- DONE: rename sqrt16() to just sqrtw() +- add "polymorphism" of min() and max() to several other builtin functions as well! Fix docs. - 6502 codegen: see if we can let for loops skip the loop if startvar>endvar, without adding a lot of code size/duplicating the loop condition. It is documented behavior to now loop 'around' $00 but it's too easy to forget about! Lot of work because of so many special cases in ForLoopsAsmgen..... @@ -25,10 +16,11 @@ For 9.0 major changes But see complaint on github https://github.com/irmen/prog8/issues/106 - duplicate diskio for cx16 (get rid of cx16diskio, just copy diskio and tweak everything) + documentation - get f_seek_w working like in the BASIC program - this needs the changes to diskio.f_open to use suffixes ,p,m -- add special (u)word array type (or modifier such as @fast? ) that puts the array into memory as 2 separate byte-arrays 1 for LSB 1 for MSB -> allows for word arrays of length 256 and faster indexing +- once 9.0 is stable, upgrade other programs (assem, shell, etc) to it. + add migration guide to the manual. +- [much work:] add special (u)word array type (or modifier such as @fast? ) that puts the array into memory as 2 separate byte-arrays 1 for LSB 1 for MSB -> allows for word arrays of length 256 and faster indexing this is an enormous amout of work, if this type is to be treated equally as existing (u)word , because all expression / lookup / assignment routines need to know about the distinction.... So maybe only allow the bare essentials? (store, get, bitwise operations?) -- Some more support for (64tass) SEGMENTS ? +- [much work:] more support for (64tass) SEGMENTS ? - (What, how, isn't current BSS support enough?) - Add a mechanism to allocate variables into golden ram (or segments really) (see GoldenRam class) - maybe treat block "golden" in a special way: can only contain vars, every var will be allocated in the Golden ram area? diff --git a/examples/test.p8 b/examples/test.p8 index 6bceb6414..f93070c84 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,4 +1,5 @@ %import textio +%import floats %option no_sysinit %zeropage basicsafe @@ -14,6 +15,14 @@ main { word w1s = 2222 word w2s = -9999 + float f1 = 1111.1 + float f2 = -999.9 + + floats.print_f(floats.minf(f1, f2)) + txt.spc() + floats.print_f(floats.maxf(f1, f2)) + txt.nl() + txt.print_uw(min(v1, v2)) txt.spc() txt.print_w(min(v1s, v2s)) diff --git a/syntax-files/IDEA/Prog8.xml b/syntax-files/IDEA/Prog8.xml index 041177176..c248f7e4d 100644 --- a/syntax-files/IDEA/Prog8.xml +++ b/syntax-files/IDEA/Prog8.xml @@ -11,13 +11,13 @@