github.com/tardisgo/tardisgo@v0.0.0-20161119180838-e0dd9a7e46b5/tests/core/test.go (about)

     1  // THIS IS NOT PRETTY, IT IS A WORK-IN-PROGRESS
     2  
     3  // NOTE : No Output = success
     4  
     5  // TODO separate this jumble of tests into a set of smaller ones
     6  
     7  // This package should only test the core language functionality, all standard package tests moved elsewhere
     8  package main
     9  
    10  import (
    11  	"errors"
    12  	"fmt"
    13  	"runtime"
    14  	"unicode"
    15  	"unicode/utf8"
    16  	"unsafe"
    17  
    18  	//"haxegoruntime"
    19  
    20  	"github.com/tardisgo/tardisgo/haxe/hx"
    21  )
    22  
    23  //const tardisgoLibRuntimePath = "github.com/tardisgo/tardisgo/golibruntime"
    24  
    25  const tardisgoHeader = "/* TARDIS Go general header*/"
    26  
    27  const tardisgoHaxeHeader = `// Haxe specific header for each file
    28  `
    29  
    30  const ShowKnownErrors = false
    31  
    32  func loc(l string) string {
    33  	_, file, line, ok := runtime.Caller(2)
    34  	if !ok {
    35  		return "???"
    36  	}
    37  	return file + ":" + hx.CallString("", "Std.string", 1, line) + " " + l
    38  }
    39  
    40  func TEQ(l string, a, b interface{}) bool {
    41  	l = loc(l)
    42  	if a != b {
    43  		fmt.Println("TEQ error " + l + " ")
    44  		fmt.Println(a)
    45  		fmt.Println(b)
    46  		return false
    47  	}
    48  	return true
    49  }
    50  
    51  func TEQuint64(l string, a, b uint64) bool {
    52  	l = loc(l)
    53  	if a != b {
    54  		fmt.Println("TEQui64 error " + l + " ")
    55  		fmt.Println("high a", uint(a>>32))
    56  		fmt.Println("low a", uint(a&0xFFFFFFFF))
    57  		fmt.Println("high b", uint(b>>32))
    58  		fmt.Println("low b", uint(b&0xFFFFFFFF))
    59  		return false
    60  	}
    61  	return true
    62  }
    63  func TEQint64(l string, a, b int64) bool {
    64  	l = loc(l)
    65  	if a != b {
    66  		fmt.Println("TEQi64 error " + l + " ")
    67  		fmt.Println("high a", int(a>>32))
    68  		fmt.Println("low a", int(a&0xFFFFFFFF))
    69  		fmt.Println("high b", int(b>>32))
    70  		fmt.Println("low b", int(b&0xFFFFFFFF))
    71  		return false
    72  	}
    73  	return true
    74  }
    75  func TEQuint32(l string, a, b uint32) bool {
    76  	l = loc(l)
    77  	if a != b {
    78  		fmt.Println("TEQui32 error " + l + " ")
    79  		fmt.Println(a)
    80  		fmt.Println(b)
    81  		return false
    82  	}
    83  	return true
    84  }
    85  func TEQint32(l string, a, b int32) bool {
    86  	l = loc(l)
    87  	if a != b {
    88  		fmt.Println("TEQi32 error " + l + " ")
    89  		fmt.Println(a)
    90  		fmt.Println(b)
    91  		return false
    92  	}
    93  	return true
    94  }
    95  func TEQbyteSlice(l string, a, b []byte) bool {
    96  	l = loc(l)
    97  	if len(a) != len(b) {
    98  		fmt.Println("TEQbyteSlice error "+l+" ", a, b)
    99  		return false
   100  	}
   101  	ret := true
   102  	for i := range a {
   103  		if a[i] != b[i] {
   104  			fmt.Println("TEQbyteSlice error "+l+" ", a, b)
   105  			ret = false
   106  		}
   107  	}
   108  	return ret
   109  }
   110  func TEQruneSlice(l string, a, b []rune) bool {
   111  	l = loc(l)
   112  	if len(a) != len(b) {
   113  		fmt.Println("TEQruneSlice error "+l+" ", a, b)
   114  		return false
   115  	}
   116  	ret := true
   117  	for i := range a {
   118  		if a[i] != b[i] {
   119  			fmt.Println("TEQruneSlice error "+l+" ", a, b)
   120  			ret = false
   121  		}
   122  	}
   123  	return ret
   124  }
   125  func TEQintSlice(l string, a, b []int) bool {
   126  	l = loc(l)
   127  	//fmt.Println("TEQintSlice DEBUG: " + l + " ")
   128  	if len(a) != len(b) {
   129  		fmt.Println("TEQintSlice error "+l+" ", a, b)
   130  		return false
   131  	}
   132  	for i := range a {
   133  		if a[i] != b[i] {
   134  			fmt.Println("TEQintSlice error "+l+" ", a, b)
   135  			return false
   136  		}
   137  	}
   138  	return true
   139  }
   140  func TEQfloat(l string, a, b, maxDif float64) bool {
   141  	l = loc(l)
   142  	if a == b {
   143  		return true
   144  	}
   145  	dif := a - b
   146  	if dif < 0 {
   147  		dif = -dif
   148  	}
   149  	if dif > maxDif {
   150  		fmt.Println("TEQfloat error " + l + " ")
   151  		fmt.Println(a)
   152  		fmt.Println(b)
   153  		return false
   154  	}
   155  	return true
   156  }
   157  
   158  // CONSTANT TEST DATA
   159  const Name string = "this is my name"
   160  const ests bool = true
   161  const Pi float64 = 3.14159265358979323846
   162  const zero = 0.0 // untyped floating-point constant
   163  const (
   164  	size int = 1024
   165  	eof      = -1 // untyped integer constant
   166  )
   167  const a, b, c = 3, 4, "foo" // a = 3, b = 4, c = "foo", untyped integer and string constants
   168  const u, v float64 = 0, 3   // u = 0.0, v = 3.0
   169  const (
   170  	Sunday = iota
   171  	Monday
   172  	Tuesday
   173  	Wednesday
   174  	Thursday
   175  	Friday
   176  	Partyday
   177  	numberOfDays // this constant is not exported
   178  )
   179  const ( // iota is reset to 0
   180  	c0 = iota // c0 == 0
   181  	c1 = iota // c1 == 1
   182  	c2 = iota // c2 == 2
   183  )
   184  const (
   185  	_a = 1 << iota // a == 1 (iota has been reset)
   186  	_b = 1 << iota // b == 2
   187  	_c = 1 << iota // c == 4
   188  )
   189  const (
   190  	_u         = iota * 42 // u == 0     (untyped integer constant)
   191  	_v float64 = iota * 42 // v == 42.0  (float64 constant)
   192  	_w         = iota * 42 // w == 84    (untyped integer constant)
   193  )
   194  const _x = iota // x == 0 (iota has been reset)
   195  const _y = iota // y == 0 (iota has been reset)
   196  const (
   197  	bit0, mask0 = 1 << iota, 1<<iota - 1 // bit0 == 1, mask0 == 0
   198  	bit1, mask1                          // bit1 == 2, mask1 == 1
   199  	_, _                                 // skips iota == 2
   200  	bit3, mask3                          // bit3 == 8, mask3 == 7
   201  )
   202  const ren = '人'
   203  const Θ float64 = 3 / 2  // Θ == 1.0   (type float64, 3/2 is integer division)
   204  const Π float64 = 3 / 2. // Π == 1.5   (type float64, 3/2. is float division)
   205  const d = 1 << 3.0       // d == 8     (untyped integer constant)
   206  const e = 1.0 << 3       // e == 8     (untyped integer constant)
   207  const h = "foo" > "bar"  // h == true  (untyped boolean constant)
   208  const j = true           // j == true  (untyped boolean constant)
   209  const k = 'w' + 1        // k == 'x'   (untyped rune constant)
   210  const l = "hi"           // l == "hi"  (untyped string constant)
   211  const m = string(k)      // m == "x"   (type string)
   212  
   213  func testConst() {
   214  	TEQ("", Name, "this is my name")
   215  	TEQ("", ests, true)
   216  	TEQfloat("", Pi, 3.14159265358979323846, 0.00000000000001)
   217  	TEQ("", zero, 0.0) // untyped floating-point constant
   218  	TEQ("", size, 1024)
   219  	TEQ("", eof, -1) // untyped integer constant
   220  	// a = 3, b = 4, c = "foo", untyped integer and string constants
   221  	TEQ("", a, 3)
   222  	TEQ("", b, 4)
   223  	TEQ("", c, "foo")
   224  	// u = 0.0, v = 3.0
   225  	TEQ("", u, 0.0)
   226  	TEQ("", v, 3.0)
   227  	TEQ("", Sunday, 0)
   228  	TEQ("", Monday, 1)
   229  	TEQ("", Tuesday, 2)
   230  	TEQ("", Wednesday, 3)
   231  	TEQ("", Thursday, 4)
   232  	TEQ("", Friday, 5)
   233  	TEQ("", Partyday, 6)
   234  	TEQ("", numberOfDays, 7) // this constant is not exported
   235  	TEQ("", c0, 0)           // c0 == 0
   236  	TEQ("", c1, 1)           // c1 == 1
   237  	TEQ("", c2, 2)           // c2 == 2
   238  	TEQ("", _a, 1)           // a == 1 (iota has been reset)
   239  	TEQ("", _b, 2)           // b == 2
   240  	TEQ("", _c, 4)           // c == 4
   241  	TEQ("", _u, 0)           // u == 0     (untyped integer constant)
   242  	TEQ("", _v, 42.0)        // v == 42.0  (float64 constant)
   243  	TEQ("", _w, 84)          // w == 84    (untyped integer constant)
   244  	TEQ("", _x, 0)           // x == 0 (iota has been reset)
   245  	TEQ("", _y, 0)           // y == 0 (iota has been reset)
   246  	TEQ("", bit0, 1)
   247  	TEQ("", mask0, 0) // bit0 == 1, mask0 == 0
   248  	TEQ("", bit1, 2)
   249  	TEQ("", mask1, 1) // bit1 == 2, mask1 == 1
   250  	//_, _                                 // skips iota == 2
   251  	TEQ("", bit3, 8)
   252  	TEQ("", mask3, 7) // bit3 == 8, mask3 == 7
   253  	TEQ("", ren, '人')
   254  	TEQ("", Θ, 1.0)  // Θ == 1.0   (type float64, 3/2 is integer division)
   255  	TEQ("", Π, 1.5)  // Π == 1.5   (type float64, 3/2. is float division)
   256  	TEQ("", d, 8)    // d == 8     (untyped integer constant)
   257  	TEQ("", e, 8)    // e == 8     (untyped integer constant)
   258  	TEQ("", h, true) // h == true  (untyped boolean constant)
   259  	TEQ("", j, true) // j == true  (untyped boolean constant)
   260  	TEQ("", k, 'x')  // k == 'x'   (untyped rune constant)
   261  	TEQ("", l, "hi") // l == "hi"  (untyped string constant)
   262  	TEQ("", m, "x")  // m == "x"   (type string)
   263  }
   264  
   265  var testUTFlength = "123456789"
   266  
   267  func testUTF() {
   268  	var (
   269  		rA, rB, r  []rune
   270  		uS, s1, s2 string
   271  	)
   272  	rA = []rune{0x767d, 0x9d6c, 0x7fd4}
   273  	uS = string(rA) // "\u767d\u9d6c\u7fd4" == "白鵬翔"
   274  	rB = []rune(uS)
   275  	TEQruneSlice("", rA, rB)
   276  
   277  	s1 = "香港发生工厂班车砍人案12人受伤"
   278  	r = []rune(s1)
   279  	s2 = string(r)
   280  	TEQ("", s1, s2)
   281  
   282  	TEQ("", len(s1), 44)
   283  	TEQ("", len(testUTFlength), 9)
   284  
   285  	hellø := "hellø"
   286  	TEQ("", string([]byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}), hellø)
   287  	TEQbyteSlice("", []byte("hellø"), []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'})
   288  
   289  	TEQ("", "ø", hellø[4:])
   290  }
   291  
   292  var TestInit = "init() ran OK"
   293  var primes = [6]int{2, 3, 5, 7, 9, 2147483647}
   294  var iFace interface{} = nil
   295  
   296  func testInit() {
   297  	TEQ("", TestInit, "init() ran OK")
   298  	TEQintSlice("", primes[:], []int{2, 3, 5, 7, 9, 2147483647})
   299  	TEQ("", 9, primes[4]) // also testing array access with a constant index
   300  	TEQ("", nil, iFace)
   301  }
   302  
   303  var PublicStruct struct {
   304  	a int
   305  	b bool
   306  	c string
   307  	d float64
   308  	e interface{}
   309  	f [12]int
   310  	g [6]string
   311  	h [14]struct {
   312  		x bool
   313  		y [3]float64
   314  		z [6]interface{}
   315  	}
   316  }
   317  
   318  func testStruct() {
   319  	var PrivateStruct struct {
   320  		a int
   321  		b bool
   322  		c string
   323  		d float64
   324  		e interface{}
   325  		f [12]int
   326  		g [6]string
   327  		h [14]struct {
   328  			x bool
   329  			y [3]float64
   330  			z [6]interface{}
   331  		}
   332  	}
   333  	// check that everything is equally initialized
   334  	TEQ("", PublicStruct.a, PrivateStruct.a)
   335  	TEQ("", PublicStruct.b, PrivateStruct.b)
   336  	TEQ("", PublicStruct.c, PrivateStruct.c)
   337  	TEQfloat("", PublicStruct.d, PrivateStruct.d, 0.01)
   338  	TEQ("", PublicStruct.e, PrivateStruct.e)
   339  	//fmt.Println("", PublicStruct.f[:], PrivateStruct.f[:])
   340  	TEQintSlice("", PublicStruct.f[:], PrivateStruct.f[:])
   341  	PublicStruct.a = 42
   342  	PrivateStruct.a = 42
   343  	TEQ("", PublicStruct.a, PrivateStruct.a)
   344  	PublicStruct.c = Name
   345  	PrivateStruct.c = Name
   346  	TEQ("", PublicStruct.c, PrivateStruct.c)
   347  	for i := range PrivateStruct.h {
   348  		for j := range PrivateStruct.h[i].y {
   349  			PrivateStruct.h[i].y[j] = 42.0 * float64(i) * float64(j)
   350  			PublicStruct.h[i].y[j] = 42.0 * float64(i) * float64(j)
   351  			TEQfloat("", PrivateStruct.h[i].y[j], PublicStruct.h[i].y[j], 1.0)
   352  		}
   353  	}
   354  }
   355  func Sqrt(x float64) float64 {
   356  	z := x
   357  	for i := 0; i < 1000; i++ {
   358  		z -= (z*z - x) / (2.0 * x)
   359  	}
   360  	return z
   361  }
   362  
   363  func testFloat() { // and also slices!
   364  	TEQfloat("", Sqrt(1024), 32.0, 0.1)
   365  	threeD := make([][][]float64, 10)
   366  	for i := range threeD {
   367  		threeD[i] = make([][]float64, 10)
   368  		for j := range threeD[i] {
   369  			threeD[i][j] = make([]float64, 10)
   370  			for k := range threeD[i][j] {
   371  				threeD[i][j][k] = float64(i) * float64(j) * float64(k)
   372  				TEQfloat("", threeD[i][j][k], float64(i)*float64(j)*float64(k), 0.1)
   373  			}
   374  		}
   375  	}
   376  	// TODO add more here
   377  }
   378  
   379  func noCaller() float64 { // this should be removed by a good target compiler...
   380  	U_ := Sqrt(float64(64))
   381  	return U_
   382  }
   383  
   384  //var aPtr *int // TODO this should generate an error
   385  
   386  func twoRets(x int) (a int, b string) {
   387  	return 42 * x, "forty-two"
   388  }
   389  
   390  func testMultiRet() {
   391  	r1, r2 := twoRets(1)
   392  	TEQ("", r1, 42)
   393  	TEQ("", r2, "forty-two")
   394  }
   395  
   396  func testAppend() {
   397  	s0 := []int{0, 0}
   398  	s1 := append(s0, 2) // append a single element     s1 == []int{0, 0, 2}
   399  	TEQintSlice("", []int{0, 0, 2}, s1)
   400  	s2 := append(s1, 3, 5, 7) // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}
   401  	TEQintSlice("", []int{0, 0, 2, 3, 5, 7}, s2)
   402  	s3 := append(s2, s0...) // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
   403  	TEQintSlice("", []int{0, 0, 2, 3, 5, 7, 0, 0}, s3)
   404  	var t []interface{}
   405  	t = append(t, 42, 3.1415, "foo", nil) //       				 t == []interface{}{42, 3.1415, "foo"}
   406  	TEQ("", t[0], 42)
   407  	TEQ("", t[1], 3.1415)
   408  	TEQ("", t[2], "foo")
   409  	TEQ("", t[3], nil)
   410  
   411  	var b []byte
   412  	b = append(b, "bar"...)
   413  	TEQbyteSlice("", b, []byte{'b', 'a', 'r'})
   414  }
   415  
   416  func testHeader() {
   417  	// not sure how to test this
   418  }
   419  
   420  func testCopy() {
   421  	var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
   422  	var s = make([]int, 6)
   423  	n1 := copy(s, a[0:]) // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
   424  	TEQ("", n1, 6)
   425  	TEQintSlice("", s, []int{0, 1, 2, 3, 4, 5})
   426  	n2 := copy(s, s[2:]) // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
   427  	TEQ("", n2, 4)
   428  	TEQintSlice("", s, []int{2, 3, 4, 5, 4, 5})
   429  	var b = make([]byte, 5)
   430  	n3 := copy(b, "Hello, World!") // n3 == 5, b == []byte("Hello")
   431  	TEQ("", n3, 5)
   432  	TEQbyteSlice("", b, []byte("Hello"))
   433  }
   434  
   435  func testInFuncPtr() { // there is no way to stop this use of pointers...
   436  	var ss = 12
   437  	var ssa = &ss
   438  	TEQ("", *ssa, 12)
   439  }
   440  
   441  func testCallByValue(a struct{ b int }, x [10]int, y []int, z int) {
   442  	a.b = 42
   443  	x[0] = 43
   444  	y[0] = 44
   445  	z = 45
   446  }
   447  
   448  func testCallByReference(a *struct{ b int }, x *[10]int, y []int, z *int) {
   449  	a.b = 46
   450  	x[0] = 47
   451  	y[0] = 48
   452  	*z = 49
   453  }
   454  func testTweakFloatByReference(i *float64) {
   455  	if *i == 0 {
   456  		*i = 0
   457  	} else {
   458  		*i = Sqrt(*i)
   459  	}
   460  }
   461  func testCallBy() {
   462  	var a struct {
   463  		b int
   464  	}
   465  	var x [10]int
   466  	var y []int = make([]int, 1)
   467  	var z int
   468  	testCallByValue(a, x, y, z)
   469  	TEQ("", a.b, 0)
   470  	TEQ("", x[0], 0)
   471  	TEQ("", y[0], 44)
   472  	TEQ("", z, 0)
   473  
   474  	testCallByReference(&a, &x, y, &z)
   475  	TEQ("", a.b, 46)
   476  	TEQ("", x[0], 47)
   477  	TEQ("", y[0], 48)
   478  	TEQ("", z, 49)
   479  
   480  	var xx [10]float64
   481  	for i := range x {
   482  		xx[i] = float64(i * i)
   483  		testTweakFloatByReference(&xx[i])
   484  		TEQfloat("", xx[i], float64(i), 0.1)
   485  	}
   486  }
   487  
   488  func testMap() { // and map-like constucts
   489  	// vowels[ch] is true if ch is a vowel
   490  	vowels := [128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': true, 'y': true}
   491  	for k, v := range vowels {
   492  		switch k {
   493  		case 'a', 'e', 'i', 'o', 'u', 'y':
   494  			TEQ("", true, v)
   495  		default:
   496  			TEQ("", false, v)
   497  		}
   498  	}
   499  
   500  	filter := [10]float64{-1, 4: -0.1, -0.1, 9: -1}
   501  	TEQfloat("", filter[5], -0.1, 0.01)
   502  
   503  	// frequencies in Hz for equal-tempered scale (A4 = 440Hz)
   504  	noteFrequency := map[string]float64{
   505  		"C0": 16.35, "D0": 18.35, "E0": 20.60, "F0": 21.83,
   506  		"G0": 24.50, "A0": 27.50, "B0": 30.87,
   507  	}
   508  	noteFrequency["Test"] = 42.42
   509  	TEQ("", len(noteFrequency), 8)
   510  	for k, v := range noteFrequency {
   511  		r := 0.0
   512  		switch k {
   513  		case "C0":
   514  			r = 16.35
   515  		case "D0":
   516  			r = 18.35
   517  		case "E0":
   518  			r = 20.60
   519  		case "F0":
   520  			r = 21.83
   521  		case "G0":
   522  			r = 24.50
   523  		case "A0":
   524  			r = 27.50
   525  		case "B0":
   526  			r = 30.87
   527  		case "Test":
   528  			r = 42.42
   529  		default:
   530  			r = -1
   531  		}
   532  		if !TEQfloat(""+" Value itterator in map", v, r, 0.01) {
   533  			break
   534  		}
   535  	}
   536  	x, isok := noteFrequency["Test"]
   537  	TEQfloat("", 42.42, x, 0.01)
   538  	TEQ("", true, isok)
   539  	_, notok := noteFrequency["notHere"]
   540  	TEQ("", false, notok)
   541  	delete(noteFrequency, "Test")
   542  	_, isok = noteFrequency["Test"]
   543  	TEQ("", false, isok)
   544  
   545  	if true { // just to get a new scope
   546  		// frequencies in Hz for equal-tempered scale (A4 = 440Hz)
   547  		noteFrequency2 := map[float64]string{
   548  			16.35: "C0", 18.35: "D0", 20.60: "E0", 21.83: "F0",
   549  			24.50: "G0", 27.50: "A0", 30.87: "B0",
   550  		}
   551  		noteFrequency2[42.42] = "Test"
   552  		TEQ("", len(noteFrequency2), 8)
   553  		for k, v := range noteFrequency2 {
   554  			r := ""
   555  			switch k {
   556  			case 16.35:
   557  				r = "C0"
   558  			case 18.35:
   559  				r = "D0"
   560  			case 20.60:
   561  				r = "E0"
   562  			case 21.83:
   563  				r = "F0"
   564  			case 24.50:
   565  				r = "G0"
   566  			case 27.50:
   567  				r = "A0"
   568  			case 30.87:
   569  				r = "B0"
   570  			case 42.42:
   571  				r = "Test"
   572  			default:
   573  				r = "NOT FOUND"
   574  			}
   575  			if !TEQ(""+" Value itterator in map", v, r) {
   576  				break
   577  			}
   578  		}
   579  		x, isok := noteFrequency2[42.42]
   580  		TEQ("", "Test", x)
   581  		TEQ("", true, isok)
   582  		_, notok := noteFrequency2[-42]
   583  		TEQ("", false, notok)
   584  		delete(noteFrequency2, 42.42)
   585  		_, isok = noteFrequency2[43.42]
   586  		TEQ("", false, isok)
   587  	}
   588  }
   589  
   590  type MyFloat float64
   591  type MyFloat2 MyFloat
   592  
   593  var namedGlobal MyFloat
   594  
   595  type IntArray [8]int
   596  
   597  type (
   598  	Point struct {
   599  		x, y float64
   600  	}
   601  	Polar Point
   602  )
   603  
   604  var myPolar Polar
   605  
   606  func (f MyFloat) Abs() float64 {
   607  	if f < 0 {
   608  		return float64(-f)
   609  	}
   610  	return float64(f)
   611  }
   612  
   613  func (f MyFloat) UncalledMethod() {
   614  	panic("Why are we here?")
   615  }
   616  
   617  func (mf *MyFloat) set42() {
   618  	*mf = 42
   619  }
   620  
   621  // this is required as Go does not allow the MyFloat2 type to inheret MyFloat.Abs
   622  func (f MyFloat2) Abs() float64 {
   623  	if f < 0 {
   624  		return float64(-f)
   625  	}
   626  	return float64(f)
   627  }
   628  func (f MyFloat2) Scale(x float64) float64 {
   629  	return float64(f) * x
   630  }
   631  
   632  func (ia *IntArray) set42() {
   633  	for i := range ia {
   634  		ia[i] = 42
   635  	}
   636  }
   637  func (p Polar) BearVal() bool {
   638  	return p.x == p.y
   639  }
   640  
   641  // from the language spec section Method Values
   642  type T struct {
   643  	a int
   644  }
   645  
   646  func (tv T) Mv(a int) int          { return a } // value receiver
   647  func (tp *T) Mp(f float32) float32 { return f } // pointer receiver
   648  
   649  var t T
   650  var pt *T
   651  
   652  func testNamed() {
   653  	var ia IntArray
   654  	for i := range ia {
   655  		ia[i] = i
   656  	}
   657  	TEQintSlice("", ia[:], []int{0, 1, 2, 3, 4, 5, 6, 7})
   658  	var namedLocal MyFloat = 41.42
   659  	namedGlobal = 42.42
   660  	namedLocal += 1.0
   661  	TEQfloat("", float64(namedGlobal), float64(namedLocal), 0.0002)
   662  	myPolar.x = 11.11
   663  	myPolar.y = 10.11
   664  	myPolar.y++
   665  	TEQfloat("", float64(myPolar.x), float64(myPolar.y), 0.0002)
   666  	// method expression tests...
   667  	TEQ("", myPolar.BearVal(), true)
   668  	f := MyFloat(-555)
   669  	g := MyFloat2(-555)
   670  	TEQfloat("", f.Abs(), g.Abs(), 0.0002)
   671  	fi := Abser(f)
   672  	gi := Abser(g)
   673  	TEQfloat("", fi.Abs(), gi.Abs(), 0.0002)
   674  
   675  	ia.set42()
   676  	f.set42()
   677  	TEQfloat("", float64(ia[3]), float64(f), 0.0002)
   678  
   679  	// from the language spec section on method values (requires ssa.MakeClosure instruction)
   680  	f1 := t.Mv
   681  	TEQ("", f1(7), t.Mv(7))
   682  	pt = &t
   683  	f2 := pt.Mp
   684  	TEQ("", f2(7), pt.Mp(7))
   685  	f3 := pt.Mv
   686  	TEQ("", f3(7), (*pt).Mv(7))
   687  	f4 := t.Mp
   688  	TEQ("", f4(7), (&t).Mp(7))
   689  
   690  	// more from the language spec on Method expressions
   691  
   692  	TEQ("", t.Mv(7), T.Mv(t, 7))
   693  	TEQ("", t.Mv(7), (T).Mv(t, 7))
   694  
   695  	f1a := T.Mv
   696  	TEQ("", t.Mv(7), f1a(t, 7))
   697  	f2a := (T).Mv
   698  	TEQ("", t.Mv(7), f2a(t, 7))
   699  
   700  }
   701  
   702  var hypot1 = func(x, y float64) float64 {
   703  	return Sqrt(x*x + y*y)
   704  }
   705  
   706  func testFuncPtr() {
   707  	var hypot2 = func(x, y float64) float64 {
   708  		return Sqrt(x*x + y*y)
   709  	}
   710  	TEQfloat("", hypot1(3, 4), hypot2(3, 4), 0.2)
   711  }
   712  
   713  var int64_max int64 = 0x7FFFFFFFFFFFFFFF
   714  var int32_max int32 = 0x7FFFFFFF
   715  var int16_max int16 = 0x7FFF
   716  var int8_max int8 = 0x7F
   717  var uint64_max uint64 = 0xFFFFFFFFFFFFFFFF
   718  var uint32_max uint32 = 0xFFFFFFFF // This value too big and too ambiguous for cpp when held as an Int...
   719  var uint16_max uint16 = 0xFFFF
   720  var uint8_max uint8 = 0xFF
   721  var int8_mostNeg int8 = -128
   722  var int16_mostNeg int16 = -32768
   723  var int32_mostNeg int32 = -2147483648
   724  var int64_mostNeg int64 = -9223372036854775808
   725  
   726  var five int = 5
   727  var three int = 3
   728  
   729  var uint64Global uint64
   730  var uint64GlobalArray [4]uint64
   731  
   732  func testIntOverflow() { //TODO add int64
   733  	TEQ(""+" int16 overflow test 1", int16_max+1, int16_mostNeg)
   734  	TEQ(""+" int8 overflow test 1", int8_max+1, int8_mostNeg)
   735  	TEQ(""+" uint16 overflow test 2", uint16(uint16_max+1), uint16(0))
   736  	TEQ(""+" uint8 overflow test 2", uint8(uint8_max+1), uint8(0))
   737  	TEQ(""+" int8 overflow test 3", int8(int8_mostNeg-1), int8_max)
   738  	TEQ(""+" int16 overflow test 3", int16(int16_mostNeg-1), int16_max)
   739  
   740  	TEQint64(""+" int64 overflow test 1 ", int64_max+1, int64_mostNeg)
   741  	TEQint32(""+" int32 overflow test 1 ", int32_max+1, int32_mostNeg)
   742  	TEQuint64(""+" uint64 overflow test 2 ", uint64(uint64_max+1), uint64(0))
   743  	TEQuint32(""+" uint32 overflow test 2 ", uint32(uint32_max+1), uint32(0))
   744  
   745  	TEQint32(""+" int32 overflow test 3 ", int32(int32_mostNeg-int32(1)), int32_max)
   746  	TEQint64(""+" int64 overflow test 3 ", int64(int64_mostNeg-int64(1)), int64_max)
   747  
   748  	//Math.imul test case at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
   749  	TEQuint32("", ((uint32_max << 1) * 5), uint32_max+1-10)
   750  	TEQuint32("", (((uint32_max << 1) + 1) * 5), uint32_max+1-5)
   751  
   752  	/* from Go spec:
   753  	   For two integer values x and y, the integer quotient q = x / y and remainder r = x % y satisfy the following relationships:
   754  
   755  	   x = q*y + r  and  |r| < |y|
   756  	   with x / y truncated towards zero ("truncated division").
   757  
   758  	    x     y     x / y     x % y
   759  	    5     3       1         2
   760  	   -5     3      -1        -2
   761  	    5    -3      -1         2
   762  	   -5    -3       1        -2
   763  
   764  	*/
   765  
   766  	TEQ("", five/three, 1)
   767  	TEQ("", five%three, 2)
   768  	TEQ("", (-five)/three, -1)
   769  	TEQ("", (-five)%three, -2)
   770  	TEQ("", five/(-three), -1)
   771  	TEQ("", five%(-three), 2)
   772  	TEQ("", (-five)/(-three), 1)
   773  	TEQ("", (-five)%(-three), -2)
   774  
   775  	TEQint64("", int64(five)/int64(three), int64(1))
   776  	TEQint64("", int64(five)%int64(three), int64(2))
   777  	TEQint64("", int64(-five)/int64(three), int64(-1))
   778  	TEQint64("", int64(-five)%int64(three), int64(-2))
   779  	TEQint64("", int64(five)/int64(-three), int64(-1))
   780  	TEQint64("", int64(five)%int64(-three), int64(2))
   781  	TEQint64("", int64(-five)/int64(-three), int64(1))
   782  	TEQint64("", int64(-five)%int64(-three), int64(-2))
   783  
   784  	/*
   785  		As an exception to this rule, if the dividend x is the most negative value for the int type of x,
   786  		the quotient q = x / -1 is equal to x (and r = 0).
   787  	*/
   788  	TEQint64(""+" int64 div special case", int64_mostNeg/int64(-1), int64_mostNeg)
   789  	TEQint64(""+" int64 mod special case", int64_mostNeg%int64(-1), 0)
   790  	TEQint32(""+" int32 div special case", int32(int32_mostNeg/int32(-1)), int32_mostNeg)
   791  	TEQint32(""+" int32 mod special case", int32_mostNeg%int32(-1), 0)
   792  	if int16(int16_mostNeg/int16(-1)) != int16_mostNeg {
   793  		fmt.Println("" + " int16 div special case")
   794  	}
   795  	if int16(int16_mostNeg%int16(-1)) != int16(0) {
   796  		fmt.Println("" + " int16 mod special case")
   797  	}
   798  	if int8(int8_mostNeg/int8(-1)) != int8_mostNeg {
   799  		fmt.Println("" + " int8 div special case")
   800  	}
   801  	if int8(int8_mostNeg%int8(-1)) != int8(0) {
   802  		fmt.Println("" + " int8 mod special case")
   803  	}
   804  
   805  	/*THESE VALUES ARE NOT IN THE SPEC, SO UNTESTED
   806  	if uint64(int64_mostNeg)/0xFFFFFFFFFFFFFFFF == uint64(int64_mostNeg) {
   807  		fmt.Println("" + " uint64 div special case")
   808  	}
   809  	if uint64(int64_mostNeg)%0xFFFFFFFFFFFFFFFF == uint64(0) {
   810  		fmt.Println("" + " uint64 mod special case")
   811  	}
   812  	if uint32(int32_mostNeg)/0xFFFFFFFF == uint32(int32_mostNeg) {
   813  		fmt.Println("" + " uint32 div special case")
   814  	}
   815  	if uint32(int32_mostNeg)%0xFFFFFFFF == uint32(0) {
   816  		fmt.Println("" + " uint32 mod special case")
   817  	}
   818  	if uint16(int16_mostNeg)/0xFFFF == uint16(int16_mostNeg) {
   819  		fmt.Println("" + " uint16 div special case")
   820  	}
   821  	if uint16(int16_mostNeg)%0xFFFF == uint16(0) {
   822  		fmt.Println("" + " uint16 mod special case")
   823  	}
   824  	if uint8(int8_mostNeg)/0xFF == uint8(int8_mostNeg) {
   825  		fmt.Println("" + " uint8 div special case")
   826  	}
   827  	if uint8(int8_mostNeg)%0xFF == uint8(0) {
   828  		fmt.Println("" + " uint8 mod special case")
   829  	}
   830  	*/
   831  
   832  	//TODO more tests for unsigned comparisons, need to check all possibilities are covered
   833  	TEQ("", uint8(int8_mostNeg) > uint8(0), true)
   834  	TEQ("", uint8(int8_mostNeg) < uint8(0), false)
   835  	TEQ("", uint16(int16_mostNeg) > uint16(0), true)
   836  	TEQ("", uint16(int16_mostNeg) < uint16(0), false)
   837  
   838  	TEQ("", uint32(int32_mostNeg) > uint32(0), true)
   839  	TEQ("", uint32(int32_mostNeg) < uint32(0), false)
   840  	TEQ(""+" uint64(int64_mostNeg) > uint64(0) ", uint64(int64_mostNeg) > uint64(0), true)
   841  	TEQ("", uint64(int64_mostNeg) < uint64(0), false)
   842  
   843  	//TEQint64("", int64(int64_mostNeg), int64(uint64(0x8000000000000000)))
   844  	//fmt.Println(float64(int64_mostNeg))
   845  	//fmt.Println(int64_mostNeg)
   846  	uint64Global = uint64(int64_mostNeg)
   847  	TEQuint64("", uint64Global, uint64(0x8000000000000000))
   848  
   849  	for i := range uint64GlobalArray {
   850  		uint64GlobalArray[i] = uint64(int64_mostNeg)
   851  		TEQ(""+" uint64(int64_mostNeg) > uint64(0) [Array] ", uint64(uint64GlobalArray[i]) > uint64(0), true)
   852  	}
   853  
   854  	// TODO test for equality too & check these constants are not being resolved by the compiler, rather than genereating tests!
   855  	TEQ("", uint8(int8_mostNeg)-uint8(42) > uint8(0), true)
   856  	TEQ("", uint8(int8_mostNeg)-uint8(42) < uint8(three), false)
   857  	TEQ("", uint16(int16_mostNeg)-uint16(42) > uint16(0), true)
   858  	TEQ("", uint16(0xffff)-uint16(five) < uint16(three), false)
   859  	TEQ("", uint32(0xffffffff)-uint32(five) > uint32(0), true)
   860  	TEQ("", uint32(0xffffffff)-uint32(five) < uint32(three), false)
   861  	TEQ("", uint64(0xffffffffffffffff)-uint64(five) > uint64(0), true)
   862  	TEQ("", uint64(0xffffffffffffffff)-uint64(five) < uint64(three), false)
   863  	TEQ("", uint8(0xff) > uint8(0xfe)-uint8(five), true)
   864  	TEQ("", uint8(five) < uint8(three), false)
   865  	TEQ("", uint16(0xffff) > uint16(0xfffe)-uint16(five), true)
   866  	TEQ("", uint16(10000)-uint16(five) < uint16(1000), false)
   867  	TEQ("", uint32(0xffffffff) > uint32(0xfffffffe)-uint32(five), true)
   868  	TEQ("", uint32(12)-uint32(five) < uint32(three), false)
   869  	TEQ("", uint64(0xffffffffffffffff) > uint64(0xfffffffffffffffe)-uint64(five), true)
   870  	TEQ("", uint64(12)-uint64(five) < uint64(three), false)
   871  
   872  	// test Float / Int64 conversions
   873  	fiveI64 := int64(five)
   874  	TEQfloat("", float64(fiveI64), 5.0, 0.1)
   875  	TEQfloat("", float64(int32_mostNeg), float64(-2147483648.0), 0.1)
   876  
   877  	TEQint64(""+" big -ve int64 division",
   878  		int64_mostNeg/int64(100000), int64(-9223372036854775808)/int64(100000))
   879  
   880  	TEQfloat(""+" PHP error",
   881  		float64(int64_mostNeg/int64(100000)), float64(int64(-9223372036854775808)/int64(100000)), float64(1.0))
   882  	TEQfloat(""+" PHP error ",
   883  		float64(int64_max/200), float64(int64(0x7fffffffffffffff)/200), float64(10.0))
   884  	TEQfloat("", float64(int64_mostNeg+1), float64(int64(-9223372036854775808+1)), float64(2000.0))
   885  	TEQfloat("", float64(int64_mostNeg), float64(int64(-9223372036854775808)), float64(2000.0))
   886  	TEQfloat("", float64(uint64Global), float64(int64(0x7fffffffffffffff)), float64(2000.0))
   887  	uint64Global = 0xFFFFFFFFFFFFFFFF
   888  	TEQfloat("", float64(uint64Global), float64(uint64(0xffffffffffffffff)), float64(2000.0))
   889  
   890  	// tests below removed to avoid also loading the math package
   891  	//TEQint64(""+" NaN ->int64 conversion", int64(math.NaN()), -9223372036854775808)
   892  	//TEQuint64(""+" NaN ->uint64 conversion (error on php)", uint64(math.NaN()), 9223372036854775808)
   893  
   894  	myPi := float64(3)
   895  	myPi64 := int64(myPi)
   896  	myPu64 := uint64(myPi)
   897  	limit := float64(1 << 52)
   898  	loops := 0
   899  	for myPi < limit {
   900  		loops++
   901  		a := TEQint64(""+" +ve float->int64 conversion  ", int64(myPi), myPi64)
   902  		b := TEQint64(""+" -ve float->int64 conversion  ", int64(-myPi), -myPi64)
   903  		c := TEQuint64(""+" float->uint64 conversion  ", uint64(myPi), myPu64)
   904  		d := TEQfloat(""+" int64->Float conversion  ", myPi, float64(myPi64), 0)
   905  		e := TEQfloat(""+" uint64->Float conversion  ", myPi, float64(myPu64), 0)
   906  		if a == false || b == false || c == false || d == false || e == false {
   907  			fmt.Println("i64 loops=", loops, "myPi=", myPi, "myPi64=", myPi64, "myPu64=", myPu64)
   908  			break
   909  		}
   910  		myPi *= myPi
   911  		myPi64 *= myPi64
   912  		myPu64 *= myPu64
   913  	}
   914  
   915  	itter := 0
   916  	for u := uint64(1); itter < 53; u = u<<1 + 1 {
   917  		f := float64(u)
   918  		fu := uint64(f)
   919  		if u != fu {
   920  			fmt.Println("uint64/float64 conversion error", itter, u, f, fu, u == fu)
   921  		}
   922  		itter++
   923  	}
   924  }
   925  
   926  func testSlices() {
   927  	// from the Go tour...
   928  	p := []int{2, 3, 5, 7, 11, 13}
   929  	TEQintSlice("", p[1:4], []int{3, 5, 7})
   930  	TEQintSlice("", p[:3], []int{2, 3, 5})
   931  	TEQintSlice("", p[4:], []int{11, 13})
   932  
   933  	a := make([]int, 5)
   934  	TEQintSlice("", a, []int{0, 0, 0, 0, 0})
   935  	TEQ("", len(a), 5)
   936  	TEQ("", cap(a), 5)
   937  	b := make([]int, 0, 5)
   938  	TEQintSlice("", b, []int{})
   939  	TEQ("", len(b), 0)
   940  	TEQ("", cap(b), 5)
   941  	c := b[:2]
   942  	TEQintSlice("", c, []int{0, 0})
   943  	TEQ("", len(c), 2)
   944  	TEQ("", cap(c), 5)
   945  	d := c[2:5]
   946  	TEQintSlice("", d, []int{0, 0, 0})
   947  	TEQ("", len(d), 3)
   948  	TEQ("", cap(d), 3)
   949  
   950  	var z []int
   951  	TEQ("", len(z), 0)
   952  	TEQ("", cap(z), 0)
   953  	TEQ("", z == nil, true)
   954  
   955  }
   956  
   957  func testUTF8() {
   958  	b := []byte("Hello, 世界")
   959  	r, size := utf8.DecodeLastRune(b)
   960  	TEQ("", '界', r)
   961  	TEQ("", size, 3)
   962  	b = b[:len(b)-size]
   963  	r, size = utf8.DecodeLastRune(b)
   964  	TEQ("", '世', r)
   965  	TEQ("", size, 3)
   966  	b = b[:len(b)-size]
   967  	r, size = utf8.DecodeLastRune(b)
   968  	TEQ("", ' ', r)
   969  	TEQ("", size, 1)
   970  
   971  	//fmt.Println("len(Zi)=", len("字"), hx.CodeInt(`'字'.length;`))
   972  
   973  	str := "Hello, 世界"
   974  	r, size = utf8.DecodeLastRuneInString(str)
   975  	TEQ("", '界', r)
   976  	TEQ("", size, 3)
   977  	str = str[:len(str)-size]
   978  	r, size = utf8.DecodeLastRuneInString(str)
   979  	TEQ("", '世', r)
   980  	TEQ("", size, 3)
   981  	str = str[:len(str)-size]
   982  	r, size = utf8.DecodeLastRuneInString(str)
   983  	TEQ("", ' ', r)
   984  	TEQ("", size, 1)
   985  
   986  	ru := '世'
   987  	buf := make([]byte, 3)
   988  	n := utf8.EncodeRune(buf, ru)
   989  	TEQ("", n, 3)
   990  	TEQbyteSlice("", buf, []byte{228, 184, 150})
   991  
   992  	buf = []byte{228, 184, 150} // 世
   993  	TEQ("", true, utf8.FullRune(buf))
   994  	TEQ("", false, utf8.FullRune(buf[:2]))
   995  
   996  	str = "世"
   997  	TEQ("", true, utf8.FullRuneInString(str))
   998  	//if ShowKnownErrors || hx.GetInt("", "'字'.length") == 3 {
   999  	TEQ(""+" NOTE: known error handling incorrect strings on UTF16 platforms", false, utf8.FullRuneInString(str[:2]))
  1000  	//}
  1001  	buf = []byte("Hello, 世界")
  1002  	TEQ("", 13, len(buf))
  1003  	TEQ("", 9, utf8.RuneCount(buf))
  1004  
  1005  	str = "Hello, 世界"
  1006  	TEQ("", 13, len(str))
  1007  	TEQ("", 9, utf8.RuneCountInString(str))
  1008  
  1009  	TEQ("", 1, utf8.RuneLen('a'))
  1010  	TEQ("", 3, utf8.RuneLen('界'))
  1011  
  1012  	buf = []byte("a界")
  1013  	TEQ("", true, utf8.RuneStart(buf[0]))
  1014  	TEQ("", true, utf8.RuneStart(buf[1]))
  1015  	TEQ("", false, utf8.RuneStart(buf[2]))
  1016  
  1017  	valid := []byte("Hello, 世界")
  1018  	invalid := []byte{0xff, 0xfe, 0xfd}
  1019  	TEQ("", true, utf8.Valid(valid))
  1020  	TEQ("", false, utf8.Valid(invalid))
  1021  
  1022  	valid_rune := 'a'
  1023  	invalid_rune := rune(0xfffffff)
  1024  	TEQ("", true, utf8.ValidRune(valid_rune))
  1025  	TEQ("", false, utf8.ValidRune(invalid_rune))
  1026  
  1027  	valid_string := "Hello, 世界"
  1028  	invalid_string := string([]byte{0xff, 0xfe, 0xfd})
  1029  	TEQ("", true, utf8.ValidString(valid_string))
  1030  	//if ShowKnownErrors || hx.GetInt("", "'字'.length") == 3 {
  1031  	TEQ(""+" NOTE: known error handling incorrect strings on UTF16 platforms", false, utf8.ValidString(invalid_string))
  1032  	//}
  1033  }
  1034  
  1035  func testChan() {
  1036  	c := make(chan int, 2)
  1037  	c <- 1
  1038  	c <- 2
  1039  	close(c)
  1040  	TEQ("", <-c, 1)
  1041  	TEQ("", <-c, 2)
  1042  	v, ok := <-c
  1043  	TEQ("", v, 0)
  1044  	TEQ("", ok, false)
  1045  
  1046  	ch := make(chan bool, 2)
  1047  	ch <- true
  1048  	ch <- true
  1049  	close(ch)
  1050  	rangeCount := 0
  1051  	for v := range ch {
  1052  		TEQ("", v, true)
  1053  		rangeCount++
  1054  	}
  1055  	TEQ("", rangeCount, 2)
  1056  
  1057  	//TODO much more to come here...
  1058  }
  1059  
  1060  func testComplex() {
  1061  
  1062  	var x, y, z complex64
  1063  	var ss complex128
  1064  
  1065  	x = 1 + 2i
  1066  	TEQfloat("", float64(real(x)), 1, 0.1)
  1067  	TEQfloat("", float64(imag(x)), 2, 0.1)
  1068  
  1069  	y = complex(3, 4)
  1070  	TEQfloat("", float64(real(y)), 3, 0.1)
  1071  	TEQfloat("", float64(imag(y)), 4, 0.1)
  1072  
  1073  	//this previously failed in the SSA interpreter
  1074  	z = -x
  1075  	TEQfloat("", float64(real(z)), -1, 0.1)
  1076  	TEQfloat("", float64(imag(z)), -2, 0.1)
  1077  
  1078  	z = x + y
  1079  	TEQfloat("", float64(real(z)), 4, 0.1)
  1080  	TEQfloat("", float64(imag(z)), 6, 0.1)
  1081  
  1082  	z = x - y
  1083  	TEQfloat("", float64(real(z)), -2, 0.1)
  1084  	TEQfloat("", float64(imag(z)), -2, 0.1)
  1085  
  1086  	z = x + y - y
  1087  	TEQfloat("", float64(real(z)), float64(real(x)), 0.1)
  1088  	TEQfloat("", float64(imag(z)), float64(imag(x)), 0.1)
  1089  	/*
  1090  		z = x * y
  1091  		printf64("real(x*y)", float64(real(z)))
  1092  		printf64("imag(x*y)", float64(imag(z)))
  1093  
  1094  		z = x / y
  1095  		printf64("real(x/y)", float64(real(z)))
  1096  		printf64("imag(x/y)", float64(imag(z)))
  1097  	*/
  1098  	z = x * y / y
  1099  	TEQfloat("", float64(real(z)), float64(real(x)), 0.1)
  1100  	TEQfloat("", float64(imag(z)), float64(imag(x)), 0.1)
  1101  
  1102  	TEQ("", x == y, false)
  1103  
  1104  	TEQ("", x != y, true)
  1105  
  1106  	ss = complex128(x)
  1107  	tt := complex128(y)
  1108  	TEQ("", ss != tt, true)
  1109  }
  1110  
  1111  var aString = "A"
  1112  var aaString = "AA"
  1113  var bbString = "BB"
  1114  
  1115  func testString() {
  1116  	TEQ("", aString <= "A", true)
  1117  	TEQ("", aString <= aaString, true)
  1118  	TEQ("", aString > aaString, false)
  1119  	TEQ("", aString == aaString, false)
  1120  	TEQ("", aString+aString == aaString, true)
  1121  	TEQ("", bbString < aaString, false)
  1122  }
  1123  
  1124  func adder() func(int) int {
  1125  	sum := 0
  1126  	return func(x int) int {
  1127  		sum += x
  1128  		return sum
  1129  	}
  1130  }
  1131  
  1132  // fib returns a function that returns
  1133  // successive Fibonacci numbers.
  1134  func fib() func() int {
  1135  	a, b := 0, 1
  1136  	return func() int {
  1137  		a, b = b, a+b
  1138  		return a
  1139  	}
  1140  }
  1141  
  1142  func testClosure() {
  1143  	// example from the go tour
  1144  	pos, neg := adder(), adder()
  1145  	for i := 0; i < 10; i++ {
  1146  		pos(i)
  1147  		neg(-2 * i)
  1148  	}
  1149  	TEQ("", pos(0), 45)
  1150  	TEQ("", neg(0), -90)
  1151  
  1152  	// example from http://jordanorelli.tumblr.com/post/42369331748/function-types-in-go-golang
  1153  	x := 5
  1154  	fn := func(y int) {
  1155  		TEQ("", x, y)
  1156  	}
  1157  	fn(5)
  1158  	x++
  1159  	fn(6)
  1160  
  1161  	f := fib()
  1162  	TEQ("", f(), 1)
  1163  	TEQ("", f(), 1)
  1164  	TEQ("", f(), 2)
  1165  	TEQ("", f(), 3)
  1166  	TEQ("", f(), 5)
  1167  }
  1168  
  1169  func testVariadic(values ...int) {
  1170  	total := 0
  1171  	for i := range values {
  1172  		total += values[i]
  1173  	}
  1174  	TEQ("", total, 42)
  1175  }
  1176  
  1177  func testMath() {
  1178  	// comment out for quicker testing
  1179  	/*
  1180  		if int(math.Sqrt(16.0)) != 4 {
  1181  			fmt.Println("" + ": Incorrect square root of 16")
  1182  		}
  1183  	*/
  1184  
  1185  	// test defer close
  1186  	x := make(chan interface{})
  1187  	defer close(x) // to make sure it is not removed by Dead Code Elimination
  1188  }
  1189  
  1190  func testInterface() {
  1191  	var i interface{}
  1192  
  1193  	i = "test"
  1194  	if i.(string) != "test" {
  1195  		fmt.Println("testInterface string not equal 'test':")
  1196  		fmt.Println(i)
  1197  	}
  1198  
  1199  	i = int(42)
  1200  	if i.(int) != 42 {
  1201  		fmt.Println("testInterface int not equal 42:")
  1202  		fmt.Println(i)
  1203  	}
  1204  
  1205  	j, ok := i.(rune)
  1206  	if ok {
  1207  		fmt.Println("error rune!=int")
  1208  	}
  1209  	TEQ("", j, rune(0))
  1210  }
  1211  
  1212  // from the go tour
  1213  type Vertex struct {
  1214  	X, Y float64
  1215  }
  1216  
  1217  func (v *Vertex) Abs() float64 {
  1218  	return Sqrt(v.X*v.X + v.Y*v.Y)
  1219  }
  1220  
  1221  func (v *Vertex) Scale(f float64) float64 {
  1222  	v.X = v.X * f
  1223  	v.Y = v.Y * f
  1224  	return v.Abs()
  1225  }
  1226  
  1227  func (v MyFloat) Scale(f float64) float64 {
  1228  	return float64(v) * f
  1229  }
  1230  
  1231  type Abser interface {
  1232  	Abs() float64
  1233  	Scale(x float64) float64
  1234  }
  1235  
  1236  //from the go.tools/go/types documentation
  1237  type T0 struct {
  1238  	X float64
  1239  }
  1240  
  1241  var p0 *T0
  1242  
  1243  type Value struct {
  1244  	typ *rtype
  1245  	flag
  1246  }
  1247  
  1248  type flag uintptr
  1249  
  1250  func (f flag) mv(x flag) flag { f = x; return f }
  1251  
  1252  type rtype struct {
  1253  	hash      uint32
  1254  	_         uint8  // test unused/padding
  1255  	ptrToThis *rtype // test self-ref
  1256  	flag
  1257  }
  1258  
  1259  var rt *rtype
  1260  
  1261  func (v Value) testFieldFn() {
  1262  	f0 := flag.mv(0, 42)
  1263  	f1 := flag.mv
  1264  	TEQ("", f1(f0, 42), f0)
  1265  	rt = new(rtype)
  1266  	v.typ = rt
  1267  	v.typ.hash = 42
  1268  	x := rt.hash
  1269  	TEQ("", v.typ.hash, x)
  1270  	y := &rt.hash
  1271  	z := (*y)
  1272  	TEQ("", z, x)
  1273  	var ff interface{} = &v.flag
  1274  	*(ff.(*flag)) = 42
  1275  	var ffh interface{} = v.typ
  1276  	ffh.(*rtype).flag = f1(0, 42)
  1277  	TEQ("", *(ff.(*flag)), ffh.(*rtype).flag)
  1278  }
  1279  
  1280  func testInterfaceMethods() {
  1281  	var v0 Value
  1282  	v0.testFieldFn()
  1283  
  1284  	v := &Vertex{3, 4}
  1285  	TEQfloat("", v.Abs(), 5, 0.00001)
  1286  	TEQfloat("", v.Scale(5), 25, 0.001)
  1287  	TEQfloat("", v.X, 15, 0.0000001)
  1288  	TEQfloat("", v.Y, 20, 0.0000001)
  1289  
  1290  	var a Abser
  1291  	f := MyFloat(-42)
  1292  	vt := Vertex{3, 4}
  1293  
  1294  	a = f // a MyFloat implements Abser
  1295  	x, ok := a.(Abser)
  1296  	//fmt.Println(reflect.TypeOf(x).String()) => main.MyFloat
  1297  	if !ok {
  1298  		fmt.Println("Error in testInterfaceMethods(): MyFloat should be in Abser interface")
  1299  	}
  1300  	TEQ(""+"testInterfaceMethods():MyFloat in Abser", a, f)
  1301  	TEQ(""+"testInterfaceMethods():MyFloat.Abs()", a.Abs(), float64(42))
  1302  	TEQ(""+"testInterfaceMethods():x.Abs()", x.Abs(), float64(42))
  1303  	TEQ(""+"testInterfaceMethods():MyFloat.Scale(10)", a.Scale(10), float64(-420))
  1304  	TEQ(""+"testInterfaceMethods():x.Scale(10)", x.Scale(10), float64(-420))
  1305  
  1306  	a = &vt // a *Vertex implements Abser
  1307  	y, ok := a.(Abser)
  1308  	//fmt.Println(reflect.TypeOf(y).String()) //=> *main.Vertex
  1309  	//fmt.Println(y)
  1310  	if !ok {
  1311  		fmt.Println("Error in testInterfaceMethods(): Vertex should be in Abser interface")
  1312  	}
  1313  	TEQ(""+"testInterfaceMethods():*Vertex in Abser", a, &vt)
  1314  	TEQfloat(""+"testInterfaceMethods():*Vertex.Abs()", a.Abs(), float64(5), 0.000001)
  1315  	TEQfloat(""+"testInterfaceMethods():y.Abs()", y.Abs(), float64(5), 0.000001)
  1316  	TEQfloat(""+"testInterfaceMethods():*Vertex.Scale(10)", a.Scale(10), float64(50), 0.000001)
  1317  	//fmt.Println(y)
  1318  	TEQfloat(""+"testInterfaceMethods():y.Scale(10)", y.Scale(10),
  1319  		float64(653.351098686295472), 0.01) // crazey number because Sqrt fn is an approximisation
  1320  	//fmt.Println(y)
  1321  
  1322  	// a=vt // a Vertex, does NOT
  1323  
  1324  	//from the go.tools/go/types documentation
  1325  	p0 = new(T0) // TODO should fail with this line missing, but does not (globals pre-initialised when they should not be)
  1326  	p0.X = 42
  1327  	TEQfloat("", p0.X, 42.0, 0.01)
  1328  
  1329  }
  1330  
  1331  func testStrconv() {
  1332  	/*
  1333  		TEQ(""+"testStrconv():Itoa", "424242", strconv.Itoa(424242))
  1334  
  1335  		TEQ("", strings.HasPrefix("say what", "say"), true)
  1336  		TEQ(""+" string.Contains (error on js)", strings.Contains("say what", "ay"), true)
  1337  		TEQ(""+" string.Contains (error on js)", strings.Contains("seafood", "foo"), true)
  1338  		TEQ("", strings.Contains("seafood", "bar"), false)
  1339  		TEQ("", strings.Contains("seafood", ""), true)
  1340  		TEQ("", strings.Contains("", ""), true)
  1341  		TEQ("", strings.Contains("equal?", "equal?"), true)
  1342  
  1343  		TEQ("", bytes.HasPrefix([]byte("say what"), []byte("say")), true)
  1344  		TEQ("", bytes.Contains([]byte("say what"), []byte("ay")), true)
  1345  	*/
  1346  }
  1347  
  1348  func sum(a []int, c chan int) {
  1349  	sum := 0
  1350  	for _, v := range a {
  1351  		sum += v
  1352  	}
  1353  	c <- sum // send sum to c
  1354  }
  1355  
  1356  func testTour64() {
  1357  	a := []int{7, 2, 8, -9, 4, 0}
  1358  
  1359  	c := make(chan int)
  1360  	go sum(a[:len(a)/2], c)
  1361  	go sum(a[len(a)/2:], c)
  1362  	x, y := <-c, <-c // receive from c
  1363  
  1364  	TEQ("", x+y, 12) // x & y could arrive in any order...
  1365  }
  1366  
  1367  func testDefer_a() {
  1368  	i := 0
  1369  	defer TEQ("", i, 0)
  1370  	i++
  1371  	return
  1372  }
  1373  func testDefer_b(ch chan int) {
  1374  	for i := 0; i < 4; i++ {
  1375  		defer func(j int) { ch <- j }(i)
  1376  	}
  1377  }
  1378  func testDefer_c() (i int) {
  1379  	defer func() { i++ }()
  1380  	return 1
  1381  }
  1382  func protect(g func(int)) {
  1383  	defer func() {
  1384  		TEQ("", recover(), "test panic")
  1385  	}()
  1386  	g(0)
  1387  }
  1388  
  1389  func g(i int) {
  1390  	if i > 3 {
  1391  		err := errors.New("test panic")
  1392  		panic(err.Error())
  1393  	}
  1394  	for j := 0; j < i; j++ {
  1395  		defer testDefer_d()
  1396  	}
  1397  	g(i + 1)
  1398  }
  1399  
  1400  var tddCount = 0
  1401  
  1402  func testDefer_d() {
  1403  	tddCount++ // just to give the routine something to do
  1404  }
  1405  
  1406  func testDefer() {
  1407  	// examples from http://blog.golang.org/defer-panic-and-recover
  1408  	testDefer_a()
  1409  	b := make(chan int, 4)
  1410  	testDefer_b(b)
  1411  	TEQ("", <-b, 3)
  1412  	TEQ("", <-b, 2)
  1413  	TEQ("", <-b, 1)
  1414  	TEQ("", <-b, 0)
  1415  	TEQ("", testDefer_c(), 2)
  1416  	protect(g)
  1417  	TEQ("", tddCount, 6)
  1418  }
  1419  
  1420  // these two names were failing in java as being duplicates, now failing in PHP...
  1421  func Ilogb(x float64) int {
  1422  	return int(Sqrt(x))
  1423  }
  1424  func ilogb(x float64) int {
  1425  	return int(Sqrt(x))
  1426  }
  1427  func testCaseSensitivity() {
  1428  	//moved to a separate test file
  1429  	//TEQ("", ilogb(64), Ilogb(64))
  1430  }
  1431  
  1432  var (
  1433  	aGrCtr int32
  1434  	//aGrCtrMux sync.Mutex
  1435  	//aGrWG     sync.WaitGroup
  1436  )
  1437  
  1438  func aGoroutine(a int) {
  1439  	if a == 4 {
  1440  		//panic("test panic in goroutine 4")
  1441  	}
  1442  	for i := 0; i < a; i++ {
  1443  		runtime.Gosched()
  1444  	}
  1445  	//(&aGrCtrMux).Lock()
  1446  	//atomic.AddInt32(&aGrCtr, -1)
  1447  	aGrCtr--
  1448  	//(&aGrCtrMux).Unlock()
  1449  
  1450  	//aGrWG.Done()
  1451  }
  1452  
  1453  const numGR = 5
  1454  
  1455  func testManyGoroutines() {
  1456  	var n = numGR
  1457  	aGrCtr = numGR * 2 // set up the goroutine counter
  1458  	for i := 0; i < n; i++ {
  1459  		//aGrWG.Add(1)
  1460  		go aGoroutine(i)
  1461  	}
  1462  	for i := n; i > 0; i-- {
  1463  		//aGrWG.Add(1)
  1464  		go aGoroutine(i)
  1465  	}
  1466  }
  1467  
  1468  //
  1469  // Code from http://golangtutorials.blogspot.co.uk/2011/06/channels-in-go-range-and-select.html
  1470  //
  1471  func makeCakeAndSend(cs chan string, flavor string, count int) {
  1472  	for i := 1; i <= count; i++ {
  1473  		TEQ("Delay", i, i)
  1474  		cakeName := flavor + " Cake " + string('0'+i)
  1475  		cs <- cakeName //send a strawberry cake
  1476  	}
  1477  	close(cs)
  1478  }
  1479  
  1480  func receiveCakeAndPack(strbry_cs chan string, choco_cs chan string) {
  1481  	strbry_closed, choco_closed := false, false
  1482  
  1483  	for {
  1484  		//if both channels are closed then we can stop
  1485  		if strbry_closed && choco_closed {
  1486  			return
  1487  		}
  1488  		//fmt.Println("Waiting for a new cake ...")
  1489  		select {
  1490  		case cakeName, strbry_ok := <-strbry_cs:
  1491  			if !strbry_ok {
  1492  				strbry_closed = true
  1493  				//fmt.Println(" ... Strawberry channel closed!")
  1494  			} else {
  1495  				//fmt.Println("Received from Strawberry channel.  Now packing", cakeName)
  1496  				_ = cakeName
  1497  			}
  1498  		case cakeName, choco_ok := <-choco_cs:
  1499  			if !choco_ok {
  1500  				choco_closed = true
  1501  				//fmt.Println(" ... Chocolate channel closed!")
  1502  			} else {
  1503  				//fmt.Println("Received from Chocolate channel.  Now packing", cakeName)
  1504  				_ = cakeName
  1505  			}
  1506  		default:
  1507  			//fmt.Println("no cake!")
  1508  		}
  1509  	}
  1510  }
  1511  
  1512  func testChanSelect() {
  1513  	strbry_cs := make(chan string)
  1514  	choco_cs := make(chan string)
  1515  
  1516  	//two cake makers
  1517  	go makeCakeAndSend(choco_cs, "Chocolate", 3)   //make 3 chocolate cakes and send
  1518  	go makeCakeAndSend(strbry_cs, "Strawberry", 3) //make 3 strawberry cakes and send
  1519  
  1520  	//one cake receiver and packer
  1521  	receiveCakeAndPack(strbry_cs, choco_cs) //pack all cakes received on these cake channels
  1522  
  1523  	//sleep for a while so that the program doesn’t exit immediately
  1524  	//time.Sleep(2 * 1e9)
  1525  }
  1526  
  1527  //end code from http://golangtutorials.blogspot.co.uk/2011/06/channels-in-go-range-and-select.html
  1528  
  1529  //From the go tour http://tour.golang.org/#69
  1530  func fibonacci(c, quit chan int) {
  1531  	x, y := 0, 1
  1532  	for {
  1533  		select {
  1534  		case c <- x:
  1535  			x, y = y, x+y
  1536  		case <-quit:
  1537  			//fmt.Println("quit")
  1538  			return
  1539  		}
  1540  	}
  1541  }
  1542  
  1543  func tourfib() {
  1544  	c := make(chan int)
  1545  	quit := make(chan int)
  1546  	go func() {
  1547  		for i := 0; i < 10; i++ {
  1548  			/*fmt.Println(*/ <-c /*)*/
  1549  		}
  1550  		quit <- 0
  1551  	}()
  1552  	fibonacci(c, quit)
  1553  }
  1554  
  1555  // end tour
  1556  
  1557  func testUintDiv32() {
  1558  	for seed := int32(-2); seed <= 2; seed++ {
  1559  		var uifs, pwr2 uint32
  1560  		uifs = uint32(seed)
  1561  		if seed != 0 {
  1562  			one := uint32(1)
  1563  			TEQuint32("testUintDiv32() uint x/x==unity ", 1, uifs/uifs)
  1564  			TEQint32("testUintDiv32() int x/x==unity ", 1, seed/seed)
  1565  			TEQuint32("testUintDiv32() uint x/1==x ", uifs/one, uifs)
  1566  			TEQint32("testUintDiv32() int x/1==x ", seed/int32(one), seed)
  1567  			if seed > 0 {
  1568  				TEQuint32("testUintDiv32() uint +ve roundtrip ", uifs, (uifs*uifs)/uifs)
  1569  			}
  1570  			TEQint32("testUintDiv32() int +ve roundtrip ", seed, (seed*seed)/seed)
  1571  		}
  1572  		pwr2 = uint32(1)
  1573  		for i := uint32(0); i < 32; i++ {
  1574  			if !TEQuint32("testUintDiv32() T1 uint ", (uifs)>>i, (uifs)/pwr2) {
  1575  				fmt.Println("ProblemT1 uint i=", int(i))
  1576  			}
  1577  			if !TEQuint32("testUintDiv32() uint shift equivalence roundtrip  ", (uifs*pwr2)>>i, (uifs<<i)/pwr2) {
  1578  				fmt.Println("Problem uint seed,i=", seed, i)
  1579  			}
  1580  			if i < 31 {
  1581  				if seed >= 0 {
  1582  					if !TEQint32("testUintDiv32() T1 int ", (seed)>>i, (seed)/int32(pwr2)) {
  1583  						fmt.Println("ProblemT1 int i=", int(i))
  1584  					}
  1585  				}
  1586  				if !TEQint32("testUintDiv32() int shift equivalence roundtrip  ",
  1587  					(seed*int32(pwr2))>>i, (seed<<i)/int32(pwr2)) {
  1588  					fmt.Println("Problem int seed,i=", seed, i)
  1589  				}
  1590  			}
  1591  			pwr2 <<= 1
  1592  		}
  1593  	}
  1594  }
  1595  func testUintDiv64() {
  1596  	for seed := int64(-2); seed <= 2; seed++ {
  1597  		var uifs, pwr2 uint64
  1598  		uifs = uint64(seed)
  1599  		if seed != 0 {
  1600  			one := uint64(1)
  1601  			TEQuint64("testUintDiv64() uint x/x==unity ", 1, uifs/uifs)
  1602  			TEQint64("testUintDiv64() int x/x==unity ", 1, seed/seed)
  1603  			TEQuint64("testUintDiv64() uint x/1==x ", uifs/one, uifs)
  1604  			TEQint64("testUintDiv64() int x/1==x ", seed/int64(one), seed)
  1605  			if seed > 0 {
  1606  				TEQuint64("testUintDiv64() +ve roundtrip ", uifs, (uifs*uifs)/uifs)
  1607  			}
  1608  			TEQint64("testUintDiv64() int +ve roundtrip ", seed, (seed*seed)/seed)
  1609  		}
  1610  		pwr2 = uint64(1)
  1611  		for i := uint64(0); i < 64; i++ {
  1612  			if !TEQuint64("testUintDiv64() uint ", uifs>>i, uifs/pwr2) {
  1613  				fmt.Println("Problem seed,i=", seed, i)
  1614  			}
  1615  			if !TEQuint64("testUintDiv64() uint shift equivalence roundtrip  ", (uifs*pwr2)>>i, (uifs<<i)/pwr2) {
  1616  				fmt.Println("Problem seed,i=", seed, i)
  1617  			}
  1618  			if i < 63 {
  1619  				if seed >= 0 {
  1620  					if !TEQint64("testUintDiv64() T1 int ", (seed)>>i, (seed)/int64(pwr2)) {
  1621  						fmt.Println("ProblemT1 int i=", int(i))
  1622  					}
  1623  				}
  1624  				if !TEQint64("testUintDiv64() int shift equivalence roundtrip  ",
  1625  					(seed*int64(pwr2))>>i, (seed<<i)/int64(pwr2)) {
  1626  					fmt.Println("Problem int seed,i=", seed, i)
  1627  				}
  1628  			}
  1629  			pwr2 <<= 1
  1630  		}
  1631  	}
  1632  }
  1633  
  1634  type foo struct {
  1635  	a int
  1636  }
  1637  
  1638  func bar() *foo {
  1639  	//fmt.Println("bar() called")
  1640  	return &foo{42}
  1641  }
  1642  
  1643  type foo2 struct {
  1644  	a struct {
  1645  		b int
  1646  	}
  1647  }
  1648  
  1649  func testPtr() {
  1650  	q := &bar().a
  1651  	//fmt.Println("pointer created")
  1652  	*q = 40
  1653  	TEQ("", *q, 40) // should be 40
  1654  
  1655  	// type foo as above
  1656  	f := foo{6}
  1657  	r := &f // this isn't creating a pointer
  1658  	f = foo{4}
  1659  	TEQ("", r.a, 4) // should be 4
  1660  
  1661  	f2 := foo2{}
  1662  	p2 := &f2.a
  1663  	q2 := &p2.b // referring to the `p` variable instead of its pointer value at the time; &(*p).b (should be equivalent) is handled correctly though
  1664  	p2 = nil
  1665  	TEQ("", *q2, 0) // should be 0
  1666  
  1667  	var f3 struct{ a [3]int }
  1668  	f3.a = [3]int{6, 6, 6}
  1669  	s3 := f3.a[:]
  1670  	f3.a = [3]int{4, 4, 4}
  1671  	TEQ("", s3[1], 4) // should be 4
  1672  
  1673  }
  1674  
  1675  type tbe struct {
  1676  	a int
  1677  	b string
  1678  }
  1679  
  1680  func (x tbe) zip() string {
  1681  	ret := ""
  1682  	for z := 0; z < x.a; z++ {
  1683  		ret += x.b
  1684  	}
  1685  	return ret
  1686  }
  1687  
  1688  type testtbe struct {
  1689  	tbe // embedded struct
  1690  	c   bool
  1691  }
  1692  
  1693  func testEmbed() {
  1694  	var t testtbe
  1695  	t.a = 3
  1696  	t.b = "Grunt"
  1697  	TEQ("", "GruntGruntGrunt", t.zip())
  1698  }
  1699  
  1700  func testUnsafe() { // adapted from http://stackoverflow.com/questions/19721008/golang-unsafe-dynamic-byte-array
  1701  
  1702  	// Arbitrary size
  1703  	n := 4
  1704  
  1705  	// Create a slice of the correct size
  1706  	m := make([]int32, n)
  1707  
  1708  	// Use convoluted indirection to cast the first few bytes of the slice
  1709  	// to an unsafe pointer
  1710  	mPtr := unsafe.Pointer(&m[0])
  1711  
  1712  	// Check it worked
  1713  	m[0] = 987
  1714  	// (we have to recast the uintptr to a *int to examine it)
  1715  	TEQint32("", m[0], *(*int32)(mPtr))
  1716  
  1717  	if runtime.GOARCH != "neko" { // to avoid errors on the automated test
  1718  		TEQuint32("Only works in fullunsafe mode", 219, (uint32)(*(*uint8)(mPtr)))
  1719  	}
  1720  
  1721  	// error on pointer arithmetic
  1722  	//uip := uintptr(mPtr)
  1723  	//uip++
  1724  }
  1725  
  1726  func tc64(f float64) float64 {
  1727  	if runtime.GOOS == "nacl" {
  1728  		return hx.CallFloat("", "Go_haxegoruntime_FFloat64frombits.hx", 1,
  1729  			hx.CallDynamic("", "Go_haxegoruntime_FFloat64bits.hx", 1, f))
  1730  	}
  1731  	return f
  1732  }
  1733  
  1734  const (
  1735  	SmallestNormalFloat64   = 2.2250738585072014e-308 // 2**-1022
  1736  	LargestSubnormalFloat64 = SmallestNormalFloat64 - SmallestNonzeroFloat64
  1737  
  1738  	MaxFloat32             = 3.40282346638528859811704183484516925440e+38  // 2**127 * (2**24 - 1) / 2**23
  1739  	SmallestNonzeroFloat32 = 1.401298464324817070923729583289916131280e-45 // 1 / 2**(127 - 1 + 23)
  1740  
  1741  	MaxFloat64             = 1.797693134862315708145274237317043567981e+308 // 2**1023 * (2**53 - 1) / 2**52
  1742  	SmallestNonzeroFloat64 = 4.940656458412465441765687928682213723651e-324 // 1 / 2**(1023 - 1 + 52)
  1743  )
  1744  
  1745  func testFloatConv() {
  1746  	if runtime.GOARCH != "neko" {
  1747  		TEQ("SmallestNormalFloat64", SmallestNormalFloat64, tc64(SmallestNormalFloat64))
  1748  		TEQ("LargestSubnormalFloat64", LargestSubnormalFloat64, tc64(LargestSubnormalFloat64))
  1749  		TEQ("MaxFloat32", MaxFloat32, tc64(MaxFloat32))
  1750  		TEQ("SmallestNonzeroFloat32", SmallestNonzeroFloat32, tc64(SmallestNonzeroFloat32))
  1751  		TEQ("MaxFloat64", MaxFloat64, tc64(MaxFloat64))
  1752  		TEQ("SmallestNonzeroFloat64", SmallestNonzeroFloat64, tc64(SmallestNonzeroFloat64))
  1753  		TEQ("42.42", 42.42, tc64(42.42))
  1754  		if runtime.GOOS == "nacl" {
  1755  			pi := tc64(hx.GetFloat("", "Math.POSITIVE_INFINITY"))
  1756  			if pi <= MaxFloat64 {
  1757  				fmt.Println("testFloatConv() POSITIVE_INFINITY invalid")
  1758  			}
  1759  			ni := tc64(hx.GetFloat("", "Math.NEGATIVE_INFINITY"))
  1760  			if ni >= SmallestNonzeroFloat64 {
  1761  				fmt.Println("testFloatConv() NEGATIVE_INFINITY invalid")
  1762  			}
  1763  			if hx.GetFloat("", "Math.NaN") == tc64(hx.GetFloat("", "Math.NaN")) {
  1764  				fmt.Println("testFloatConv() NaN == NaN")
  1765  			}
  1766  		}
  1767  	}
  1768  }
  1769  
  1770  type ObjKey [2]int
  1771  
  1772  func testObjMap() {
  1773  	m := map[ObjKey]int32{
  1774  		ObjKey{1, 2}: 3,
  1775  	}
  1776  	TEQint32("", 3, m[ObjKey{1, 2}])
  1777  
  1778  	cm := map[complex128]int32{
  1779  		1 + 2i: 3,
  1780  	}
  1781  
  1782  	TEQint32("", 3, cm[1+2i])
  1783  
  1784  }
  1785  
  1786  type unaligned7 struct {
  1787  	h [17]testtbe
  1788  	i int32
  1789  	j uint16
  1790  	k uint8
  1791  }
  1792  
  1793  func testUnaligned() {
  1794  	var x [3]unaligned7
  1795  	//y := interface{}(x)
  1796  	//z := reflect.ValueOf(y)
  1797  	for d := 0; d < len(x); d++ {
  1798  		x[d].k = uint8(d)
  1799  		TEQuint32("x[d]k!=d", uint32(x[d].k), uint32(d))
  1800  		//TEQuint32("reflect(x[d]k)!=d", uint32(z.Index(d).FieldByName("k").Int()), uint32(d))
  1801  		for hh := 0; hh < 17; hh++ {
  1802  			x[d].h[hh].a = hh
  1803  			TEQuint32("x[d].h[hh].a!=hh", uint32(x[d].h[hh].a), uint32(hh))
  1804  			//TEQuint32("reflect(x[d].h[hh].a)!=hh", uint32(z.Index(d).FieldByName("h").Index(hh).Int()), uint32(hh))
  1805  		}
  1806  	}
  1807  	x1 := make([]unaligned7, 7)
  1808  	//y1 := interface{}(x1)
  1809  	//z1 := reflect.ValueOf(y1)
  1810  	for d := 0; d < len(x1); d++ {
  1811  		x1[d].k = uint8(d)
  1812  		TEQuint32("x1[d]k!=d", uint32(x1[d].k), uint32(d))
  1813  		//TEQuint32("reflect(x1[d]k)!=d", uint32(z1.Index(d).FieldByName("k").Int()), uint32(d))
  1814  		for hh := 0; hh < 17; hh++ {
  1815  			x1[d].h[hh].a = hh
  1816  			TEQuint32("x1[d].h[hh].a!=hh", uint32(x1[d].h[hh].a), uint32(hh))
  1817  			//TEQuint32("reflect(x1[d].h[hh].a)!=hh", uint32(z1.Index(d).FieldByName("h").Index(hh).Int()), uint32(hh))
  1818  		}
  1819  	}
  1820  }
  1821  
  1822  func main() {
  1823  	var array [4][5]int
  1824  	array[3][2] = 12
  1825  	if array[3][2] != 12 {
  1826  		fmt.Println("Array handling error:", array[3][2])
  1827  	}
  1828  	//fmt.Println("Start test running in: " + runtime.GOARCH)
  1829  	testManyGoroutines() // here to run alongside the other code execution
  1830  	tourfib()
  1831  	testCaseSensitivity()
  1832  	testInit()
  1833  	testConst()
  1834  	testUTF()
  1835  	testFloat()
  1836  	testMultiRet()
  1837  	testAppend()
  1838  	testStruct()
  1839  	testHeader()
  1840  	testCopy()
  1841  	testInFuncPtr()
  1842  	testCallBy()
  1843  	testMap()
  1844  	testNamed()
  1845  	testFuncPtr()
  1846  	testIntOverflow()
  1847  	testSlices()
  1848  	testChan()
  1849  	testComplex()
  1850  	testUTF8()
  1851  	testString()
  1852  	testClosure()
  1853  	testVariadic(42)
  1854  	testVariadic(40, 2)
  1855  	testVariadic(42, -5, 3, 2)
  1856  	testInterface()
  1857  	testInterfaceMethods()
  1858  	testStrconv()
  1859  	testTour64()
  1860  	testUintDiv32()
  1861  	testUintDiv64()
  1862  	testDefer()
  1863  	testPtr()
  1864  	testChanSelect()
  1865  	testEmbed()
  1866  	testUnsafe()
  1867  	testObjMap()
  1868  	testFloatConv()
  1869  	testUnaligned()
  1870  	//aGrWG.Wait()
  1871  	TEQint32(""+" testManyGoroutines() (NOT sync/atomic) counter:", aGrCtr, 0)
  1872  	if runtime.GOOS == "nacl" { // really a haxe emulation of nacl
  1873  		TEQ("", hx.CodeInt("", "42;"), int(42))
  1874  		TEQ("", hx.CodeString("", "'test';"), "test")
  1875  		TEQ(""+"Num Haxe GR post-wait", runtime.NumGoroutine(), 1)
  1876  		//panic("show GRs active")
  1877  	} else {
  1878  		//fmt.Println(runtime.NumGoroutine())
  1879  		TEQ(""+"Num Haxe GR post-wait", runtime.NumGoroutine(), 3)
  1880  	}
  1881  	TEQ("", unicode.IsSpace(' '), true) // makes the test longer but more complete
  1882  	//fmt.Println("End test running in: " + runtime.GOARCH)
  1883  	//fmt.Println("Σ sigma, " + "再见!Previous two chinese characters should say goodbye! (testing unicode output)")
  1884  	//fmt.Println()
  1885  	//hx.Call("", "Tgotypes.setup", 0)
  1886  	//hx.Call("", "Go_haxegoruntime_typetest.hx", 0)
  1887  	//testTypes()
  1888  	//fmt.Println(hx.GetFloat("", "Object.MinFloat64"))
  1889  }
  1890  
  1891  /*
  1892  func testTypes() {
  1893  	for id := 0; id < len(haxegoruntime.TypeTable); id++ {
  1894  		r := unsafe.Pointer(haxegoruntime.TypeTable[id])
  1895  		fmt.Println("DEBUG type", id, r)
  1896  	}
  1897  }
  1898  */