diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-04-23 17:02:16 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-04-23 17:15:16 -0700 |
commit | 7bf9212fd47e505711cc0873d30456e3d793034d (patch) | |
tree | e6c84ac4666269b5e366ceff78dd040ac39343bc /033exclusive_container.cc | |
parent | 991d76f32817f5515fb8db25a7d5ca2912cfe4ac (diff) | |
download | mu-7bf9212fd47e505711cc0873d30456e3d793034d.tar.gz |
2861 - 'maybe-convert' no longer returns address
Diffstat (limited to '033exclusive_container.cc')
-rw-r--r-- | 033exclusive_container.cc | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/033exclusive_container.cc b/033exclusive_container.cc index 2a006a99..4a7a5e40 100644 --- a/033exclusive_container.cc +++ b/033exclusive_container.cc @@ -60,18 +60,24 @@ def main [ 12:number <- copy 1 13:number <- copy 35 14:number <- copy 36 - 20:address:point <- maybe-convert 12:number-or-point/unsafe, 1:variant + 20:point, 22:boolean <- maybe-convert 12:number-or-point/unsafe, 1:variant ] -+mem: storing 13 in location 20 +# point ++mem: storing 35 in location 20 ++mem: storing 36 in location 21 +# boolean ++mem: storing 1 in location 22 :(scenario maybe_convert_fail) def main [ 12:number <- copy 1 13:number <- copy 35 14:number <- copy 36 - 20:address:number <- maybe-convert 12:number-or-point/unsafe, 0:variant + 20:number, 21:boolean <- maybe-convert 12:number-or-point/unsafe, 0:variant ] -+mem: storing 0 in location 20 +# number: no write +# boolean ++mem: storing 0 in location 21 :(before "End Primitive Recipe Declarations") MAYBE_CONVERT, @@ -95,6 +101,10 @@ case MAYBE_CONVERT: { break; } if (inst.products.empty()) break; + if (SIZE(inst.products) != 2) { + raise << maybe(caller.name) << "'maybe-convert' expects exactly 2 products in '" << to_original_string(inst) << "'\n" << end(); + break; + } reagent product = inst.products.at(0); if (!canonize_type(product)) break; reagent& offset = inst.ingredients.at(1); @@ -104,11 +114,14 @@ case MAYBE_CONVERT: { break; } reagent variant = variant_type(base, offset.value); - variant.type = new type_tree("address", get(Type_ordinal, "address"), variant.type); if (!types_coercible(product, variant)) { raise << maybe(caller.name) << "'maybe-convert " << base.original_string << ", " << inst.ingredients.at(1).original_string << "' should write to " << to_string(variant.type) << " but " << product.name << " has type " << to_string(product.type) << '\n' << end(); break; } + if (!is_mu_boolean(inst.products.at(1))) { + raise << maybe(get(Recipe, r).name) << "second product yielded by 'maybe-convert' should be a boolean, but tried to write to " << inst.products.at(1).original_string << '\n' << end(); + break; + } break; } :(before "End Primitive Recipe Implementations") @@ -121,16 +134,26 @@ case MAYBE_CONVERT: { break; } int tag = current_instruction().ingredients.at(1).value; - int result; + reagent product = current_instruction().products.at(0); + canonize(product); + reagent did_conversion_happen = current_instruction().products.at(1); + canonize(did_conversion_happen); + // optimization: directly write results to only update first product when necessary if (tag == static_cast<int>(get_or_insert(Memory, base_address))) { - result = base_address+1; + const reagent variant = variant_type(base, tag); + for (int i = 0; i < size_of(variant); ++i) { + double val = get_or_insert(Memory, base_address+1+i); + trace(9999, "mem") << "storing " << no_scientific(val) << " in location " << product.value+i << end(); + put(Memory, product.value+i, val); + } + trace(9999, "mem") << "storing 1 in location " << did_conversion_happen.value << end(); + put(Memory, did_conversion_happen.value, 1); } else { - result = 0; + trace(9999, "mem") << "storing 0 in location " << did_conversion_happen.value << end(); + put(Memory, did_conversion_happen.value, 0); } - products.resize(1); - products.at(0).push_back(result); - break; + goto finish_instruction; } :(code) @@ -151,9 +174,9 @@ def main [ 12:number <- copy 1 13:number <- copy 35 14:number <- copy 36 - 20:address:number <- maybe-convert 12:number-or-point/unsafe, 1:variant + 20:number, 21:boolean <- maybe-convert 12:number-or-point/unsafe, 1:variant ] -+error: main: 'maybe-convert 12:number-or-point/unsafe, 1:variant' should write to (address point) but 20 has type (address number) ++error: main: 'maybe-convert 12:number-or-point/unsafe, 1:variant' should write to point but 20 has type number //:: Allow exclusive containers to be defined in mu code. @@ -338,6 +361,21 @@ def main [ ] +error: main: too few ingredients in '1:foo <- merge 1/y, 23' +:(scenario merge_check_exclusive_container_containing_container_4) +exclusive-container foo [ + x:number + y:bar +] +container bar [ + a:number + b:number +] +def main [ + 1:bar <- merge 23, 24 + 3:foo <- merge 1/y, 1:bar +] +$error: 0 + //: Since the different variants of an exclusive-container might have //: different sizes, relax the size mismatch check for 'merge' instructions. :(before "End size_mismatch(x) Cases") |