about summary refs log tree commit diff stats
path: root/031address.cc
blob: f38e96ba0386916dcd10e95b8b8f1832762ac202 (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:number <- copy 2:literal
  2:number <- copy 34:literal
  # This loads location 1 as an address and looks up *that* location.
  3:number <- copy 1:address:number/deref
]
+run: instruction main/2
+mem: location 1 is 2
+mem: location 2 is 34
+mem: storing 34 in location 3

:(before "long long int base = x.value" following "vector<double> 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:number <- copy 2:literal
  1:address:number/deref <- copy 34:literal
]
+run: instruction main/1
+mem: location 1 is 2
+mem: storing 34 in location 2

:(before "long long int base = x.value" following "void write_memory(reagent x, vector<double> 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 type_number ADDRESS = Type_number["address"];
  reagent result;
  assert(x.types.at(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'
  long long int i = 0;
  long long int len = SIZE(x.properties);
  for (i = 0; i < len; ++i) {
    if (x.properties.at(i).first == "deref") break;
    result.properties.push_back(x.properties.at(i));
  }
  ++i;  // skip first deref
  for (; i < len; ++i) {
    result.properties.push_back(x.properties.at(i));
  }
  return result;
}

//:: 'get' can read from container address
:(scenario get_indirect)
recipe main [
  1:number <- copy 2:literal
  2:number <- copy 34:literal
  3:number <- copy 35:literal
  4:number <- get 1:address:point/deref, 0:offset
]
+run: instruction main/3
+run: address to copy is 2
+run: product 0 is 4
+mem: storing 34 in location 4

:(scenario include_nonderef_properties)
recipe main [
  1:number <- copy 2:literal
  2:number <- copy 34:literal
  3:number <- copy 35:literal
  4:number <- get 1:address:point/deref/foo, 0:offset
]
+run: instruction main/3
+run: address to copy is 2
+run: product 0 is 4
+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:number <- copy 2:literal
  2:number <- copy 34:literal
  3:number <- copy 35:literal
  4:number <- get-address 1:address:point/deref, 0:offset
]
+run: instruction main/3
+run: address to copy is 2
+run: product 0 is 4

:(after "reagent base = " following "case GET_ADDRESS:")
base = canonize(base);

//:: helpers

:(code)
bool has_property(reagent x, string name) {
  for (long long int i = 0; i < SIZE(x.properties); ++i) {
    if (x.properties.at(i).first == name) return true;
  }
  return false;
}

vector<string> property(const reagent& r, const string& name) {
  for (long long int p = 0; p != SIZE(r.properties); ++p) {
    if (r.properties.at(p).first == name)
      return r.properties.at(p).second;
  }
  return vector<string>();
}