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
|
|
@ -26,7 +26,7 @@ function emit_str_const(s: pointer) -> pointer {
|
|||
|
||||
# the constant initializer for a global var: a literal, or 0/null
|
||||
function global_init(d: Node) -> pointer {
|
||||
if (d.a == null) { if (llty(d.ty) == "ptr") { return "null" }; return "0" }
|
||||
if (d.a == null) or is_fp(d.ty) { return zero_of(llty(d.ty)) } # a float's value is set by L_init_globals
|
||||
let e = d.a
|
||||
if e.kind == E_INT or e.kind == E_FLOAT or e.kind == E_BOOL { return itoa(e.ival) }
|
||||
if e.kind == E_UN and (e.s == ("-")) and e.a.kind == E_INT { return (("-") + itoa(e.a.ival)) }
|
||||
|
|
@ -40,6 +40,7 @@ function global_init(d: Node) -> pointer {
|
|||
# does a global's initializer need code at startup (anything global_init cannot fold)?
|
||||
function global_needs_init_code(d: Node) -> bool {
|
||||
if (d.a == null) { return false }
|
||||
if is_fp(d.ty) { return true }
|
||||
let e = d.a
|
||||
if e.kind == E_INT or e.kind == E_FLOAT or e.kind == E_BOOL or e.kind == E_NULL { return false }
|
||||
if e.kind == E_UN and (e.s == ("-")) and e.a.kind == E_INT { return false }
|
||||
|
|
@ -62,7 +63,8 @@ function emit_global_init_fn() -> void {
|
|||
let d = prog[i]
|
||||
if d.kind == N_VAR and global_needs_init_code(d) {
|
||||
let v = emit_expr(d.a)
|
||||
emit(" store "); emit(llty(d.ty)); emit(" "); emit(coerce_code(v, d.ty)); emit(", ptr @g_"); emit(d.s); emit("\n")
|
||||
let cv = coerce_code(v, d.ty) # any conversion is its own line, before the store
|
||||
emit(" store "); emit(llty(d.ty)); emit(" "); emit(cv); emit(", ptr @g_"); emit(d.s); emit("\n")
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue