feat(lang): float and double types with ordinary operators
`float` (32-bit) and `double` (64-bit) with + - * / %, comparisons and unary minus. Decimal literals take their type from context and stay `fixed` elsewhere; int and long promote implicitly (LUDIC_WARN_FLOAT_PROMOTE=1 lists every promotion). float(), double(), int(), long() and fixed() convert; floats(n)/doubles(n) buffers; float fields, globals, constants and parameters; Math.* computes in float for float arguments; string/print write the shortest round-tripping decimal; float_bits/float_from_bits expose the bits. @deterministic code may not use floats. The f_* runtime helpers stay as they are. Editors know the new type words; the JetBrains plugin is 1.5.0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
f92d7f89c6
commit
e010c2cecc
40 changed files with 67726 additions and 57272 deletions
|
|
@ -10,6 +10,16 @@ function is_math_builtin(name: pointer) -> bool {
|
|||
}
|
||||
|
||||
function emit_math_builtin(name: pointer, e: Node) -> Val {
|
||||
if len(e.kids) == 0 { return emit_math_builtin_fixed(name, e) }
|
||||
let orig = e.kids[0]
|
||||
let fpv = math_fp_route(name, e)
|
||||
if (fpv != null) { return fpv }
|
||||
let r = emit_math_builtin_fixed(name, e)
|
||||
e.kids[0] = orig # the node may be emitted again elsewhere
|
||||
return r
|
||||
}
|
||||
|
||||
function emit_math_builtin_fixed(name: pointer, e: Node) -> Val {
|
||||
if (name == "abs") {
|
||||
let a = emit_expr(e.kids[0])
|
||||
let c = emit_bind(`icmp slt i32 {a.code}, 0`)
|
||||
|
|
@ -79,9 +89,31 @@ function is_math_ns(meth: pointer) -> bool {
|
|||
return false
|
||||
}
|
||||
|
||||
# a float/double call goes to emit_fp_math; otherwise the evaluated first
|
||||
# argument is left in place (E_PREVAL) for the fixed-point path. null = fixed.
|
||||
function math_fp_route(meth: pointer, e: Node) -> Val {
|
||||
if len(e.kids) == 0 { return null }
|
||||
if (e.kids[0].kind == E_PREVAL) { return null }
|
||||
let first = emit_expr(e.kids[0])
|
||||
let t = fp_math_type(first, e)
|
||||
if not (t == "") { return emit_fp_math(meth, t, first, e) }
|
||||
e.kids[0] = preval_node(first)
|
||||
return null
|
||||
}
|
||||
|
||||
function emit_math_ns(meth: pointer, e: Node) -> Val {
|
||||
if len(e.kids) == 0 { return emit_math_ns_fixed(meth, e) }
|
||||
let orig = e.kids[0]
|
||||
let fpv = math_fp_route(meth, e)
|
||||
if (fpv != null) { return fpv }
|
||||
let r = emit_math_ns_fixed(meth, e)
|
||||
e.kids[0] = orig # the node may be emitted again elsewhere
|
||||
return r
|
||||
}
|
||||
|
||||
function emit_math_ns_fixed(meth: pointer, e: Node) -> Val {
|
||||
if (meth == "min") or (meth == "max") or (meth == "abs") or (meth == "clamp") {
|
||||
return emit_math_builtin(meth, e)
|
||||
return emit_math_builtin_fixed(meth, e)
|
||||
}
|
||||
if (meth == "sign") { # sign(x) -> -1 / 0 / 1 (int)
|
||||
let a = emit_expr(e.kids[0])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue