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  }