github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/testdata/slice.go (about)

     1  package main
     2  
     3  import "unsafe"
     4  
     5  type MySlice [32]byte
     6  
     7  type myUint8 uint8
     8  
     9  type RecursiveSlice []RecursiveSlice
    10  
    11  // Indexing into slice with named type (regression test).
    12  var array = [4]int{
    13  	myUint8(2): 3,
    14  }
    15  
    16  func main() {
    17  	l := 5
    18  	foo := []int{1, 2, 4, 5}
    19  	bar := make([]int, l-2, l)
    20  	println("foo is nil?", foo == nil, nil == foo)
    21  	printslice("foo", foo)
    22  	printslice("bar", bar)
    23  	printslice("foo[1:2]", foo[1:2])
    24  	println("sum foo:", sum(foo))
    25  
    26  	// creating a slice of uncommon base type
    27  	assert(len(make([]struct{}, makeInt(4))) == 4)
    28  
    29  	// creating a slice with uncommon len, cap types
    30  	assert(len(make([]int, makeInt(2), makeInt(3))) == 2)
    31  	assert(len(make([]int, makeInt8(2), makeInt8(3))) == 2)
    32  	assert(len(make([]int, makeInt16(2), makeInt16(3))) == 2)
    33  	assert(len(make([]int, makeInt32(2), makeInt32(3))) == 2)
    34  	assert(len(make([]int, makeInt64(2), makeInt64(3))) == 2)
    35  	assert(len(make([]int, makeUint(2), makeUint(3))) == 2)
    36  	assert(len(make([]int, makeUint8(2), makeUint8(3))) == 2)
    37  	assert(len(make([]int, makeUint16(2), makeUint16(3))) == 2)
    38  	assert(len(make([]int, makeUint32(2), makeUint32(3))) == 2)
    39  	assert(len(make([]int, makeUint64(2), makeUint64(3))) == 2)
    40  	assert(len(make([]int, makeUintptr(2), makeUintptr(3))) == 2)
    41  	assert(len(make([]int, makeMyUint8(2), makeMyUint8(3))) == 2)
    42  
    43  	// indexing into a slice with uncommon index types
    44  	assert(foo[int(2)] == 4)
    45  	assert(foo[int8(2)] == 4)
    46  	assert(foo[int16(2)] == 4)
    47  	assert(foo[int32(2)] == 4)
    48  	assert(foo[int64(2)] == 4)
    49  	assert(foo[uint(2)] == 4)
    50  	assert(foo[uint8(2)] == 4)
    51  	assert(foo[uint16(2)] == 4)
    52  	assert(foo[uint32(2)] == 4)
    53  	assert(foo[uint64(2)] == 4)
    54  	assert(foo[uintptr(2)] == 4)
    55  
    56  	// slicing with uncommon low, high types
    57  	assert(len(foo[int(1):int(3)]) == 2)
    58  	assert(len(foo[int8(1):int8(3)]) == 2)
    59  	assert(len(foo[int16(1):int16(3)]) == 2)
    60  	assert(len(foo[int32(1):int32(3)]) == 2)
    61  	assert(len(foo[int64(1):int64(3)]) == 2)
    62  	assert(len(foo[uint(1):uint(3)]) == 2)
    63  	assert(len(foo[uint8(1):uint8(3)]) == 2)
    64  	assert(len(foo[uint16(1):uint16(3)]) == 2)
    65  	assert(len(foo[uint32(1):uint32(3)]) == 2)
    66  	assert(len(foo[uint64(1):uint64(3)]) == 2)
    67  	assert(len(foo[uintptr(1):uintptr(3)]) == 2)
    68  
    69  	// slicing an array with uncommon low, high types
    70  	arr := [4]int{1, 2, 4, 5}
    71  	assert(len(arr[int(1):int(3)]) == 2)
    72  	assert(len(arr[int8(1):int8(3)]) == 2)
    73  	assert(len(arr[int16(1):int16(3)]) == 2)
    74  	assert(len(arr[int32(1):int32(3)]) == 2)
    75  	assert(len(arr[int64(1):int64(3)]) == 2)
    76  	assert(len(arr[uint(1):uint(3)]) == 2)
    77  	assert(len(arr[uint8(1):uint8(3)]) == 2)
    78  	assert(len(arr[uint16(1):uint16(3)]) == 2)
    79  	assert(len(arr[uint32(1):uint32(3)]) == 2)
    80  	assert(len(arr[uint64(1):uint64(3)]) == 2)
    81  	assert(len(arr[uintptr(1):uintptr(3)]) == 2)
    82  
    83  	// slicing with max parameter (added in Go 1.2)
    84  	longfoo := []int{1, 2, 4, 5, 10, 11}
    85  	assert(cap(longfoo[int(1):int(3):int(5)]) == 4)
    86  	assert(cap(longfoo[int8(1):int8(3):int8(5)]) == 4)
    87  	assert(cap(longfoo[int16(1):int16(3):int16(5)]) == 4)
    88  	assert(cap(longfoo[int32(1):int32(3):int32(5)]) == 4)
    89  	assert(cap(longfoo[int64(1):int64(3):int64(5)]) == 4)
    90  	assert(cap(longfoo[uint(1):uint(3):uint(5)]) == 4)
    91  	assert(cap(longfoo[uint8(1):uint8(3):uint8(5)]) == 4)
    92  	assert(cap(longfoo[uint16(1):uint16(3):uint16(5)]) == 4)
    93  	assert(cap(longfoo[uint32(1):uint32(3):uint32(5)]) == 4)
    94  	assert(cap(longfoo[uint64(1):uint64(3):uint64(5)]) == 4)
    95  	assert(cap(longfoo[uintptr(1):uintptr(3):uintptr(5)]) == 4)
    96  
    97  	// slicing an array with max parameter (added in Go 1.2)
    98  	assert(cap(arr[int(1):int(2):int(4)]) == 3)
    99  	assert(cap(arr[int8(1):int8(2):int8(4)]) == 3)
   100  	assert(cap(arr[int16(1):int16(2):int16(4)]) == 3)
   101  	assert(cap(arr[int32(1):int32(2):int32(4)]) == 3)
   102  	assert(cap(arr[int64(1):int64(2):int64(4)]) == 3)
   103  	assert(cap(arr[uint(1):uint(2):uint(4)]) == 3)
   104  	assert(cap(arr[uint8(1):uint8(2):uint8(4)]) == 3)
   105  	assert(cap(arr[uint16(1):uint16(2):uint16(4)]) == 3)
   106  	assert(cap(arr[uint32(1):uint32(2):uint32(4)]) == 3)
   107  	assert(cap(arr[uint64(1):uint64(2):uint64(4)]) == 3)
   108  	assert(cap(arr[uintptr(1):uintptr(2):uintptr(4)]) == 3)
   109  
   110  	// copy
   111  	println("copy foo -> bar:", copy(bar, foo))
   112  	printslice("bar", bar)
   113  
   114  	// append
   115  	var grow []int
   116  	println("slice is nil?", grow == nil, nil == grow)
   117  	printslice("grow", grow)
   118  	grow = append(grow, 42)
   119  	printslice("grow", grow)
   120  	grow = append(grow, -1, -2)
   121  	printslice("grow", grow)
   122  	grow = append(grow, foo...)
   123  	printslice("grow", grow)
   124  	grow = append(grow)
   125  	printslice("grow", grow)
   126  	grow = append(grow, grow...)
   127  	printslice("grow", grow)
   128  
   129  	// append string to []bytes
   130  	bytes := append([]byte{1, 2, 3}, "foo"...)
   131  	print("bytes: len=", len(bytes), " cap=", cap(bytes), " data:")
   132  	for _, n := range bytes {
   133  		print(" ", n)
   134  	}
   135  	println()
   136  
   137  	// Test conversion from array to slice.
   138  	slice1 := []int{1, 2, 3, 4}
   139  	arr1 := (*[4]int)(slice1)
   140  	arr1[1] = -2
   141  	arr1[2] = 20
   142  	println("slice to array pointer:", arr1[0], arr1[1], arr1[2], arr1[3])
   143  
   144  	// Test unsafe.Add.
   145  	arr2 := [...]int{1, 2, 3, 4}
   146  	*(*int)(unsafe.Add(unsafe.Pointer(&arr2[0]), unsafe.Sizeof(int(1))*1)) = 5
   147  	*addInt(&arr2[0], 2) = 8
   148  	println("unsafe.Add array:", arr2[0], arr2[1], arr2[2], arr2[3])
   149  
   150  	// Test unsafe.Slice.
   151  	arr3 := [...]int{1, 2, 3, 4}
   152  	slice3 := unsafe.Slice(&arr3[1], 3)
   153  	slice3[0] = 9
   154  	slice3[1] = 15
   155  	println("unsafe.Slice array:", len(slice3), cap(slice3), slice3[0], slice3[1], slice3[2])
   156  
   157  	// Verify the fix in https://github.com/tinygo-org/tinygo/pull/119
   158  	var unnamed [32]byte
   159  	var named MySlice
   160  	assert(len(unnamed[:]) == 32)
   161  	assert(len(named[:]) == 32)
   162  	for _, c := range named {
   163  		assert(c == 0)
   164  	}
   165  
   166  	// Test recursive slices.
   167  	rs := []RecursiveSlice(nil)
   168  	println("len:", len(rs))
   169  }
   170  
   171  func printslice(name string, s []int) {
   172  	print(name, ": len=", len(s), " cap=", cap(s), " data:")
   173  	for _, n := range s {
   174  		print(" ", n)
   175  	}
   176  	println()
   177  }
   178  
   179  func sum(l []int) int {
   180  	sum := 0
   181  	for _, n := range l {
   182  		sum += n
   183  	}
   184  	return sum
   185  }
   186  
   187  func assert(ok bool) {
   188  	if !ok {
   189  		panic("assert failed")
   190  	}
   191  }
   192  
   193  // Helper functions used to hide const values from the compiler during IR
   194  // construction.
   195  
   196  func makeInt(x int) int             { return x }
   197  func makeInt8(x int8) int8          { return x }
   198  func makeInt16(x int16) int16       { return x }
   199  func makeInt32(x int32) int32       { return x }
   200  func makeInt64(x int64) int64       { return x }
   201  func makeUint(x uint) uint          { return x }
   202  func makeUint8(x uint8) uint8       { return x }
   203  func makeUint16(x uint16) uint16    { return x }
   204  func makeUint32(x uint32) uint32    { return x }
   205  func makeUint64(x uint64) uint64    { return x }
   206  func makeUintptr(x uintptr) uintptr { return x }
   207  func makeMyUint8(x myUint8) myUint8 { return x }
   208  
   209  func addInt(ptr *int, index uintptr) *int {
   210  	return (*int)(unsafe.Add(unsafe.Pointer(ptr), unsafe.Sizeof(int(1))*index))
   211  }