| | |
| | |
| | |
| |
|
| | package main |
| |
|
| | import ( |
| | "fmt" |
| | "strings" |
| | ) |
| |
|
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | var labels string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| |
|
| | func blocks(spec string) (blocks []string, fnameBase string) { |
| | spec = strings.ToUpper(spec) |
| | blocks = strings.Split(spec, ",") |
| | fnameBase = strings.ReplaceAll(spec, ",", "_") |
| | return |
| | } |
| |
|
| | func makeFunctionFromFlowGraph(blocks []blo, fname string) string { |
| | s := "" |
| |
|
| | for j := range blocks { |
| | |
| | if j == 0 { |
| | |
| | s += ` |
| | func ` + fname + `(x int64) int64 { |
| | y := int64(0) |
| | var b int64 |
| | _ = b` |
| | } else { |
| | |
| | l := labels[j : j+1] |
| | yeq := ` |
| | // no y increment` |
| | if blocks[j].inc != 0 { |
| | yeq = ` |
| | y += ` + fmt.Sprintf("%d", blocks[j].inc) |
| | } |
| |
|
| | s += ` |
| | ` + l + `: |
| | glob = !glob` + yeq |
| | } |
| |
|
| | |
| | if blocks[j].cond { |
| | s += ` |
| | b = x & 1 |
| | x = x >> 1 |
| | if b != 0 {` + ` |
| | goto ` + string(labels[blocks[j].succs[1]]) + ` |
| | }` |
| |
|
| | } |
| | |
| | s += ` |
| | goto ` + string(labels[blocks[j].succs[0]]) |
| | } |
| |
|
| | |
| | s += ` |
| | Z: |
| | return y |
| | } |
| | ` |
| | return s |
| | } |
| |
|
| | var graphs []string = []string{ |
| | "Z", "BZ,Z", "B,BZ", "BZ,BZ", |
| | "ZB,Z", "B,ZB", "ZB,BZ", "ZB,ZB", |
| |
|
| | "BC,C,Z", "BC,BC,Z", "BC,BC,BZ", |
| | "BC,Z,Z", "BC,ZC,Z", "BC,ZC,BZ", |
| | "BZ,C,Z", "BZ,BC,Z", "BZ,CZ,Z", |
| | "BZ,C,BZ", "BZ,BC,BZ", "BZ,CZ,BZ", |
| | "BZ,C,CZ", "BZ,BC,CZ", "BZ,CZ,CZ", |
| |
|
| | "BC,CD,BE,BZ,CZ", |
| | "BC,BD,CE,CZ,BZ", |
| | "BC,BD,CE,FZ,GZ,F,G", |
| | "BC,BD,CE,FZ,GZ,G,F", |
| |
|
| | "BC,DE,BE,FZ,FZ,Z", |
| | "BC,DE,BE,FZ,ZF,Z", |
| | "BC,DE,BE,ZF,FZ,Z", |
| | "BC,DE,EB,FZ,FZ,Z", |
| | "BC,ED,BE,FZ,FZ,Z", |
| | "CB,DE,BE,FZ,FZ,Z", |
| |
|
| | "CB,ED,BE,FZ,FZ,Z", |
| | "BC,ED,EB,FZ,ZF,Z", |
| | "CB,DE,EB,ZF,FZ,Z", |
| | "CB,ED,EB,FZ,FZ,Z", |
| |
|
| | "BZ,CD,CD,CE,BZ", |
| | "EC,DF,FG,ZC,GB,BE,FD", |
| | "BH,CF,DG,HE,BF,CG,DH,BZ", |
| | } |
| |
|
| | |
| | type blo struct { |
| | inc int64 |
| | cond bool |
| | succs [2]int64 |
| | } |
| |
|
| | |
| | |
| | |
| | func strings2blocks(blocks []string, fname string, i int) (bs []blo, cond uint) { |
| | bs = make([]blo, len(blocks)) |
| | edge := int64(1) |
| | cond = 0 |
| | k := uint(0) |
| | for j, s := range blocks { |
| | if j == 0 { |
| | } else { |
| | if (i>>k)&1 != 0 { |
| | bs[j].inc = edge |
| | edge *= 10 |
| | } |
| | k++ |
| | } |
| | if len(s) > 1 { |
| | bs[j].succs[1] = int64(blocks[j][1] - 'A') |
| | bs[j].cond = true |
| | cond++ |
| | } |
| | bs[j].succs[0] = int64(blocks[j][0] - 'A') |
| | } |
| | return bs, cond |
| | } |
| |
|
| | |
| | func fmtBlocks(bs []blo) string { |
| | s := "[]blo{" |
| | for _, b := range bs { |
| | s += fmt.Sprintf("blo{inc:%d, cond:%v, succs:[2]int64{%d, %d}},", b.inc, b.cond, b.succs[0], b.succs[1]) |
| | } |
| | s += "}" |
| | return s |
| | } |
| |
|
| | func main() { |
| | fmt.Printf(`// This is a machine-generated test file from flowgraph_generator1.go. |
| | package main |
| | import "fmt" |
| | var glob bool |
| | `) |
| | s := "var funs []fun = []fun{" |
| | for _, g := range graphs { |
| | split, fnameBase := blocks(g) |
| | nconfigs := 1 << uint(len(split)-1) |
| |
|
| | for i := 0; i < nconfigs; i++ { |
| | fname := fnameBase + fmt.Sprintf("%b", i) |
| | bs, k := strings2blocks(split, fname, i) |
| | fmt.Printf("%s", makeFunctionFromFlowGraph(bs, fname)) |
| | s += ` |
| | {f:` + fname + `, maxin:` + fmt.Sprintf("%d", 1<<k) + `, blocks:` + fmtBlocks(bs) + `},` |
| | } |
| |
|
| | } |
| | s += `} |
| | ` |
| | |
| | fmt.Printf("%s", |
| | ` |
| | type blo struct { |
| | inc int64 |
| | cond bool |
| | succs [2]int64 |
| | } |
| | type fun struct { |
| | f func(int64) int64 |
| | maxin int64 |
| | blocks []blo |
| | } |
| | `) |
| | |
| | fmt.Printf("%s", s) |
| |
|
| | |
| | fmt.Printf("%s", ` |
| | func interpret(blocks []blo, x int64) (int64, bool) { |
| | y := int64(0) |
| | last := int64(25) // 'Z'-'A' |
| | j := int64(0) |
| | for i := 0; i < 4*len(blocks); i++ { |
| | b := blocks[j] |
| | y += b.inc |
| | next := b.succs[0] |
| | if b.cond { |
| | c := x&1 != 0 |
| | x = x>>1 |
| | if c { |
| | next = b.succs[1] |
| | } |
| | } |
| | if next == last { |
| | return y, true |
| | } |
| | j = next |
| | } |
| | return -1, false |
| | } |
| | |
| | func main() { |
| | sum := int64(0) |
| | for i, f := range funs { |
| | for x := int64(0); x < 16*f.maxin; x++ { |
| | y, ok := interpret(f.blocks, x) |
| | if ok { |
| | yy := f.f(x) |
| | if y != yy { |
| | fmt.Printf("y(%d) != yy(%d), x=%b, i=%d, blocks=%v\n", y, yy, x, i, f.blocks) |
| | return |
| | } |
| | sum += y |
| | } |
| | } |
| | } |
| | // fmt.Printf("Sum of all returns over all terminating inputs is %d\n", sum) |
| | } |
| | `) |
| | } |
| |
|