diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-02-21 14:34:09 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-02-21 14:34:09 -0800 |
commit | 986eebffcfbc896449a0d61c395b714bab59c5f0 (patch) | |
tree | b1fffcccfa9312c711c4cb6486282005f9e40dcc /cpp/018address | |
parent | 0060093e9ed53a32570fab1c18da8074926520d1 (diff) | |
download | mu-986eebffcfbc896449a0d61c395b714bab59c5f0.tar.gz |
807 - first passing test for indirect addressing
Diffstat (limited to 'cpp/018address')
-rw-r--r-- | cpp/018address | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/cpp/018address b/cpp/018address new file mode 100644 index 00000000..4a5bcd51 --- /dev/null +++ b/cpp/018address @@ -0,0 +1,84 @@ +:(scenario "copy_indirect") +# Instructions can read from addresses pointing at other locations using the 'deref' property. +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 2 ++mem: location 1 is 2 ++mem: location 2 is 34 ++mem: storing in location 3 + +:(replace{} "vector<int> read_memory(reagent x)") +vector<int> read_memory(reagent x) { + vector<int> result; + if (x.types[0] == 0) { // literal + result.push_back(to_int(x.name)); + return result; + } + x = canonize(x); + int base = to_int(x.name); + for (size_t offset = 0; offset < Type[x.types[0]].size; ++offset) { + int val = Memory[base+offset]; + trace("mem") << "location " << base+offset << " is " << val; + result.push_back(val); + } + return result; +} + +:(replace{} "void write_memory(reagent x, vector<int> data)") +void write_memory(reagent x, vector<int> data) { + int base = to_int(x.name); + size_t size = size_of(x.types[0]); + if (size != data.size()) raise << "size mismatch in storing to " << x.to_string(); + for (size_t offset = 0; offset < size; ++offset) { + trace("mem") << "storing in location " << base+offset; + Memory[base+offset] = data[offset]; + } +} + +:(code) +reagent canonize(reagent x) { + reagent r = x; + while (has_property(r, "deref")) + r = deref(r); + return r; +} + +bool has_property(reagent x, string name) { + for (size_t i = 0; i < x.properties.size(); ++i) { + if (x.properties[i].first == name) return true; + } + return false; +} + +reagent deref(reagent x) { + reagent result(""); + assert(x.types[0] == 2); // address + + // compute name + ostringstream out; + out << Memory[to_int(x.name)]; + result.name = out.str(); + trace("mem") << "location " << x.name << " is " << result.name; + + // 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(); + while (true) { + assert(i < len); + if (x.properties[i].first == "deref") break; + result.properties.push_back(x.properties[i]); + ++i; + } + ++i; // skip first deref + while (i < len) { + result.properties.push_back(x.properties[i]); + } + return result; +} |