From b8348923fbc89c4cf7ec71c187b729fc0fa42d46 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Wed, 13 Apr 2016 09:03:06 -0700 Subject: 2831 - bugfix in static arrays I'd started using size_of() in transforms at some point, but not gotten around to actually updating it to support arrays before run-time. Wish there was a way I could statically enforce that something is only called at transform time vs runtime. Thanks Ella and Caleb Couch for finding this issue. Static arrays are likely still half-baked, but should get a thorough working-over in coming weeks. --- 032array.cc | 33 +++++++++++++++++++++++---------- 042name.cc | 18 ++++++++++++++++++ 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/032array.cc b/032array.cc index 0fd1d0a4..bd28fef3 100644 --- a/032array.cc +++ b/032array.cc @@ -49,24 +49,26 @@ case CREATE_ARRAY: { reagent product = current_instruction().products.at(0); canonize(product); int base_address = product.value; - int array_size = to_integer(product.type->right->right->name); + int array_length = to_integer(product.type->right->right->name); // initialize array size, so that size_of will work - put(Memory, base_address, array_size); // in array elements + put(Memory, base_address, array_length); // in array elements int size = size_of(product); // in locations trace(9998, "run") << "creating array of size " << size << '\n' << end(); // initialize array for (int i = 1; i <= size_of(product); ++i) { put(Memory, base_address+i, 0); } - // dummy product; doesn't actually do anything - products.resize(1); - products.at(0).push_back(array_size); - break; + // no need to update product + goto finish_instruction; } :(scenario copy_array) # Arrays can be copied around with a single instruction just like numbers, # no matter how large they are. +# You don't need to pass the size around, since each array variable stores its +# size in memory at run-time. We'll call a variable with an explicit size a +# 'static' array, and one without a 'dynamic' array since it can contain +# arrays of many different sizes. def main [ 1:array:number:3 <- create-array 2:number <- copy 14 @@ -103,18 +105,20 @@ def main [ ] +app: foo: 3 14 15 16 -//: disable the size mismatch check since the destination array need not be initialized -:(before "End size_mismatch(x) Cases") -if (x.type && x.type->value == get(Type_ordinal, "array")) return false; :(before "End size_of(reagent) Cases") if (r.type && r.type->value == get(Type_ordinal, "array")) { if (!r.type->right) { raise << maybe(current_recipe_name()) << "'" << r.original_string << "' is an array of what?\n" << end(); return 1; } - return 1 + get_or_insert(Memory, r.value)*size_of(array_element(r.type)); + return 1 + array_length(r)*size_of(array_element(r.type)); } +//: disable the size mismatch check for arrays since the destination array +//: need not be initialized +:(before "End size_mismatch(x) Cases") +if (x.type && x.type->value == get(Type_ordinal, "array")) return false; + //: arrays are disallowed inside containers unless their length is fixed in //: advance @@ -233,6 +237,15 @@ type_tree* array_element(const type_tree* type) { return type->right; } +int array_length(const reagent& x) { + if (x.type->right->right) { + return to_integer(x.type->right->right->name); + } + // this should never happen at transform time + // x should already be canonized. + return get_or_insert(Memory, x.value); +} + :(scenario index_indirect) def main [ 1:array:number:3 <- create-array diff --git a/042name.cc b/042name.cc index d0d114fb..ade9c069 100644 --- a/042name.cc +++ b/042name.cc @@ -149,6 +149,24 @@ bool is_special_name(const string& s) { return false; } +:(scenario transform_names_supports_containers) +def main [ + x:point <- merge 34, 35 + y:number <- copy 3 +] ++name: assign x 1 +# skip location 2 because x occupies two locations ++name: assign y 3 + +:(scenario transform_names_supports_static_arrays) +def main [ + x:array:number:3 <- create-array + y:number <- copy 3 +] ++name: assign x 1 +# skip locations 2, 3, 4 because x occupies four locations ++name: assign y 5 + :(scenario transform_names_passes_dummy) # _ is just a dummy result that never gets consumed def main [ -- cgit 1.4.1-2-gfad0