aboutsummaryrefslogtreecommitdiff
path: root/tests/programs/typedef.zc
blob: 307ef754b7f36143e6d119857f0346bc388a8264 (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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
namespace;
include rt;
typecheck on;

// typedef T name; makes name another way to write T: the same type, so the two mix freely
struct node { int v; node* next; };
struct pair<A, B> { A a; B b; };

typedef int count;
typedef char* label;
typedef node* link;
typedef link* links;
typedef int[4] quad;
typedef int(int, int) binop;
typedef pair<int, int> ipair;
typedef int[?] ints;
typedef count counter;

struct box { count n; link head; ipair p; };

count twice(count x) { return x + x; }
count add(int a, int b) { return a + b; }
count apply(binop f, count a, count b) { return f(a, b); }
count sum(link n) { count s = 0; while (n) { s += n.v; n = n.next; } return s; }
label hello() { return "hello"; }
string greet(string s) { return s; }
// string is only a type where a type is expected: an untyped parameter can still be called string
fn twice_name(string) { return string + string; }
count first_of(links ls) { return ls[0].v; }
T pick<T>(T x) { typedef T item; item y = x; return y; }
count scoped() {
	count total = 0;
	{ typedef int cell; cell c = 3; total += c; }
	{ typedef char* cell; cell c = "ab"; total += rt.len_w(c); }
	return total;
}
count scoped_again() { typedef quad cell; cell c; c[2] = 7; return c[2] + sizeof(cell); }

// a link is a node*: every use below mixes the two
count same_ptr(node* p, link q) { return p == q; }
count casts(link p) {
	word w = p as word;
	link back = w as link;
	node* n = (node*)back;
	return back.v + ((link)n == p);
}
count boxed(link p) {
	box bx; bx.n = 6; bx.head = 0; bx.p.a = 1; bx.p.b = 2;
	pair<link, count> pl; pl.a = 0; pl.b = 5;
	return bx.n + p.v + bx.p.a + bx.p.b + pl.b + !bx.head + !pl.a;
}
count by_ref(links ls) { return first_of(ls); }

fn main() {
	link a = rt.new(node), b = rt.new(node);
	a.v = 3; b.v = 4; a.next = b;
	rt.put_n(sum(a)); rt.put_c(' ');
	rt.put_n(same_ptr(a, a)); rt.put_c(' ');
	rt.put_n(twice(21)); rt.put_c(' ');
	rt.put_n(apply(add, 2, 3)); rt.put_c(' ');
	binop op = add;
	rt.put_n(op(10, 20)); rt.put_c(10);

	quad q; q[3] = 9;
	rt.put_n(q[3] + sizeof(quad)); rt.put_c(' ');
	rt.put_n(sizeof(count) + sizeof(link) + sizeof(ipair)); rt.put_c(' ');
	rt.put_n(boxed(a)); rt.put_c(' ');
	ints xs = {1, 2, 3};
	push(xs, 4);
	rt.put_n(len(xs)); rt.put_c(10);

	rt.put_n(casts(a)); rt.put_c(' ');
	counter k = (count)3;
	rt.put_n(k); rt.put_c(' ');
	links ls = &a;
	rt.put_n(by_ref(ls)); rt.put_c(' ');
	rt.put_n(pick<count>(11) + pick(1)); rt.put_c(10);

	rt.put_n(scoped()); rt.put_c(' ');
	rt.put_n(scoped_again()); rt.put_c(10);

	string s = "hi";
	label l = s;
	char* c = l;
	rt.put_s(s); rt.put_s(l); rt.put_s(c); rt.put_s(hello()); rt.put_s(greet("ok")); rt.put_c(10);
	rt.put_n(twice_name(4)); rt.put_c(10);
	rt.free(d*a);
	return 0;
}