VERY hacky f64 printing

This commit is contained in:
2026-06-26 09:34:18 +02:00
parent e4582ec85a
commit 3f3f161151
2 changed files with 96 additions and 8 deletions

View File

@@ -249,6 +249,9 @@ func io.printf[..] : void
else if s[0] == 'c' else if s[0] == 'c'
io.print_char(_var_arg(i) as u8) io.print_char(_var_arg(i) as u8)
i += 1 i += 1
else if s[0] == 'f'
io.print_f64(_var_arg(i) as i64)
i += 1
else if s[0] == '%' else if s[0] == '%'
io.print_char('%') io.print_char('%')
else if s[0] == 0 else if s[0] == 0
@@ -293,6 +296,87 @@ func io.println_i64[x: i64] : void
x->to_str_buf(s) x->to_str_buf(s)
io.println(s as str) io.println(s as str)
// TODO: fix when we implement f64 params
func io.print_f64[x: i64] : void
s := _stackalloc(64)
f64.to_str_buf(x, s)
io.print(s as str)
func f64.to_str_buf[x: i64, buf: ptr] : void
bits := x
sign := (bits >> 63) & 1
exp := (bits >> 52) & 0x7ff
mant := bits & 0x000fffffffffffff
if exp == 0x7ff
if mant == 0
if sign
mem.copy("-inf" as ptr, buf, 5)
else
mem.copy("inf" as ptr, buf, 4)
else
mem.copy("nan" as ptr, buf, 4)
return
p := 0
if sign
buf[p] = '-'
p += 1
bits = bits & 0x7fffffffffffffff
if exp == 0 && mant == 0
buf[p] = '0'
buf[p+1] = '.'
buf[p+2] = '0'
buf[p+3] = 0
return
sig := mant
if exp != 0
sig = sig | 0x0010000000000000
shift := exp - 1075
if shift >= 0
(sig << shift)->to_str_buf(buf + p)
while buf[p]
p += 1
buf[p] = '.'
buf[p+1] = '0'
buf[p+2] = 0
return
ns := -shift
if ns <= 52
int_part := sig >> ns
int_part->to_str_buf(buf + p)
while buf[p]
p += 1
else
buf[p] = '0'
p += 1
buf[p] = '.'
p += 1
mask := (1 << ns) - 1
frac := sig & mask
for i in 0..6
if frac == 0
if i > 0
break
buf[p] = '0'
p += 1
break
frac = frac * 10
digit := frac >> ns
buf[p] = '0' + digit as u8
p += 1
frac = frac & mask
buf[p] = 0
func io.read_char[] : u8 func io.read_char[] : u8
c := 0 as u8 c := 0 as u8
_builtin_syscall(SYS_read, STDIN, ^c, 1) _builtin_syscall(SYS_read, STDIN, ^c, 1)
@@ -394,7 +478,7 @@ func str.format_into[..] : i64
i := 3 i := 3
n := 0 n := 0
tmp := _stackalloc(21) as str tmp := _stackalloc(64) as str
while s[0] while s[0]
if s[0] == '%' if s[0] == '%'
@@ -426,6 +510,14 @@ func str.format_into[..] : i64
buf[n] = _var_arg(i) as u8 buf[n] = _var_arg(i) as u8
n += 1 n += 1
i += 1 i += 1
else if s[0] == 'f'
// TODO: fix when we implement f64 params
f64.to_str_buf(_var_arg(i), tmp as ptr)
tmp_len := tmp->len()
remaining := size - n - 1
mem.copy(tmp as ptr, buf + n, math.min(tmp_len, remaining))
n += tmp_len
i += 1
else if s[0] == '%' else if s[0] == '%'
if n < size - 1 if n < size - 1
buf[n] = '%' buf[n] = '%'
@@ -1080,7 +1172,6 @@ func os.time[] : i64
out := tv->tv_sec * 1000 + tv->tv_usec / 1000 out := tv->tv_sec * 1000 + tv->tv_usec / 1000
return out return out
// voodoo magic
func os.run_shell_command[command: str] : i64, bool func os.run_shell_command[command: str] : i64, bool
pid := _builtin_syscall(SYS_fork) pid := _builtin_syscall(SYS_fork)
if pid < 0 if pid < 0

View File

@@ -300,9 +300,6 @@ impl<'a> TypeChecker<'a> {
"unrecognized type: ".to_owned() + &return_type "unrecognized type: ".to_owned() + &return_type
); );
} }
if return_type == "f64" {
return error!(&return_types[0].loc, "returning f64 not implemented yet");
}
self.current_function_return_type = return_type.clone(); self.current_function_return_type = return_type.clone();
@@ -559,13 +556,13 @@ impl<'a> TypeChecker<'a> {
Ok(field.field_type.clone()) Ok(field.field_type.clone())
} }
ExprKind::Cast { expr, type_name } => { ExprKind::Cast { expr, type_name } => {
if type_name.lexeme == "f64" { let expr_type = self.typecheck_expr(env, expr)?;
if expr_type != "any" && type_name.lexeme == "f64" {
return error!( return error!(
&type_name.loc, &type_name.loc,
"use _builtin_cvtsi2sd and _builtin_cvttsd2si to cast to f64" "use _builtin_cvtsi2sd and _builtin_cvttsd2si to cast between integers and f64"
); );
} }
self.typecheck_expr(env, expr)?;
if !self.is_valid_type_name(&type_name.lexeme) { if !self.is_valid_type_name(&type_name.lexeme) {
return error!( return error!(
&type_name.loc, &type_name.loc,