From b291f85b8d0ece9312b066a84cbeca1b367fe85f Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Thu, 19 Feb 2015 23:49:13 -0800 Subject: 798 - start of record support --- cpp/.traces/copy_multiple_locations | 21 +++++++++++++++++++++ cpp/010vm | 11 +++++++++-- cpp/012run | 19 +++++++++++++------ cpp/017and-record | 27 +++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 cpp/.traces/copy_multiple_locations create mode 100644 cpp/017and-record diff --git a/cpp/.traces/copy_multiple_locations b/cpp/.traces/copy_multiple_locations new file mode 100644 index 00000000..d721dafb --- /dev/null +++ b/cpp/.traces/copy_multiple_locations @@ -0,0 +1,21 @@ +parse/0: instruction: 1 +parse/0: ingredient: {name: "34", type: 0} +parse/0: product: {name: "1", type: 1} +parse/0: instruction: 1 +parse/0: ingredient: {name: "0", type: 0} +parse/0: product: {name: "2", type: 2} +parse/0: instruction: 1 +parse/0: ingredient: {name: "1", type: 3} +parse/0: product: {name: "3", type: 3} +run/0: instruction 0 +run/0: ingredient 0 is 34 +mem/0: storing in location 1 +run/0: instruction 1 +run/0: ingredient 0 is 0 +mem/0: storing in location 2 +run/0: instruction 2 +run/0: ingredient 0 is 1 +mem/0: location 1 is 34 +mem/0: location 2 is 0 +mem/0: storing in location 3 +mem/0: storing in location 4 diff --git a/cpp/010vm b/cpp/010vm index b864179e..342eeb9a 100644 --- a/cpp/010vm +++ b/cpp/010vm @@ -77,6 +77,8 @@ void setup_types() { int integer = Type_number["integer"] = 1; Type[integer].size = 1; Next_type_number++; + int boolean = Type_number["boolean"] = Next_type_number++; + Type[boolean].size = 1; // End Mu Types. } :(before "End Setup") @@ -86,14 +88,19 @@ void setup_types() { // You can construct arbitrary new types. Types are either 'records', containing // 'fields' of other types, 'array's of a single type repeated over and over, // or 'addresses' pointing at a location elsewhere in memory. +// +// For example: +// storing bank balance next to a person's name might require a record, and +// high scores in a game might need an array of numbers. +// You'll see examples using addresses later. struct type_info { - int size; + size_t size; bool is_address; bool is_record; bool is_array; vector target; // only if is_address vector > elements; // only if is_record or is_array - type_info() :size(0) {} + type_info() :size(0), is_address(false), is_record(false), is_array(false) {} }; :(before "End Globals") diff --git a/cpp/012run b/cpp/012run index acc423a4..a1778705 100644 --- a/cpp/012run +++ b/cpp/012run @@ -47,16 +47,23 @@ vector read_memory(reagent x) { result.push_back(to_int(x.name)); return result; } - int val = Memory[to_int(x.name)]; - trace("mem") << "location " << x.name << " is " << val; - result.push_back(val); + 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; } void write_memory(reagent x, vector data) { - int dest = to_int(x.name); - trace("mem") << "storing in location " << dest; - Memory[dest] = data[0]; + int base = to_int(x.name); + size_t size = Type[x.types[0]].size; + 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) diff --git a/cpp/017and-record b/cpp/017and-record new file mode 100644 index 00000000..a9a3c0a0 --- /dev/null +++ b/cpp/017and-record @@ -0,0 +1,27 @@ +// Support for records. +:(before "End Mu Types") +// We'll use this record as a running example, with two fields: an integer and +// a boolean. +int integer_boolean = Type_number["integer-boolean"] = Next_type_number++; +Type[integer_boolean].size = 2; +Type[integer_boolean].is_record = true; +vector i; +i.push_back(integer); +Type[integer_boolean].elements.push_back(i); +vector b; +b.push_back(boolean); +Type[integer_boolean].elements.push_back(b); + +// Records can be copied around with a single instruction just like integers, +// no matter how large they are. +:(scenario copy_multiple_locations) +recipe main [ + 1:integer <- copy 34:literal + 2:boolean <- copy 0:literal + 3:integer-boolean <- copy 1:integer-boolean +] ++run: ingredient 0 is 1 ++mem: location 1 is 34 ++mem: location 2 is 0 ++mem: storing in location 3 ++mem: storing in location 4 -- cgit 1.4.1-2-gfad0