VERY hacky f64 printing
This commit is contained in:
@@ -249,6 +249,9 @@ func io.printf[..] : void
|
||||
else if s[0] == 'c'
|
||||
io.print_char(_var_arg(i) as u8)
|
||||
i += 1
|
||||
else if s[0] == 'f'
|
||||
io.print_f64(_var_arg(i) as i64)
|
||||
i += 1
|
||||
else if s[0] == '%'
|
||||
io.print_char('%')
|
||||
else if s[0] == 0
|
||||
@@ -293,6 +296,87 @@ func io.println_i64[x: i64] : void
|
||||
x->to_str_buf(s)
|
||||
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
|
||||
c := 0 as u8
|
||||
_builtin_syscall(SYS_read, STDIN, ^c, 1)
|
||||
@@ -394,7 +478,7 @@ func str.format_into[..] : i64
|
||||
i := 3
|
||||
n := 0
|
||||
|
||||
tmp := _stackalloc(21) as str
|
||||
tmp := _stackalloc(64) as str
|
||||
|
||||
while s[0]
|
||||
if s[0] == '%'
|
||||
@@ -426,6 +510,14 @@ func str.format_into[..] : i64
|
||||
buf[n] = _var_arg(i) as u8
|
||||
n += 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] == '%'
|
||||
if n < size - 1
|
||||
buf[n] = '%'
|
||||
@@ -1080,7 +1172,6 @@ func os.time[] : i64
|
||||
out := tv->tv_sec * 1000 + tv->tv_usec / 1000
|
||||
return out
|
||||
|
||||
// voodoo magic
|
||||
func os.run_shell_command[command: str] : i64, bool
|
||||
pid := _builtin_syscall(SYS_fork)
|
||||
if pid < 0
|
||||
|
||||
@@ -300,9 +300,6 @@ impl<'a> TypeChecker<'a> {
|
||||
"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();
|
||||
|
||||
@@ -559,13 +556,13 @@ impl<'a> TypeChecker<'a> {
|
||||
Ok(field.field_type.clone())
|
||||
}
|
||||
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!(
|
||||
&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) {
|
||||
return error!(
|
||||
&type_name.loc,
|
||||
|
||||
Reference in New Issue
Block a user