blob: f84af8d73a41cf9f911577a9f8d5e39307ed83aa (
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
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
|
//: Instructions can read from addresses pointing at other locations using the
//: 'deref' property.
:(scenario copy_indirect)
recipe main [
1:address:integer <- copy 2:literal
2:integer <- copy 34:literal
# This loads location 1 as an address and looks up *that* location.
3:integer <- copy 1:address:integer/deref
]
+run: instruction main/2
+mem: location 1 is 2
+mem: location 2 is 34
+mem: storing 34 in location 3
:(before "int base = x.value" following "vector<int> read_memory(reagent x)")
x = canonize(x);
//: similarly, write to addresses pointing at other locations using the
//: 'deref' property
:(scenario store_indirect)
recipe main [
1:address:integer <- copy 2:literal
1:address:integer/deref <- copy 34:literal
]
+run: instruction main/1
+mem: location 1 is 2
+mem: storing 34 in location 2
:(before "int base = x.value" following "void write_memory(reagent x, vector<int> data)")
x = canonize(x);
:(code)
reagent canonize(reagent x) {
if (isa_literal(x)) return x;
//? cout << "canonize\n"; //? 1
reagent r = x;
//? cout << x.to_string() << " => " << r.to_string() << '\n'; //? 1
while (has_property(r, "deref"))
r = deref(r);
return r;
}
reagent deref(reagent x) {
//? cout << "deref: " << x.to_string() << "\n"; //? 2
static const int ADDRESS = Type_number["address"];
reagent result;
assert(x.types[0] == ADDRESS);
// compute value
result.set_value(Memory[x.value]);
trace("mem") << "location " << x.value << " is " << result.value;
// populate types
copy(++x.types.begin(), x.types.end(), inserter(result.types, result.types.begin()));
// drop-one 'deref'
int i = 0;
int len = x.properties.size();
for (i = 0; i < len; ++i) {
if (x.properties[i].first == "deref") break;
result.properties.push_back(x.properties[i]);
}
++i; // skip first deref
for (; i < len; ++i) {
result.properties.push_back(x.properties[i]);
}
return result;
}
//:: 'get' can read from container address
:(scenario get_indirect)
recipe main [
1:integer <- copy 2:literal
2:integer <- copy 34:literal
3:integer <- copy 35:literal
4:integer <- get 1:address:point/deref, 0:offset
]
+run: instruction main/3
+run: address to copy is 2
+run: product 0 is 34
+mem: storing 34 in location 4
:(scenario include_nonderef_properties)
recipe main [
1:integer <- copy 2:literal
2:integer <- copy 34:literal
3:integer <- copy 35:literal
4:integer <- get 1:address:point/deref/foo, 0:offset
]
+run: instruction main/3
+run: address to copy is 2
+run: product 0 is 34
+mem: storing 34 in location 4
:(after "reagent base = " following "case GET:")
base = canonize(base);
:(scenario get_address_indirect)
# 'get' can read from container address
recipe main [
1:integer <- copy 2:literal
2:integer <- copy 34:literal
3:integer <- copy 35:literal
4:integer <- get-address 1:address:point/deref, 0:offset
]
+run: instruction main/3
+run: address to copy is 2
+run: product 0 is 2
:(after "reagent base = " following "case GET_ADDRESS:")
base = canonize(base);
//:: helpers
:(code)
bool has_property(reagent x, string name) {
for (index_t i = 0; i < x.properties.size(); ++i) {
if (x.properties[i].first == name) return true;
}
return false;
}
vector<string> property(const reagent& r, const string& name) {
for (index_t p = 0; p != r.properties.size(); ++p) {
if (r.properties[p].first == name)
return r.properties[p].second;
}
return vector<string>();
}
|