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  }