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 /cpp/034exclusive_container | |
parent | 6ea73c227fc6479e4de64690f197ea0ae24a0bfd (diff) | |
download | mu-dd994cdad0eb4aa5b890ec62138d573fdf3c3f10.tar.gz |
1085 - to access variants of sum types use 'maybe-convert'
Diffstat (limited to 'cpp/034exclusive_container')
-rw-r--r-- | cpp/034exclusive_container | 48 |
1 files changed, 48 insertions, 0 deletions
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; +} |