mirror of
https://github.com/golang/go
synced 2024-11-23 13:10:15 -07:00
81 lines
1.3 KiB
Go
81 lines
1.3 KiB
Go
|
// errorcheckoutput
|
||
|
|
||
|
package main
|
||
|
|
||
|
import "fmt"
|
||
|
|
||
|
// We are going to define 256 types T(n),
|
||
|
// such that T(n) embeds T(2n) and *T(2n+1).
|
||
|
|
||
|
func main() {
|
||
|
fmt.Printf("// errorcheck\n\n")
|
||
|
fmt.Printf("package p\n\n")
|
||
|
fmt.Println(`import "unsafe"`)
|
||
|
|
||
|
// Dump types.
|
||
|
for n := 1; n < 256; n++ {
|
||
|
writeStruct(n)
|
||
|
}
|
||
|
// Dump leaves
|
||
|
for n := 256; n < 512; n++ {
|
||
|
fmt.Printf("type T%d int\n", n)
|
||
|
}
|
||
|
|
||
|
fmt.Printf("var t T1\n")
|
||
|
fmt.Printf("var p *T1\n")
|
||
|
|
||
|
// Simple selectors
|
||
|
for n := 2; n < 256; n++ {
|
||
|
writeDot(n)
|
||
|
}
|
||
|
|
||
|
// Double selectors
|
||
|
for n := 128; n < 256; n++ {
|
||
|
writeDot(n/16, n)
|
||
|
}
|
||
|
|
||
|
// Triple selectors
|
||
|
for n := 128; n < 256; n++ {
|
||
|
writeDot(n/64, n/8, n)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const structTpl = `
|
||
|
type T%d struct {
|
||
|
A%d int
|
||
|
T%d
|
||
|
*T%d
|
||
|
}
|
||
|
`
|
||
|
|
||
|
func writeStruct(n int) {
|
||
|
fmt.Printf(structTpl, n, n, 2*n, 2*n+1)
|
||
|
}
|
||
|
|
||
|
func writeDot(ns ...int) {
|
||
|
for _, root := range []string{"t", "p"} {
|
||
|
fmt.Printf("const _ = unsafe.Offsetof(%s", root)
|
||
|
for _, n := range ns {
|
||
|
fmt.Printf(".T%d", n)
|
||
|
}
|
||
|
// Does it involve an indirection?
|
||
|
nlast := ns[len(ns)-1]
|
||
|
nprev := 1
|
||
|
if len(ns) > 1 {
|
||
|
nprev = ns[len(ns)-2]
|
||
|
}
|
||
|
isIndirect := false
|
||
|
for n := nlast / 2; n > nprev; n /= 2 {
|
||
|
if n%2 == 1 {
|
||
|
isIndirect = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
fmt.Print(")")
|
||
|
if isIndirect {
|
||
|
fmt.Print(` // ERROR "indirection"`)
|
||
|
}
|
||
|
fmt.Print("\n")
|
||
|
}
|
||
|
}
|