diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-04-17 18:32:39 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-04-17 18:32:39 -0700 |
commit | dd994cdad0eb4aa5b890ec62138d573fdf3c3f10 (patch) | |
tree | 855db79a1219794bc93dc6180c45a5ae529aaaeb | |
parent | 6ea73c227fc6479e4de64690f197ea0ae24a0bfd (diff) | |
download | mu-dd994cdad0eb4aa5b890ec62138d573fdf3c3f10.tar.gz |
1085 - to access variants of sum types use 'maybe-convert'
-rw-r--r-- | cpp/.traces/maybe_convert | 31 | ||||
-rw-r--r-- | cpp/.traces/maybe_convert_fail | 31 | ||||
-rw-r--r-- | cpp/030container | 2 | ||||
-rw-r--r-- | cpp/034exclusive_container | 48 |
4 files changed, 111 insertions, 1 deletions
diff --git a/cpp/.traces/maybe_convert b/cpp/.traces/maybe_convert new file mode 100644 index 00000000..c87f4aec --- /dev/null +++ b/cpp/.traces/maybe_convert @@ -0,0 +1,31 @@ +parse/0: instruction: 1 +parse/0: ingredient: {name: "1", value: 0, type: 0, properties: ["1": "literal"]} +parse/0: product: {name: "12", value: 0, type: 1, properties: ["12": "integer"]} +parse/0: instruction: 1 +parse/0: ingredient: {name: "35", value: 0, type: 0, properties: ["35": "literal"]} +parse/0: product: {name: "13", value: 0, type: 1, properties: ["13": "integer"]} +parse/0: instruction: 1 +parse/0: ingredient: {name: "36", value: 0, type: 0, properties: ["36": "literal"]} +parse/0: product: {name: "14", value: 0, type: 1, properties: ["14": "integer"]} +parse/0: instruction: 24 +parse/0: ingredient: {name: "12", value: 0, type: 8, properties: ["12": "integer-or-point"]} +parse/0: ingredient: {name: "1", value: 0, type: 0, properties: ["1": "variant"]} +parse/0: product: {name: "20", value: 0, type: 2-6, properties: ["20": "address":"point"]} +after-brace/0: recipe main +after-brace/0: copy ... +after-brace/0: copy ... +after-brace/0: copy ... +after-brace/0: maybe-convert ... +run/0: instruction main/0 +run/0: ingredient 0 is 1 +mem/0: storing 1 in location 12 +run/0: instruction main/1 +run/0: ingredient 0 is 35 +mem/0: storing 35 in location 13 +run/0: instruction main/2 +run/0: ingredient 0 is 36 +mem/0: storing 36 in location 14 +run/0: instruction main/3 +run/0: ingredient 0 is 12 +run/0: ingredient 1 is 1 +mem/0: storing 13 in location 20 diff --git a/cpp/.traces/maybe_convert_fail b/cpp/.traces/maybe_convert_fail new file mode 100644 index 00000000..33666c95 --- /dev/null +++ b/cpp/.traces/maybe_convert_fail @@ -0,0 +1,31 @@ +parse/0: instruction: 1 +parse/0: ingredient: {name: "1", value: 0, type: 0, properties: ["1": "literal"]} +parse/0: product: {name: "12", value: 0, type: 1, properties: ["12": "integer"]} +parse/0: instruction: 1 +parse/0: ingredient: {name: "35", value: 0, type: 0, properties: ["35": "literal"]} +parse/0: product: {name: "13", value: 0, type: 1, properties: ["13": "integer"]} +parse/0: instruction: 1 +parse/0: ingredient: {name: "36", value: 0, type: 0, properties: ["36": "literal"]} +parse/0: product: {name: "14", value: 0, type: 1, properties: ["14": "integer"]} +parse/0: instruction: 24 +parse/0: ingredient: {name: "12", value: 0, type: 8, properties: ["12": "integer-or-point"]} +parse/0: ingredient: {name: "0", value: 0, type: 0, properties: ["0": "variant"]} +parse/0: product: {name: "20", value: 0, type: 2-6, properties: ["20": "address":"point"]} +after-brace/0: recipe main +after-brace/0: copy ... +after-brace/0: copy ... +after-brace/0: copy ... +after-brace/0: maybe-convert ... +run/0: instruction main/0 +run/0: ingredient 0 is 1 +mem/0: storing 1 in location 12 +run/0: instruction main/1 +run/0: ingredient 0 is 35 +mem/0: storing 35 in location 13 +run/0: instruction main/2 +run/0: ingredient 0 is 36 +mem/0: storing 36 in location 14 +run/0: instruction main/3 +run/0: ingredient 0 is 12 +run/0: ingredient 1 is 0 +mem/0: storing 0 in location 20 diff --git a/cpp/030container b/cpp/030container index 7f333509..fa936d25 100644 --- a/cpp/030container +++ b/cpp/030container @@ -108,7 +108,7 @@ case GET: { } //: 'get' requires a literal in ingredient 1. We'll use a synonym called -//: 'offset' +//: 'offset'. :(before "End Mu Types Initialization") Type_number["offset"] = 0; diff --git a/cpp/034exclusive_container b/cpp/034exclusive_container index 07758694..e38433d6 100644 --- a/cpp/034exclusive_container +++ b/cpp/034exclusive_container @@ -53,7 +53,55 @@ if (t.kind == exclusive_container) { return result+1; } +//: To access variants of an exclusive container, use 'maybe-convert'. +//: It always returns an address (so that you can modify it) or null (to +//: signal that the conversion failed (because the container contains a +//: different variant). + +//: 'maybe-convert' requires a literal in ingredient 1. We'll use a synonym +//: called 'variant'. +:(before "End Mu Types Initialization") +Type_number["variant"] = 0; + +:(scenario "maybe_convert") +recipe main [ + 12:integer <- copy 1:literal + 13:integer <- copy 35:literal + 14:integer <- copy 36:literal + 20:address:point <- maybe-convert 12:integer-or-point, 1:variant +] ++mem: storing 13 in location 20 + +:(scenario "maybe_convert_fail") +recipe main [ + 12:integer <- copy 1:literal + 13:integer <- copy 35:literal + 14:integer <- copy 36:literal + 20:address:point <- maybe-convert 12:integer-or-point, 0:variant +] ++mem: storing 0 in location 20 + :(before "End Primitive Recipe Declarations") MAYBE_CONVERT, :(before "End Primitive Recipe Numbers") Recipe_number["maybe-convert"] = MAYBE_CONVERT; +:(before "End Primitive Recipe Implementations") +case MAYBE_CONVERT: { + trace("run") << "ingredient 0 is " << instructions[pc].ingredients[0].name; + reagent base = canonize(instructions[pc].ingredients[0]); + int base_address = base.value; + int base_type = base.types[0]; + assert(Type[base_type].kind == exclusive_container); + trace("run") << "ingredient 1 is " << instructions[pc].ingredients[1].name; + assert(isa_literal(instructions[pc].ingredients[1])); + size_t tag = instructions[pc].ingredients[1].value; + vector<int> result; + if (tag == static_cast<size_t>(Memory[base_address])) { + result.push_back(base_address+1); + } + else { + result.push_back(0); + } + write_memory(instructions[pc].products[0], result); + break; +} |