mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +00:00
e35cfd4971
Unfortunately a few routines (minf, maxf, clampf) remain unchanged, because removing the 'f' would make them clash with a builtin function. floats.rndf -> floats.rnd floats.parse_f -> floats.parse floats.rndseedf -> floats.rndseed floats.print_f -> floats.print floats.str_f -> floats.tostr
194 lines
3.7 KiB
Lua
194 lines
3.7 KiB
Lua
; Prog8 definitions for floating point handling on the VirtualMachine
|
|
|
|
%option enable_floats, ignore_unused
|
|
|
|
floats {
|
|
|
|
const float π = 3.141592653589793
|
|
const float PI = π
|
|
const float TWOPI = 2*π
|
|
|
|
|
|
sub print(float value) {
|
|
; ---- prints the floating point value (without a newline and no leading spaces).
|
|
%ir {{
|
|
loadm.f fr65535,floats.print.value
|
|
syscall 25 (fr65535.f)
|
|
return
|
|
}}
|
|
}
|
|
|
|
sub tostr(float value) -> str {
|
|
; ---- converts the floating point value to a string (no leading spaces)
|
|
str @shared buffer=" "*20
|
|
%ir {{
|
|
load.w r65535,floats.tostr.buffer
|
|
loadm.f fr65535,floats.tostr.value
|
|
syscall 47 (r65535.w, fr65535.f)
|
|
load.w r0,floats.tostr.buffer
|
|
returnr.w r0
|
|
}}
|
|
}
|
|
|
|
sub parse(str value) -> float {
|
|
; -- parse a string value of a number to float
|
|
%ir {{
|
|
loadm.w r65535,floats.parse.value
|
|
syscall 45 (r65535.w): fr0.f
|
|
returnr.f fr0
|
|
}}
|
|
}
|
|
|
|
sub pow(float value, float power) -> float {
|
|
%ir {{
|
|
loadm.f fr0,floats.pow.value
|
|
loadm.f fr1,floats.pow.power
|
|
fpow.f fr0,fr1
|
|
returnr.f fr0
|
|
}}
|
|
}
|
|
|
|
sub sin(float angle) -> float {
|
|
%ir {{
|
|
loadm.f fr0,floats.sin.angle
|
|
fsin.f fr0,fr0
|
|
returnr.f fr0
|
|
}}
|
|
}
|
|
|
|
sub cos(float angle) -> float {
|
|
%ir {{
|
|
loadm.f fr0,floats.cos.angle
|
|
fcos.f fr0,fr0
|
|
returnr.f fr0
|
|
}}
|
|
}
|
|
|
|
sub tan(float value) -> float {
|
|
%ir {{
|
|
loadm.f fr0,floats.tan.value
|
|
ftan.f fr0,fr0
|
|
returnr.f fr0
|
|
}}
|
|
}
|
|
|
|
sub atan(float value) -> float {
|
|
%ir {{
|
|
loadm.f fr0,floats.atan.value
|
|
fatan.f fr0,fr0
|
|
returnr.f fr0
|
|
}}
|
|
}
|
|
|
|
sub ln(float value) -> float {
|
|
%ir {{
|
|
loadm.f fr0,floats.ln.value
|
|
fln.f fr0,fr0
|
|
returnr.f fr0
|
|
}}
|
|
}
|
|
|
|
sub log2(float value) -> float {
|
|
%ir {{
|
|
loadm.f fr0,floats.log2.value
|
|
flog.f fr0,fr0
|
|
returnr.f fr0
|
|
}}
|
|
}
|
|
|
|
sub rad(float angle) -> float {
|
|
; -- convert degrees to radians (d * pi / 180)
|
|
return angle * PI / 180.0
|
|
}
|
|
|
|
sub deg(float angle) -> float {
|
|
; -- convert radians to degrees (d * (1/ pi * 180))
|
|
return angle * 180.0 / PI
|
|
}
|
|
|
|
sub round(float value) -> float {
|
|
%ir {{
|
|
loadm.f fr0,floats.round.value
|
|
fround.f fr0,fr0
|
|
returnr.f fr0
|
|
}}
|
|
}
|
|
|
|
sub floor(float value) -> float {
|
|
%ir {{
|
|
loadm.f fr0,floats.floor.value
|
|
ffloor.f fr0,fr0
|
|
returnr.f fr0
|
|
}}
|
|
}
|
|
|
|
sub ceil(float value) -> float {
|
|
; -- ceil: tr = int(f); if tr==f -> return else return tr+1
|
|
%ir {{
|
|
loadm.f fr0,floats.ceil.value
|
|
fceil.f fr0,fr0
|
|
returnr.f fr0
|
|
}}
|
|
}
|
|
|
|
sub rnd() -> float {
|
|
%ir {{
|
|
syscall 35 () : fr0.f
|
|
returnr.f fr0
|
|
}}
|
|
}
|
|
|
|
sub rndseed(float seed) {
|
|
%ir {{
|
|
loadm.f fr65535,floats.rndseed.seed
|
|
syscall 32 (fr65535.f)
|
|
return
|
|
}}
|
|
}
|
|
|
|
|
|
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
|
|
}
|
|
|
|
|
|
sub clampf(float value, float minimum, float maximum) -> float {
|
|
if value<minimum
|
|
value=minimum
|
|
if value<maximum
|
|
return value
|
|
return maximum
|
|
}
|
|
|
|
sub normalize(float value) -> float {
|
|
return value
|
|
}
|
|
|
|
sub push(float value) {
|
|
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
|
%ir {{
|
|
loadm.f fr65535,floats.push.value
|
|
push.f fr65535
|
|
return
|
|
}}
|
|
}
|
|
|
|
sub pop() -> float {
|
|
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
|
%ir {{
|
|
pop.f fr65535
|
|
returnr.f fr65535
|
|
}}
|
|
}
|
|
|
|
}
|