aboutsummaryrefslogtreecommitdiff
path: root/tests/programs/zc0umd.zc
blob: b5a6d2aa8d346e6da6bd5658b6cfded24e2fb12c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
namespace;
include rt;

// u, m and d are ordinary names, and a tag is written .u, .m or .d after a type.
// u*x, m*x and d*x with no space before the star is a recast when no variable
// named u, m or d is visible there (spec 1.6.3); otherwise, and with a space, it
// is a product. the same program runs on the resident compiler and, built
// into a run-only image, on stage 0 (src/tools/zc0.c), which reads the tags and
// recasts and does nothing with them.

int uu = 2, m = 3;			// globals (no global u, so u*x recasts below; m*x with m visible is a product)
int[4] d4;
int d(int x) { return x + 1; }		// a function

int mul3(int u, int m, int d) { return u * m * d; }	// parameters
int mixed(int.d u, int m, int d) { return u * m - d; }
int tagged(int(int) f, int.m x) { return f(x); }

// owned objects through locals named for their tags
word*.u box(int v) { word* m = rt.new(2); m[0] = v; m[1] = v * 2; return u*m; }
word*.u pair(int x, int m) {
	word* d = rt.new(2);
	d[0] = x; d[1] = m;
	return u*d;
}
.u single(int v) { let d = rt.new(1); d[0] = v; return u*d; }
int sum(word*.m m) { return m[0] + m[1]; }
int eat(word*.d d) { return d[0] + d[1]; }
int hold(.m u, .d d) { return u[0] * 100 + d[0]; }
int dig(word*.m u) { int m = u[0], d = u[1]; return m * 10 + d; }

fn main() {
	int a = 4, b = 5;
	int.m n = 9;
	word*.m p = box(7);
	.m q = single(6);
	word* r = pair(8, 9);
	let c = box(10), e = pair(1, 2);
	rt.put_n(uu * m); rt.put_c(32);			// two globals multiplied
	rt.put_n(uu*=m); rt.put_c(32);			// *= is not a recast either
	rt.put_n(d(uu) * d(m)); rt.put_c(32);
	rt.put_n(mul3(2, 3, 4)); rt.put_c(32);
	rt.put_n(mixed(7, 6, 5)); rt.put_c(32);
	rt.put_n(tagged(d, n)); rt.put_c(10);
	{
		int u = 6, m = 7, d = 8;		// locals shadow the globals
		rt.put_n(u * m); rt.put_c(32);
		rt.put_n(u * d - m); rt.put_c(32);
		rt.put_n(m * u * d); rt.put_c(32);
		rt.put_n(a * u + m * b); rt.put_c(10);
	}
	rt.put_n(sum(p)); rt.put_c(32);
	rt.put_n(q[0]); rt.put_c(32);
	rt.put_n(r[0] * r[1]); rt.put_c(32);
	rt.put_n(dig(c)); rt.put_c(32);
	rt.put_n(hold(e, single(5))); rt.put_c(32);
	rt.put_n(eat(d*p)); rt.put_c(10);
	return 0;
}