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 */