restructure: move el compiler content into lang/

This commit is contained in:
Will Anderson
2026-05-05 01:38:51 -05:00
parent ce68f91a38
commit 1ae68962cf
143 changed files with 0 additions and 0 deletions
+170
View File
@@ -0,0 +1,170 @@
// runtime/math.el Float math, integer utilities, and numeric conversions.
//
// Implements the math/float surface from el-compiler/runtime/legacy/el_runtime.c
// (lines 303305 for el_abs/max/min, lines 47254771 for float/format ops)
// in pure El, using seed primitives.
//
// Seed primitives consumed:
// __sqrt_f(f: Float) -> Float
// __log_f(f: Float) -> Float
// __ln_f(f: Float) -> Float
// __sin_f(f: Float) -> Float
// __cos_f(f: Float) -> Float
// __pi_f() -> Float
// __float_to_str(f: Float) -> String
// __str_to_float(s: String) -> Float
// __int_to_str(n: Int) -> String
// __str_to_int(s: String) -> Int
// ---------------------------------------------------------------------------
// Integer math el_abs, el_max, el_min.
//
// Matches legacy el_abs, el_max, el_min (lines 303305).
// ---------------------------------------------------------------------------
// el_abs absolute value of an integer.
fn el_abs(n: Int) -> Int {
if n < 0 { return -n }
return n
}
// el_max larger of two integers.
fn el_max(a: Int, b: Int) -> Int {
if a > b { return a }
return b
}
// el_min smaller of two integers.
fn el_min(a: Int, b: Int) -> Int {
if a < b { return a }
return b
}
// ---------------------------------------------------------------------------
// Float math thin wrappers over seed primitives.
//
// Matches legacy math_sqrt, math_log, math_ln, math_sin, math_cos, math_pi
// (lines 47664771).
// ---------------------------------------------------------------------------
// math_sqrt square root.
fn math_sqrt(f: Float) -> Float {
return __sqrt_f(f)
}
// math_log base-10 logarithm.
fn math_log(f: Float) -> Float {
return __log_f(f)
}
// math_ln natural logarithm.
fn math_ln(f: Float) -> Float {
return __ln_f(f)
}
// math_sin sine (radians).
fn math_sin(f: Float) -> Float {
return __sin_f(f)
}
// math_cos cosine (radians).
fn math_cos(f: Float) -> Float {
return __cos_f(f)
}
// math_pi the constant π.
fn math_pi() -> Float {
return __pi_f()
}
// ---------------------------------------------------------------------------
// Float conversions float_to_str, int_to_float, float_to_int, str_to_float.
//
// Matches legacy float_to_str, int_to_float, float_to_int, str_to_float
// (lines 47254762).
// ---------------------------------------------------------------------------
// float_to_str format a float using %g (shortest exact representation).
// Matches legacy float_to_str() snprintf "%g".
fn float_to_str(f: Float) -> String {
return __float_to_str(f)
}
// int_to_float convert an integer to a float.
// Matches legacy int_to_float() (double)(int64_t)n.
fn int_to_float(n: Int) -> Float {
return __int_to_float(n)
}
// float_to_int truncate a float to an integer (toward zero).
// Matches legacy float_to_int() (int64_t)el_to_float(f).
fn float_to_int(f: Float) -> Int {
return __float_to_int(f)
}
// str_to_float parse a float from a string. Returns 0.0 on failure.
// Matches legacy str_to_float() strtod(str, NULL).
fn str_to_float(s: String) -> Float {
return __str_to_float(s)
}
// ---------------------------------------------------------------------------
// format_float format a float to a fixed number of decimal places.
//
// decimals is clamped to [0, 30]. Matches legacy format_float() snprintf "%.*f".
// ---------------------------------------------------------------------------
fn format_float(f: Float, decimals: Int) -> String {
let d: Int = decimals
if d < 0 { d = 0 }
if d > 30 { d = 30 }
// Delegate to seed; the seed exposes __format_float(f, d) -> String.
// This matches snprintf(buf, 128, "%.*f", d, v) in the legacy runtime.
return __format_float(f, d)
}
// ---------------------------------------------------------------------------
// decimal_round round a float to d decimal places (half-away-from-zero).
//
// Matches legacy decimal_round():
// mul = pow(10, d)
// r = (v >= 0 ? floor(v*mul + 0.5) : -floor(-v*mul + 0.5)) / mul
//
// We implement pow(10, d) via a loop (d <= 15, so at most 15 multiplications).
// ---------------------------------------------------------------------------
// _pow10 10^n as a Float for n in [0, 15].
fn _pow10(n: Int) -> Float {
let result: Float = 1.0
let i: Int = 0
while i < n {
result = result * 10.0
i = i + 1
}
return result
}
// _floor_f floor of a float: largest integer <= f.
// Uses __float_to_int (truncation) with correction for negative non-integers.
fn _floor_f(f: Float) -> Float {
let t: Int = __float_to_int(f)
let tf: Float = __int_to_float(t)
// if f was negative and not already an integer, subtract 1
if f < 0.0 {
if tf > f {
return tf - 1.0
}
}
return tf
}
fn decimal_round(f: Float, decimals: Int) -> Float {
let d: Int = decimals
if d < 0 { d = 0 }
if d > 15 { d = 15 }
let mul: Float = _pow10(d)
if f >= 0.0 {
return _floor_f(f * mul + 0.5) / mul
}
return 0.0 - _floor_f((0.0 - f) * mul + 0.5) / mul
}