diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-02-07 21:03:08 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-02-07 21:03:08 -0800 |
commit | 8d82da3c775e5223e2cb2d70ff6c75c9139c90bc (patch) | |
tree | 8996e43cec5fc8c391e53ff2f286b906bbb3ad41 | |
parent | d751912a06d269a7d9de2bac2402ed8901d6164a (diff) | |
download | mu-8d82da3c775e5223e2cb2d70ff6c75c9139c90bc.tar.gz |
2639 - convert variables to arrays of 'bytes'
Just this conversion isn't in itself a violation of the type system -- as long as there's no way to convert back. Except there is with 'merge'. Next step is to type-check 'merge'.
-rw-r--r-- | 038location_array.cc | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/038location_array.cc b/038location_array.cc new file mode 100644 index 00000000..b2ac48b1 --- /dev/null +++ b/038location_array.cc @@ -0,0 +1,42 @@ +:(before "End Primitive Recipe Declarations") +TO_LOCATION_ARRAY, +:(before "End Primitive Recipe Numbers") +put(Recipe_ordinal, "to-location-array", TO_LOCATION_ARRAY); +:(before "End Primitive Recipe Checks") +case TO_LOCATION_ARRAY: { + const recipe& caller = get(Recipe, r); + if (!is_shared_address_of_array_of_numbers(inst.products.at(0))) { + raise_error << maybe(caller.name) << "product of 'to-location-array' has incorrect type: " << inst.to_string() << '\n' << end(); + break; + } + break; +} +:(code) +bool is_shared_address_of_array_of_numbers(reagent product) { + canonize_type(product); + if (!product.type || product.type->value != get(Type_ordinal, "address")) return false; + drop_from_type(product, "address"); + if (!product.type || product.type->value != get(Type_ordinal, "shared")) return false; + drop_from_type(product, "shared"); + if (!product.type || product.type->value != get(Type_ordinal, "array")) return false; + drop_from_type(product, "array"); + if (!product.type || product.type->value != get(Type_ordinal, "number")) return false; + return true; +} +:(before "End Primitive Recipe Implementations") +case TO_LOCATION_ARRAY: { + long long int array_size = SIZE(ingredients.at(0)); + long long int allocation_size = array_size + /*refcount*/1 + /*length*/1; + ensure_space(allocation_size); + const long long int result = Current_routine->alloc; + products.resize(1); + products.at(0).push_back(result); + // initialize array refcount + put(Memory, result, 0); + // initialize array length + put(Memory, result+1, array_size); + // now copy over data + for (long long int i = 0; i < array_size; ++i) + put(Memory, result+2+i, ingredients.at(0).at(i)); + break; +} |