min max docs, added floats.minf() and maxf()

This commit is contained in:
Irmen de Jong 2023-04-29 17:52:15 +02:00
parent 2885f4f7b1
commit 025bf900a5
13 changed files with 59 additions and 25 deletions

View File

@ -93,6 +93,8 @@ val BuiltinFunctions: Map<String, FSignature> = mapOf(
"lsb" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE), "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), "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), "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__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__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), "min__word" to FSignature(true, listOf(FParam("val1", arrayOf(DataType.WORD)), FParam("val2", arrayOf(DataType.WORD))), DataType.WORD),

View File

@ -844,7 +844,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
val targetReg = AsmAssignTarget.fromRegisters(resultRegister!!, signed, fcall.position, fcall.definingISub(), asmgen) val targetReg = AsmAssignTarget.fromRegisters(resultRegister!!, signed, fcall.position, fcall.definingISub(), asmgen)
asmgen.assignRegister(RegisterOrPair.A, targetReg) 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[0], "P8ZP_SCRATCH_W1", fcall.type) // left
asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W2", fcall.type) // right asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W2", fcall.type) // right
if(signed) { if(signed) {
@ -885,6 +885,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
val targetReg = AsmAssignTarget.fromRegisters(resultRegister!!, signed, fcall.position, fcall.definingISub(), asmgen) val targetReg = AsmAssignTarget.fromRegisters(resultRegister!!, signed, fcall.position, fcall.definingISub(), asmgen)
asmgen.assignRegister(RegisterOrPair.AY, targetReg) 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) val targetReg = AsmAssignTarget.fromRegisters(resultRegister!!, signed, fcall.position, fcall.definingISub(), asmgen)
asmgen.assignRegister(RegisterOrPair.A, targetReg) 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[0], "P8ZP_SCRATCH_W1", fcall.type) // left
asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W2", fcall.type) // right asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W2", fcall.type) // right
if(signed) { if(signed) {
@ -945,6 +947,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
val targetReg = AsmAssignTarget.fromRegisters(resultRegister!!, signed, fcall.position, fcall.definingISub(), asmgen) val targetReg = AsmAssignTarget.fromRegisters(resultRegister!!, signed, fcall.position, fcall.definingISub(), asmgen)
asmgen.assignRegister(RegisterOrPair.AY, targetReg) asmgen.assignRegister(RegisterOrPair.AY, targetReg)
} }
} else {
throw AssemblyError("max float not supported")
} }
} }

View File

@ -89,7 +89,8 @@ class VarConstantValueTypeAdjuster(private val program: Program, private val err
else else
"${funcName}__uword" "${funcName}__uword"
} else if(t1.isNumeric && t2.isNumeric) { } else if(t1.isNumeric && t2.isNumeric) {
replaceFunc = "${funcName}__float" errors.err("min/max not supported for floats", functionCallExpr.position)
return noModifications
} else { } else {
errors.err("expected numeric arguments", functionCallExpr.position) errors.err("expected numeric arguments", functionCallExpr.position)
return noModifications return noModifications

View File

@ -237,4 +237,18 @@ sub rndseedf(float seed) {
}} }}
} }
sub minf(float f1, float f2) -> float {
if f1<f2
return f1
return f2
}
sub maxf(float f1, float f2) -> float {
if f1>f2
return f1
return f2
}
} }

View File

@ -29,7 +29,7 @@ internal val constEvaluatorsForBuiltinFuncs: Map<String, ConstExpressionCaller>
"max__ubyte" to ::builtinMaxUByte, "max__ubyte" to ::builtinMaxUByte,
"max__byte" to ::builtinMaxByte, "max__byte" to ::builtinMaxByte,
"max__uword" to ::builtinMaxUWord, "max__uword" to ::builtinMaxUWord,
"max__word" to ::builtinMaxWord, "max__word" to ::builtinMaxWord
) )
private fun builtinAny(array: List<Double>): Double = if(array.any { it!=0.0 }) 1.0 else 0.0 private fun builtinAny(array: List<Double>): Double = if(array.any { it!=0.0 }) 1.0 else 0.0

View File

@ -71,7 +71,7 @@ Language features
- Floating point math also supported on select compiler targets (C64, Cx16 and virtual). - 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. - 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. - 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. - 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. - 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)! - 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)!

View File

@ -252,6 +252,12 @@ ln(x)
log2(x) log2(x)
Base 2 logarithm. 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) rad(x)
Degrees to radians. Degrees to radians.

View File

@ -765,6 +765,12 @@ abs (x)
Absolute value of an integer. Value returned is an unsigned word. Absolute value of an integer. Value returned is an unsigned word.
For floating point numbers, use ``floats.fabs()`` instead. 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) sgn (x)
Get the sign of the value. Result is -1, 0 or 1 (negative, zero, positive). Get the sign of the value. Result is -1, 0 or 1 (negative, zero, positive).

View File

@ -1,21 +1,12 @@
TODO 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 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. - 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! 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..... 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 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 - 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 - 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.... 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?) 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?) - (What, how, isn't current BSS support enough?)
- Add a mechanism to allocate variables into golden ram (or segments really) (see GoldenRam class) - 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? - maybe treat block "golden" in a special way: can only contain vars, every var will be allocated in the Golden ram area?

View File

@ -1,4 +1,5 @@
%import textio %import textio
%import floats
%option no_sysinit %option no_sysinit
%zeropage basicsafe %zeropage basicsafe
@ -14,6 +15,14 @@ main {
word w1s = 2222 word w1s = 2222
word w2s = -9999 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.print_uw(min(v1, v2))
txt.spc() txt.spc()
txt.print_w(min(v1s, v2s)) txt.print_w(min(v1s, v2s))

View File

@ -11,10 +11,10 @@
<option name="HAS_PARENS" value="true" /> <option name="HAS_PARENS" value="true" />
<option name="HAS_STRING_ESCAPES" value="true" /> <option name="HAS_STRING_ESCAPES" value="true" />
</options> </options>
<keywords keywords="&amp;;-&gt;;@;\$;and;as;asmsub;break;clobbers;do;downto;else;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;or;repeat;return;romsub;step;sub;to;true;unroll;until;when;while;xor;~" ignore_case="false" /> <keywords keywords="&amp;;-&gt;;@;and;as;asmsub;break;clobbers;do;downto;else;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;or;repeat;return;romsub;step;sub;to;true;unroll;until;when;while;xor;~" ignore_case="false" />
<keywords2 keywords="%address;%asm;%asmbinary;%asminclude;%breakpoint;%import;%ir;%launcher;%option;%output;%zeropage;%zpreserved;iso:;petscii:;sc:" /> <keywords2 keywords="%address;%asm;%asmbinary;%asminclude;%breakpoint;%import;%ir;%launcher;%option;%output;%zeropage;%zpreserved;iso:;petscii:;sc:" />
<keywords3 keywords="@requirezp;@shared;@zp;bool;byte;const;float;str;ubyte;uword;void;word" /> <keywords3 keywords="@requirezp;@shared;@zp;bool;byte;const;float;str;ubyte;uword;void;word" />
<keywords4 keywords="abs;all;any;callfar;callram;callrom;cmp;len;lsb;memory;mkword;msb;peek;peekw;poke;pokew;pop;popw;push;pushw;reverse;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;sgn;sizeof;sort;sqrtw;swap;|&gt;" /> <keywords4 keywords="abs;all;any;callfar;callram;callrom;cmp;len;lsb;max;memory;min;mkword;msb;peek;peekw;poke;pokew;pop;popw;push;pushw;reverse;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;sgn;sizeof;sort;sqrt16;swap;|&gt;" />
</highlighting> </highlighting>
<extensionMap> <extensionMap>
<mapping ext="p8" /> <mapping ext="p8" />

View File

@ -27,7 +27,7 @@
<Keywords name="Keywords1">void const&#x000D;&#x000A;str&#x000D;&#x000A;byte ubyte bool&#x000D;&#x000A;word uword&#x000D;&#x000A;float&#x000D;&#x000A;zp shared requirezp</Keywords> <Keywords name="Keywords1">void const&#x000D;&#x000A;str&#x000D;&#x000A;byte ubyte bool&#x000D;&#x000A;word uword&#x000D;&#x000A;float&#x000D;&#x000A;zp shared requirezp</Keywords>
<Keywords name="Keywords2">%address&#x000D;&#x000A;%asm&#x000D;&#x000A;%ir&#x000D;&#x000A;%asmbinary&#x000D;&#x000A;%asminclude&#x000D;&#x000A;%breakpoint&#x000D;&#x000A;%import&#x000D;&#x000A;%launcher&#x000D;&#x000A;%option&#x000D;&#x000A;%output&#x000D;&#x000A;%zeropage&#x000D;&#x000A;%zpreserved</Keywords> <Keywords name="Keywords2">%address&#x000D;&#x000A;%asm&#x000D;&#x000A;%ir&#x000D;&#x000A;%asmbinary&#x000D;&#x000A;%asminclude&#x000D;&#x000A;%breakpoint&#x000D;&#x000A;%import&#x000D;&#x000A;%launcher&#x000D;&#x000A;%option&#x000D;&#x000A;%output&#x000D;&#x000A;%zeropage&#x000D;&#x000A;%zpreserved</Keywords>
<Keywords name="Keywords3">inline sub asmsub romsub&#x000D;&#x000A;clobbers&#x000D;&#x000A;asm&#x000D;&#x000A;if&#x000D;&#x000A;when else&#x000D;&#x000A;if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z&#x000D;&#x000A;for in step do while repeat unroll&#x000D;&#x000A;break return goto</Keywords> <Keywords name="Keywords3">inline sub asmsub romsub&#x000D;&#x000A;clobbers&#x000D;&#x000A;asm&#x000D;&#x000A;if&#x000D;&#x000A;when else&#x000D;&#x000A;if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z&#x000D;&#x000A;for in step do while repeat unroll&#x000D;&#x000A;break return goto</Keywords>
<Keywords name="Keywords4">abs all any callfar cmp len lsb lsl lsr memory mkword msb peek peekw poke pokew push pushw pop popw rsave rsavex rrestore rrestorex reverse rnd rndw rol rol2 ror ror2 sgn sizeof sort sqrtw swap</Keywords> <Keywords name="Keywords4">abs all any callfar cmp len lsb lsl lsr memory mkword min max msb peek peekw poke pokew push pushw pop popw rsave rsavex rrestore rrestorex reverse rnd rndw rol rol2 ror ror2 sgn sizeof sort sqrtw swap</Keywords>
<Keywords name="Keywords5">true false&#x000D;&#x000A;not and or xor&#x000D;&#x000A;as to downto |&gt;</Keywords> <Keywords name="Keywords5">true false&#x000D;&#x000A;not and or xor&#x000D;&#x000A;as to downto |&gt;</Keywords>
<Keywords name="Keywords6"></Keywords> <Keywords name="Keywords6"></Keywords>
<Keywords name="Keywords7"></Keywords> <Keywords name="Keywords7"></Keywords>

View File

@ -13,7 +13,7 @@ syn keyword prog8BuiltInFunc sgn sqrtw
syn keyword prog8BuiltInFunc any all len reverse sort syn keyword prog8BuiltInFunc any all len reverse sort
" Miscellaneous functions " Miscellaneous functions
syn keyword prog8BuiltInFunc cmp lsb msb mkword peek peekw poke pokew push pushw pop popw rsave rsavex rrestore rrestorex syn keyword prog8BuiltInFunc cmp lsb msb mkword min max peek peekw poke pokew push pushw pop popw rsave rsavex rrestore rrestorex
syn keyword prog8BuiltInFunc rol rol2 ror ror2 sizeof syn keyword prog8BuiltInFunc rol rol2 ror ror2 sizeof
syn keyword prog8BuiltInFunc swap memory callfar syn keyword prog8BuiltInFunc swap memory callfar