forked from microsoft/verona
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathregion101.verona
161 lines (135 loc) · 4.11 KB
/
region101.verona
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright Microsoft and Project Verona Contributors.
// SPDX-License-Identifier: MIT
/************************************************************************
* This file illustrates some of the region design.
*
* Currently only uses traced regions as other forms of region have not been
* exposed in the language.
*
* Primary aim of the example is to illustrate prompt collection of whole
* regions, and independent tracing of objects within a region.
************************************************************************/
class Node
{
id: U64;
field: (Node & mut) | (None & imm);
// Self should really be read-only, but not implemented yet.
// This is called when the runtime deallocates this object.
final(self: mut)
{
Builtin.print1("Deallocating id {}\n", self.id);
}
}
class IsoNode
{
id: U64;
next: (IsoNode & iso) | (None & imm);
// Self should really be read-only, but not implemented yet.
// This is called when the runtime deallocates this object.
final(self: mut)
{
Builtin.print1("Deallocating id {}\n", self.id);
}
}
class Main
{
test1()
{
Builtin.print("Test 1\n");
// Note, `in` is used in allocation to specify a region,
// without `in` a new region is assumed.
// Allocate a new node in its own region.
var r1 = new Node;
// Allocate two nodes in the same region as r1.
var r2 = new Node in r1;
var r3 = new Node in r1;
// Give nodes an id for logging
r1.id = 1;
r2.id = 2;
r3.id = 3;
// Create a little graph that has a cycle
r1.field = r2;
r2.field = r3;
r3.field = mut-view(r1);
var other = new Node;
other.id = 10;
// The following line should be ruled out by the type checker, but that type
// of check is not currently implemented. TODO
// r3.field = mut-view(other);
// This deallocates the original value of r1, so r2 and r3 cannot be used
// from this point on
r1 = new Node;
r1.id = 4;
Builtin.print("Update\n");
// The following line will trigger a type error as you cannot use r2 at this
// point:
// Builtin.print1("r2.id = {}\n", r2.id);
Builtin.print("Test 1 - complete\n");
// CHECK-L: Deallocating id 1
// CHECK-L: Update
// CHECK-L: Deallocating id 4
}
test2()
{
Builtin.print("\n\nTest 2\n");
//Build a region with an unreachable object.
var r1 = new Node;
var r2 = new Node in r1;
r1.id = 1;
r2.id = 2;
//Build a second region with an unreachable object.
var r3 = new Node;
var r4 = new Node in r3;
r3.id = 3;
r4.id = 4;
Builtin.print("Test 2 - Trace Started\n");
// Implementation work required to improve trace signature.
Builtin.trace(mut-view(r1));
// Note this does not collect the unreachable object r4, as it is only
// tracing the region assocoiated with r1.
Builtin.print("Test 2 - Trace finished\n");
// TODO: should be illegal to access r2 at this point, but implementation
// cannot express relevant signature for trace.
// Builtin.print("Illegal: {}\n", r2.id);
Builtin.print("Test 2 - complete\n");
// CHECK-L: Deallocating id 2
// CHECK-L: Test 2 - Trace finished
// CHECK-L: Deallocating id 4
}
test3()
{
Builtin.print("\n\nTest 3\n");
var i1 = new IsoNode;
var i2 = new IsoNode;
var i3 = new IsoNode;
i1.id = 1;
i2.id = 2;
i3.id = 3;
// Create a simple three element linked list
i3.next = None.create();
i2.next = i3;
i1.next = i2;
// Swing a pointer
Builtin.print("Swing pointer\n");
var t = i1.next;
match t
{
var a : None => a,
var i : IsoNode =>
{
i1.next = (i.next = None.create())
}
};
Builtin.print("Swing pointer - complete\n");
Builtin.print("Test 3 - complete\n");
// CHECK-L: Deallocating id 2
// CHECK-L: Test 3 - complete
// CHECK-L: Deallocating id 1
}
main()
{
Main.test1();
Main.test2();
Main.test3();
}
}