1e6d6c189SCody Peter Mello#!/bin/bash
2e6d6c189SCody Peter Mello
3e6d6c189SCody Peter Melloif [[ -z "$AWK" || -z "$WORKDIR" ]]; then
4e6d6c189SCody Peter Mello    printf '$AWK and $WORKDIR must be set\n' >&2
5e6d6c189SCody Peter Mello    exit 1
6e6d6c189SCody Peter Mellofi
7e6d6c189SCody Peter Mello
8e6d6c189SCody Peter MelloTEMP1=$WORKDIR/test.temp.1
9e6d6c189SCody Peter MelloTEMP2=$WORKDIR/test.temp.2
10e6d6c189SCody Peter Mello
11e6d6c189SCody Peter MelloRESULT=0
12e6d6c189SCody Peter Mello
13e6d6c189SCody Peter Mellofail() {
14e6d6c189SCody Peter Mello	echo "$1" >&2
15e6d6c189SCody Peter Mello	RESULT=1
16e6d6c189SCody Peter Mello}
17e6d6c189SCody Peter Mello
18e6d6c189SCody Peter Melloecho T.func: test user-defined functions
19e6d6c189SCody Peter Mello
20e6d6c189SCody Peter Melloecho '10 2
21e6d6c189SCody Peter Mello2 10
22e6d6c189SCody Peter Mello10 10
23e6d6c189SCody Peter Mello10 1e1
24e6d6c189SCody Peter Mello1e1 9' | $AWK '
25e6d6c189SCody Peter Mello# tests whether function returns sensible type bits
26e6d6c189SCody Peter Mello
27e6d6c189SCody Peter Mellofunction assert(cond) { # assertion
28e6d6c189SCody Peter Mello    if (cond) print 1; else print 0
29e6d6c189SCody Peter Mello}
30e6d6c189SCody Peter Mello
31e6d6c189SCody Peter Mellofunction i(x) { return x }
32e6d6c189SCody Peter Mello
33e6d6c189SCody Peter Mello{ m=$1; n=i($2); assert(m>n) }
34e6d6c189SCody Peter Mello' > $TEMP1
35e6d6c189SCody Peter Melloecho '1
36e6d6c189SCody Peter Mello0
37e6d6c189SCody Peter Mello0
38e6d6c189SCody Peter Mello0
39e6d6c189SCody Peter Mello1' > $TEMP2
40e6d6c189SCody Peter Mellodiff $TEMP1 $TEMP2 || fail 'BAD: T.func (function return type)'
41e6d6c189SCody Peter Mello
42e6d6c189SCody Peter Melloecho 'data: data' > $TEMP1
43e6d6c189SCody Peter Mello$AWK '
44e6d6c189SCody Peter Mellofunction test1(array) { array["test"] = "data" }
45e6d6c189SCody Peter Mellofunction test2(array) { return(array["test"]) }
46e6d6c189SCody Peter MelloBEGIN { test1(foo); print "data: " test2(foo) }
47e6d6c189SCody Peter Mello' > $TEMP2
48e6d6c189SCody Peter Mellodiff $TEMP1 $TEMP2 || fail 'BAD: T.func (array type)'
49e6d6c189SCody Peter Mello
50e6d6c189SCody Peter Mello$AWK '
51e6d6c189SCody Peter MelloBEGIN	{ code() }
52e6d6c189SCody Peter MelloEND	{ codeout("x") }
53e6d6c189SCody Peter Mellofunction code() { ; }
54e6d6c189SCody Peter Mellofunction codeout(ex) { print ex }
55e6d6c189SCody Peter Mello' /dev/null > $TEMP1
56e6d6c189SCody Peter Melloecho x > $TEMP2
57e6d6c189SCody Peter Mellodiff $TEMP1 $TEMP2 || fail 'BAD: T.func (argument passing)'
58e6d6c189SCody Peter Mello
59e6d6c189SCody Peter Mello$AWK '
60e6d6c189SCody Peter MelloBEGIN { unireghf() }
61e6d6c189SCody Peter Mello
62e6d6c189SCody Peter Mellofunction unireghf(hfeed) {
63e6d6c189SCody Peter Mello	hfeed[1]=0
64e6d6c189SCody Peter Mello	rcell("foo",hfeed)
65e6d6c189SCody Peter Mello	hfeed[1]=0
66e6d6c189SCody Peter Mello	rcell("bar",hfeed)
67e6d6c189SCody Peter Mello}
68e6d6c189SCody Peter Mello
69e6d6c189SCody Peter Mellofunction rcell(cellname,hfeed) {
70e6d6c189SCody Peter Mello	print cellname
71e6d6c189SCody Peter Mello}
72e6d6c189SCody Peter Mello' > $TEMP1
73e6d6c189SCody Peter Melloecho "foo
74e6d6c189SCody Peter Mellobar" > $TEMP2
75e6d6c189SCody Peter Mellodiff $TEMP1 $TEMP2 || fail 'BAD: T.func (convert arg to array)'
76e6d6c189SCody Peter Mello
77e6d6c189SCody Peter Mello$AWK '
78e6d6c189SCody Peter Mellofunction f(n) {
79e6d6c189SCody Peter Mello	if (n <= 1)
80e6d6c189SCody Peter Mello		return 1
81e6d6c189SCody Peter Mello	else
82e6d6c189SCody Peter Mello		return n * f(n-1)
83e6d6c189SCody Peter Mello}
84e6d6c189SCody Peter Mello{ print f($1) }
85e6d6c189SCody Peter Mello' > $TEMP2 <<!
86e6d6c189SCody Peter Mello0
87e6d6c189SCody Peter Mello1
88e6d6c189SCody Peter Mello2
89e6d6c189SCody Peter Mello3
90e6d6c189SCody Peter Mello4
91e6d6c189SCody Peter Mello5
92e6d6c189SCody Peter Mello6
93e6d6c189SCody Peter Mello7
94e6d6c189SCody Peter Mello8
95e6d6c189SCody Peter Mello9
96e6d6c189SCody Peter Mello!
97e6d6c189SCody Peter Mellocat > $TEMP1 <<!
98e6d6c189SCody Peter Mello1
99e6d6c189SCody Peter Mello1
100e6d6c189SCody Peter Mello2
101e6d6c189SCody Peter Mello6
102e6d6c189SCody Peter Mello24
103e6d6c189SCody Peter Mello120
104e6d6c189SCody Peter Mello720
105e6d6c189SCody Peter Mello5040
106e6d6c189SCody Peter Mello40320
107e6d6c189SCody Peter Mello362880
108e6d6c189SCody Peter Mello!
109e6d6c189SCody Peter Mellodiff $TEMP1 $TEMP2 || fail 'BAD: T.func (factorial)'
110e6d6c189SCody Peter Mello
111e6d6c189SCody Peter Mello$AWK '
112e6d6c189SCody Peter Mellofunction ack(m,n) {
113e6d6c189SCody Peter Mello	k = k+1
114e6d6c189SCody Peter Mello	if (m == 0) return n+1
115e6d6c189SCody Peter Mello	if (n == 0) return ack(m-1, 1)
116e6d6c189SCody Peter Mello	return ack(m-1, ack(m, n-1))
117e6d6c189SCody Peter Mello}
118e6d6c189SCody Peter Mello{ k = 0; print ack($1,$2), "(" k " calls)" }
119e6d6c189SCody Peter Mello' > $TEMP2 <<!
120e6d6c189SCody Peter Mello0 0
121e6d6c189SCody Peter Mello1 1
122e6d6c189SCody Peter Mello2 2
123e6d6c189SCody Peter Mello3 3
124e6d6c189SCody Peter Mello3 4
125e6d6c189SCody Peter Mello3 5
126e6d6c189SCody Peter Mello!
127e6d6c189SCody Peter Mellocat > $TEMP1 <<!
128e6d6c189SCody Peter Mello1 (1 calls)
129e6d6c189SCody Peter Mello3 (4 calls)
130e6d6c189SCody Peter Mello7 (27 calls)
131e6d6c189SCody Peter Mello61 (2432 calls)
132e6d6c189SCody Peter Mello125 (10307 calls)
133e6d6c189SCody Peter Mello253 (42438 calls)
134e6d6c189SCody Peter Mello!
135e6d6c189SCody Peter Mellodiff $TEMP1 $TEMP2 || fail 'BAD: T.func (ackermann)'
136e6d6c189SCody Peter Mello
137e6d6c189SCody Peter Mello$AWK '
138e6d6c189SCody Peter MelloEND { print "end" }
139e6d6c189SCody Peter Mello{ print fib($1) }
140e6d6c189SCody Peter Mellofunction fib(n) {
141e6d6c189SCody Peter Mello	if (n <= 1) return 1
142e6d6c189SCody Peter Mello	else return add(fib(n-1), fib(n-2))
143e6d6c189SCody Peter Mello}
144e6d6c189SCody Peter Mellofunction add(m,n) { return m+n }
145e6d6c189SCody Peter MelloBEGIN { print "begin" }
146e6d6c189SCody Peter Mello' > $TEMP2 <<!
147e6d6c189SCody Peter Mello1
148e6d6c189SCody Peter Mello3
149e6d6c189SCody Peter Mello5
150e6d6c189SCody Peter Mello10
151e6d6c189SCody Peter Mello!
152e6d6c189SCody Peter Mellocat > $TEMP1 <<!
153e6d6c189SCody Peter Mellobegin
154e6d6c189SCody Peter Mello1
155e6d6c189SCody Peter Mello3
156e6d6c189SCody Peter Mello8
157e6d6c189SCody Peter Mello89
158e6d6c189SCody Peter Melloend
159e6d6c189SCody Peter Mello!
160e6d6c189SCody Peter Mellodiff $TEMP1 $TEMP2 || fail 'BAD: T.func (fib)'
161e6d6c189SCody Peter Mello
162e6d6c189SCody Peter Mello$AWK '
163e6d6c189SCody Peter Mellofunction foo() {
164e6d6c189SCody Peter Mello	for (i = 1; i <= 2; i++)
165e6d6c189SCody Peter Mello		return 3
166e6d6c189SCody Peter Mello	print "should not see this"
167e6d6c189SCody Peter Mello}
168e6d6c189SCody Peter MelloBEGIN { foo(); exit }
169e6d6c189SCody Peter Mello' > $TEMP1
170e6d6c189SCody Peter Mellogrep 'should not' $TEMP1 && fail 'BAD: T.func (return)'
171e6d6c189SCody Peter Mello
172e6d6c189SCody Peter Mello# this exercises multiple free of temp cells
173e6d6c189SCody Peter Melloecho 'eqn
174e6d6c189SCody Peter Melloeqn2' > $TEMP1
175e6d6c189SCody Peter Mello$AWK 'BEGIN 	{ eprocess("eqn", "x", contig)
176e6d6c189SCody Peter Mello	  process("tbl" )
177e6d6c189SCody Peter Mello	  eprocess("eqn" "2", "x", contig)
178e6d6c189SCody Peter Mello	}
179e6d6c189SCody Peter Mellofunction eprocess(file, first, contig) {
180e6d6c189SCody Peter Mello	print file
181e6d6c189SCody Peter Mello}
182e6d6c189SCody Peter Mellofunction process(file) {
183e6d6c189SCody Peter Mello	close(file)
184e6d6c189SCody Peter Mello}' > $TEMP2
185e6d6c189SCody Peter Mellodiff $TEMP1 $TEMP2 || fail 'BAD: T.func (eqn)'
186e6d6c189SCody Peter Mello
187e6d6c189SCody Peter Melloecho 1 > $TEMP1
188e6d6c189SCody Peter Mello$AWK 'function f() { n = 1; exit }
189e6d6c189SCody Peter Mello	BEGIN { n = 0; f(); n = 2 }; END { print n}' > $TEMP2
190e6d6c189SCody Peter Mellodiff $TEMP1 $TEMP2 || fail 'BAD: T.func (exit in function)'
191e6d6c189SCody Peter Mello
192e6d6c189SCody Peter Melloecho 1 > $TEMP1
193e6d6c189SCody Peter Mello$AWK '
194e6d6c189SCody Peter MelloBEGIN {	n = 10
195e6d6c189SCody Peter Mello	for (i = 1; i <= n; i++)
196e6d6c189SCody Peter Mello	for (j = 1; j <= n; j++)
197e6d6c189SCody Peter Mello		x[i,j] = n * i + j
198e6d6c189SCody Peter Mello	for (i = 1; i <= n; i++)
199e6d6c189SCody Peter Mello	for (j = 1; j <= n; j++)
200e6d6c189SCody Peter Mello		if ((i,j) in x)
201e6d6c189SCody Peter Mello			k++
202e6d6c189SCody Peter Mello	print (k == n^2)
203e6d6c189SCody Peter Mello      }
204e6d6c189SCody Peter Mello' > $TEMP2
205e6d6c189SCody Peter Mellodiff $TEMP1 $TEMP2 || fail 'BAD: T.func (multi-dim subscript)'
206e6d6c189SCody Peter Mello
207*3ee4fc2aSCody Peter Melloecho '<> 0' > $TEMP1
208*3ee4fc2aSCody Peter Mello$AWK '
209*3ee4fc2aSCody Peter Mellofunction foo() { i = 0 }
210*3ee4fc2aSCody Peter Mello        BEGIN { x = foo(); printf "<%s> %d\n", x, x }' > $TEMP2
211*3ee4fc2aSCody Peter Mellodiff $TEMP1 $TEMP2 || fail 'BAD: T.func (fall off end)'
212*3ee4fc2aSCody Peter Mello
213e6d6c189SCody Peter Melloexit $RESULT
214