github.com/goplus/llgo@v0.8.3/internal/runtime/print.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package runtime 6 7 import ( 8 "unsafe" 9 10 "github.com/goplus/llgo/c" 11 ) 12 13 // The compiler knows that a print of a value of this type 14 // should use printhex instead of printuint (decimal). 15 func bytes(s string) (ret []byte) { 16 rp := (*Slice)(unsafe.Pointer(&ret)) 17 sp := (*String)(unsafe.Pointer(&s)) 18 rp.data = sp.data 19 rp.len = sp.len 20 rp.cap = sp.len 21 return 22 } 23 24 func gwrite(b []byte) { 25 if len(b) == 0 { 26 return 27 } 28 for _, v := range b { 29 c.Fprintf(c.Stderr, c.Str("%c"), v) 30 } 31 } 32 33 func PrintBool(v bool) { 34 if v { 35 PrintString("true") 36 } else { 37 PrintString("false") 38 } 39 } 40 41 func PrintFloat(v float64) { 42 switch { 43 case v != v: 44 PrintString("NaN") 45 return 46 case v+v == v && v > 0: 47 PrintString("+Inf") 48 return 49 case v+v == v && v < 0: 50 PrintString("-Inf") 51 return 52 } 53 54 const n = 7 // digits printed 55 var buf [n + 7]byte 56 buf[0] = '+' 57 e := 0 // exp 58 if v == 0 { 59 if 1/v < 0 { 60 buf[0] = '-' 61 } 62 } else { 63 if v < 0 { 64 v = -v 65 buf[0] = '-' 66 } 67 68 // normalize 69 for v >= 10 { 70 e++ 71 v /= 10 72 } 73 for v < 1 { 74 e-- 75 v *= 10 76 } 77 78 // round 79 h := 5.0 80 for i := 0; i < n; i++ { 81 h /= 10 82 } 83 v += h 84 if v >= 10 { 85 e++ 86 v /= 10 87 } 88 } 89 90 // format +d.dddd+edd 91 for i := 0; i < n; i++ { 92 s := int(v) 93 buf[i+2] = byte(s + '0') 94 v -= float64(s) 95 v *= 10 96 } 97 buf[1] = buf[2] 98 buf[2] = '.' 99 100 buf[n+2] = 'e' 101 buf[n+3] = '+' 102 if e < 0 { 103 e = -e 104 buf[n+3] = '-' 105 } 106 107 buf[n+4] = byte(e/100) + '0' 108 buf[n+5] = byte(e/10)%10 + '0' 109 buf[n+6] = byte(e%10) + '0' 110 gwrite(buf[:]) 111 } 112 113 // func PrintComplex(c complex128) { 114 // print("(", real(c), imag(c), "i)") 115 // } 116 117 func PrintUint(v uint64) { 118 var buf [100]byte 119 i := len(buf) 120 for i--; i > 0; i-- { 121 buf[i] = byte(v%10 + '0') 122 if v < 10 { 123 break 124 } 125 v /= 10 126 } 127 gwrite(buf[i:]) 128 } 129 130 func PrintInt(v int64) { 131 if v < 0 { 132 PrintString("-") 133 v = -v 134 } 135 PrintUint(uint64(v)) 136 } 137 138 func PrintHex(v uint64) { 139 const dig = "0123456789abcdef" 140 var buf [100]byte 141 i := len(buf) 142 for i--; i > 0; i-- { 143 buf[i] = dig[v%16] 144 if v < 16 && len(buf)-i >= 0 { 145 break 146 } 147 v /= 16 148 } 149 i-- 150 buf[i] = 'x' 151 i-- 152 buf[i] = '0' 153 gwrite(buf[i:]) 154 } 155 156 func PrintPointer(p unsafe.Pointer) { 157 PrintHex(uint64(uintptr(p))) 158 } 159 160 func PrintString(s string) { 161 gwrite(bytes(s)) 162 } 163 164 func PrintSlice(s Slice) { 165 sp := (*Slice)(unsafe.Pointer(&s)) 166 print("[", s.len, "/", s.cap, "]") 167 PrintPointer(sp.data) 168 } 169 170 func PrintIface(i iface) { 171 print("(", i.tab, ",", i.data, ")") 172 }