VERY hacky f64 printing
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user