diff --git a/c/c.go b/c/c.go index fcff0826..f035ff48 100644 --- a/c/c.go +++ b/c/c.go @@ -109,6 +109,12 @@ func Printf(format *Char, __llgo_va_list ...any) Int //go:linkname Fprintf C.fprintf func Fprintf(fp FilePtr, format *Char, __llgo_va_list ...any) Int +//go:linkname Fwrite C.fwrite +func Fwrite(data Pointer, size, count uintptr, fp FilePtr) uintptr + +//go:linkname Fputc C.fputc +func Fputc(c Int, fp FilePtr) Int + // ----------------------------------------------------------------------------- //go:linkname Time C.time diff --git a/internal/runtime/llgo_autogen.lla b/internal/runtime/llgo_autogen.lla index e6491d05..61566d86 100644 Binary files a/internal/runtime/llgo_autogen.lla and b/internal/runtime/llgo_autogen.lla differ diff --git a/internal/runtime/print.go b/internal/runtime/print.go deleted file mode 100644 index aef6c02e..00000000 --- a/internal/runtime/print.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package runtime - -import ( - "unsafe" - - "github.com/goplus/llgo/c" -) - -// The compiler knows that a print of a value of this type -// should use printhex instead of printuint (decimal). -func bytes(s string) (ret []byte) { - rp := (*Slice)(unsafe.Pointer(&ret)) - sp := (*String)(unsafe.Pointer(&s)) - rp.data = sp.data - rp.len = sp.len - rp.cap = sp.len - return -} - -func gwrite(b []byte) { - if len(b) == 0 { - return - } - for _, v := range b { - c.Fprintf(c.Stderr, c.Str("%c"), v) - } -} - -func PrintByte(v byte) { - c.Fprintf(c.Stderr, c.Str("%c"), v) -} - -func PrintBool(v bool) { - if v { - PrintString("true") - } else { - PrintString("false") - } -} - -func PrintFloat(v float64) { - switch { - case v != v: - PrintString("NaN") - return - case v+v == v && v > 0: - PrintString("+Inf") - return - case v+v == v && v < 0: - PrintString("-Inf") - return - } - - const n = 7 // digits printed - var buf [n + 7]byte - buf[0] = '+' - e := 0 // exp - if v == 0 { - if 1/v < 0 { - buf[0] = '-' - } - } else { - if v < 0 { - v = -v - buf[0] = '-' - } - - // normalize - for v >= 10 { - e++ - v /= 10 - } - for v < 1 { - e-- - v *= 10 - } - - // round - h := 5.0 - for i := 0; i < n; i++ { - h /= 10 - } - v += h - if v >= 10 { - e++ - v /= 10 - } - } - - // format +d.dddd+edd - for i := 0; i < n; i++ { - s := int(v) - buf[i+2] = byte(s + '0') - v -= float64(s) - v *= 10 - } - buf[1] = buf[2] - buf[2] = '.' - - buf[n+2] = 'e' - buf[n+3] = '+' - if e < 0 { - e = -e - buf[n+3] = '-' - } - - buf[n+4] = byte(e/100) + '0' - buf[n+5] = byte(e/10)%10 + '0' - buf[n+6] = byte(e%10) + '0' - gwrite(buf[:]) -} - -// func PrintComplex(c complex128) { -// print("(", real(c), imag(c), "i)") -// } - -func PrintUint(v uint64) { - var buf [100]byte - i := len(buf) - for i--; i > 0; i-- { - buf[i] = byte(v%10 + '0') - if v < 10 { - break - } - v /= 10 - } - gwrite(buf[i:]) -} - -func PrintInt(v int64) { - if v < 0 { - PrintString("-") - v = -v - } - PrintUint(uint64(v)) -} - -func PrintHex(v uint64) { - const dig = "0123456789abcdef" - var buf [100]byte - i := len(buf) - for i--; i > 0; i-- { - buf[i] = dig[v%16] - if v < 16 && len(buf)-i >= 0 { - break - } - v /= 16 - } - i-- - buf[i] = 'x' - i-- - buf[i] = '0' - gwrite(buf[i:]) -} - -func PrintPointer(p unsafe.Pointer) { - PrintHex(uint64(uintptr(p))) -} - -func PrintString(s string) { - gwrite(bytes(s)) -} - -func PrintSlice(s Slice) { - sp := (*Slice)(unsafe.Pointer(&s)) - print("[", s.len, "/", s.cap, "]") - PrintPointer(sp.data) -} - -func PrintIface(i iface) { - print("(", i.tab, ",", i.data, ")") -} diff --git a/internal/runtime/z_print.go b/internal/runtime/z_print.go new file mode 100644 index 00000000..2bb01541 --- /dev/null +++ b/internal/runtime/z_print.go @@ -0,0 +1,71 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime + +import ( + "unsafe" + + "github.com/goplus/llgo/c" +) + +func PrintByte(v byte) { + c.Fputc(c.Int(v), c.Stderr) +} + +func PrintBool(v bool) { + if v { + c.Fprintf(c.Stderr, c.Str("true")) + } else { + c.Fprintf(c.Stderr, c.Str("false")) + } +} + +func PrintFloat(v float64) { + switch { // TODO(xsw): does c.Fprintf support these special cases? + case v != v: + c.Fprintf(c.Stderr, c.Str("NaN")) + return + case v+v == v: + if v > 0 { + c.Fprintf(c.Stderr, c.Str("+Inf")) + } else if v < 0 { + c.Fprintf(c.Stderr, c.Str("-Inf")) + } + return + } + c.Fprintf(c.Stderr, c.Str("%g"), v) +} + +// func PrintComplex(c complex128) { +// print("(", real(c), imag(c), "i)") +// } + +func PrintUint(v uint64) { + c.Fprintf(c.Stderr, c.Str("%llu"), v) +} + +func PrintInt(v int64) { + c.Fprintf(c.Stderr, c.Str("%lld"), v) +} + +func PrintHex(v uint64) { + c.Fprintf(c.Stderr, c.Str("%llx"), v) +} + +func PrintPointer(p unsafe.Pointer) { + c.Fprintf(c.Stderr, c.Str("%p"), p) +} + +func PrintString(s String) { + c.Fwrite(s.data, 1, uintptr(s.len), c.Stderr) +} + +func PrintSlice(s Slice) { + print("[", s.len, "/", s.cap, "]", s.data) +} + +func PrintIface(i Interface) { + print("(", i.tab, ",", i.data, ")") +}