# Source file test/peano.go

```     1  // run
2
4  // Use of this source code is governed by a BSD-style
6
7  // Test that heavy recursion works. Simple torture test for
8  // segmented stacks: do math in unary by recursion.
9
10  package main
11
12  import "runtime"
13
14  type Number *Number
15
16  // -------------------------------------
17  // Peano primitives
18
19  func zero() *Number {
20  	return nil
21  }
22
23  func is_zero(x *Number) bool {
24  	return x == nil
25  }
26
27  func add1(x *Number) *Number {
28  	e := new(Number)
29  	*e = x
30  	return e
31  }
32
33  func sub1(x *Number) *Number {
34  	return *x
35  }
36
37  func add(x, y *Number) *Number {
38  	if is_zero(y) {
39  		return x
40  	}
41
43  }
44
45  func mul(x, y *Number) *Number {
46  	if is_zero(x) || is_zero(y) {
47  		return zero()
48  	}
49
51  }
52
53  func fact(n *Number) *Number {
54  	if is_zero(n) {
56  	}
57
58  	return mul(fact(sub1(n)), n)
59  }
60
61  // -------------------------------------
62  // Helpers to generate/count Peano integers
63
64  func gen(n int) *Number {
65  	if n > 0 {
67  	}
68
69  	return zero()
70  }
71
72  func count(x *Number) int {
73  	if is_zero(x) {
74  		return 0
75  	}
76
77  	return count(sub1(x)) + 1
78  }
79
80  func check(x *Number, expected int) {
81  	var c = count(x)
82  	if c != expected {
83  		print("error: found ", c, "; expected ", expected, "\n")
84  		panic("fail")
85  	}
86  }
87
88  // -------------------------------------
89  // Test basic functionality
90
91  func init() {
92  	check(zero(), 0)
94  	check(gen(10), 10)
95
99
100  	check(mul(zero(), zero()), 0)
101  	check(mul(gen(3), zero()), 0)
102  	check(mul(zero(), gen(4)), 0)
105  	check(mul(gen(3), gen(4)), 12)
106
107  	check(fact(zero()), 1)
109  	check(fact(gen(5)), 120)
110  }
111
112  // -------------------------------------
113  // Factorial
114
115  var results = [...]int{
116  	1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800,
117  	39916800, 479001600,
118  }
119
120  func main() {
121  	max := 9
122  	if runtime.GOARCH == "wasm" {
123  		max = 7 // stack size is limited
124  	}
125  	for i := 0; i <= max; i++ {
126  		if f := count(fact(gen(i))); f != results[i] {
127  			println("FAIL:", i, "!:", f, "!=", results[i])
128  			panic(0)
129  		}
130  	}
131  }
132
```

View as plain text