github.com/aykevl/tinygo@v0.5.0/src/runtime/print.go (about) 1 package runtime 2 3 import ( 4 "unsafe" 5 ) 6 7 //go:nobounds 8 func printstring(s string) { 9 for i := 0; i < len(s); i++ { 10 putchar(s[i]) 11 } 12 } 13 14 func printuint8(n uint8) { 15 if TargetBits >= 32 { 16 printuint32(uint32(n)) 17 } else { 18 prevdigits := n / 10 19 if prevdigits != 0 { 20 printuint8(prevdigits) 21 } 22 putchar(byte((n % 10) + '0')) 23 } 24 } 25 26 func printint8(n int8) { 27 if TargetBits >= 32 { 28 printint32(int32(n)) 29 } else { 30 if n < 0 { 31 putchar('-') 32 n = -n 33 } 34 printuint8(uint8(n)) 35 } 36 } 37 38 func printuint16(n uint16) { 39 printuint32(uint32(n)) 40 } 41 42 func printint16(n int16) { 43 printint32(int32(n)) 44 } 45 46 //go:nobounds 47 func printuint32(n uint32) { 48 digits := [10]byte{} // enough to hold (2^32)-1 49 // Fill in all 10 digits. 50 firstdigit := 9 // digit index that isn't zero (by default, the last to handle '0' correctly) 51 for i := 9; i >= 0; i-- { 52 digit := byte(n%10 + '0') 53 digits[i] = digit 54 if digit != '0' { 55 firstdigit = i 56 } 57 n /= 10 58 } 59 // Print digits without the leading zeroes. 60 for i := firstdigit; i < 10; i++ { 61 putchar(digits[i]) 62 } 63 } 64 65 func printint32(n int32) { 66 // Print integer in signed big-endian base-10 notation, for humans to 67 // read. 68 if n < 0 { 69 putchar('-') 70 n = -n 71 } 72 printuint32(uint32(n)) 73 } 74 75 func printuint64(n uint64) { 76 prevdigits := n / 10 77 if prevdigits != 0 { 78 printuint64(prevdigits) 79 } 80 putchar(byte((n % 10) + '0')) 81 } 82 83 func printint64(n int64) { 84 if n < 0 { 85 putchar('-') 86 n = -n 87 } 88 printuint64(uint64(n)) 89 } 90 91 func printfloat32(v float32) { 92 // TODO: write an implementation like printfloat64, as some systems have 93 // 32-bit floats but only software emulation for 64-bit floats. 94 printfloat64(float64(v)) 95 } 96 97 // printfloat64() was copied from the relevant source in the original Go 98 // implementation. It is copyright by the Go authors, licensed under the same 99 // BSD 3-clause license. See https://golang.org/LICENSE for details. 100 // 101 // Source: 102 // https://github.com/golang/go/blob/master/src/runtime/print.go 103 func printfloat64(v float64) { 104 switch { 105 case v != v: 106 printstring("NaN") 107 return 108 case v+v == v && v > 0: 109 printstring("+Inf") 110 return 111 case v+v == v && v < 0: 112 printstring("-Inf") 113 return 114 } 115 116 const n = 7 // digits printed 117 var buf [n + 7]byte 118 buf[0] = '+' 119 e := 0 // exp 120 if v == 0 { 121 if 1/v < 0 { 122 buf[0] = '-' 123 } 124 } else { 125 if v < 0 { 126 v = -v 127 buf[0] = '-' 128 } 129 130 // normalize 131 for v >= 10 { 132 e++ 133 v /= 10 134 } 135 for v < 1 { 136 e-- 137 v *= 10 138 } 139 140 // round 141 h := 5.0 142 for i := 0; i < n; i++ { 143 h /= 10 144 } 145 v += h 146 if v >= 10 { 147 e++ 148 v /= 10 149 } 150 } 151 152 // format +d.dddd+edd 153 for i := 0; i < n; i++ { 154 s := int(v) 155 buf[i+2] = byte(s + '0') 156 v -= float64(s) 157 v *= 10 158 } 159 buf[1] = buf[2] 160 buf[2] = '.' 161 162 buf[n+2] = 'e' 163 buf[n+3] = '+' 164 if e < 0 { 165 e = -e 166 buf[n+3] = '-' 167 } 168 169 buf[n+4] = byte(e/100) + '0' 170 buf[n+5] = byte(e/10)%10 + '0' 171 buf[n+6] = byte(e%10) + '0' 172 for _, c := range buf { 173 putchar(c) 174 } 175 } 176 177 func printcomplex64(c complex64) { 178 putchar('(') 179 printfloat32(real(c)) 180 printfloat32(imag(c)) 181 printstring("i)") 182 } 183 184 func printcomplex128(c complex128) { 185 putchar('(') 186 printfloat64(real(c)) 187 printfloat64(imag(c)) 188 printstring("i)") 189 } 190 191 func printspace() { 192 putchar(' ') 193 } 194 195 func printnl() { 196 putchar('\r') 197 putchar('\n') 198 } 199 200 func printitf(msg interface{}) { 201 switch msg := msg.(type) { 202 case string: 203 print(msg) 204 default: 205 // cast to underlying type 206 itf := *(*_interface)(unsafe.Pointer(&msg)) 207 putchar('(') 208 switch unsafe.Sizeof(itf.typecode) { 209 case 2: 210 printuint16(uint16(itf.typecode)) 211 case 4: 212 printuint32(uint32(itf.typecode)) 213 case 8: 214 printuint64(uint64(itf.typecode)) 215 } 216 putchar(':') 217 print(itf.value) 218 putchar(')') 219 } 220 } 221 222 func printmap(m *hashmap) { 223 print("map[") 224 if m == nil { 225 print("nil") 226 } else { 227 print(uint(m.count)) 228 } 229 putchar(']') 230 } 231 232 func printptr(ptr uintptr) { 233 if ptr == 0 { 234 print("nil") 235 return 236 } 237 putchar('0') 238 putchar('x') 239 for i := 0; i < int(unsafe.Sizeof(ptr))*2; i++ { 240 nibble := byte(ptr >> (unsafe.Sizeof(ptr)*8 - 4)) 241 if nibble < 10 { 242 putchar(nibble + '0') 243 } else { 244 putchar(nibble - 10 + 'a') 245 } 246 ptr <<= 4 247 } 248 } 249 250 func printbool(b bool) { 251 if b { 252 printstring("true") 253 } else { 254 printstring("false") 255 } 256 }