2931 - be explicit about making copies
This commit is contained in:
parent
ce9616a77f
commit
3473c63ad9
2
010vm.cc
2
010vm.cc
|
@ -388,7 +388,7 @@ string slurp_until(istream& in, char delim) {
|
|||
return out.str();
|
||||
}
|
||||
|
||||
bool has_property(reagent x, string name) {
|
||||
bool has_property(const reagent& x, const string& name) {
|
||||
for (int i = 0; i < SIZE(x.properties); ++i) {
|
||||
if (x.properties.at(i).first == name) return true;
|
||||
}
|
||||
|
|
10
020run.cc
10
020run.cc
|
@ -250,13 +250,14 @@ void load_all(string dir) {
|
|||
//:: Reading from memory, writing to memory.
|
||||
|
||||
:(code)
|
||||
vector<double> read_memory(reagent x) {
|
||||
vector<double> read_memory(reagent/*copy*/ x) {
|
||||
// Begin Preprocess read_memory(reagent x)
|
||||
vector<double> result;
|
||||
if (is_literal(x)) {
|
||||
result.push_back(x.value);
|
||||
return result;
|
||||
}
|
||||
// End Preprocess read_memory(x)
|
||||
// End Preprocess read_memory(reagent x)
|
||||
int size = size_of(x);
|
||||
for (int offset = 0; offset < size; ++offset) {
|
||||
double val = get_or_insert(Memory, x.value+offset);
|
||||
|
@ -266,14 +267,15 @@ vector<double> read_memory(reagent x) {
|
|||
return result;
|
||||
}
|
||||
|
||||
void write_memory(reagent x, const vector<double>& data) {
|
||||
void write_memory(reagent/*copy*/ x, const vector<double>& data) {
|
||||
// Begin Preprocess write_memory(reagent x, vector<double> data)
|
||||
if (!x.type) {
|
||||
raise << "can't write to " << to_string(x) << "; no type\n" << end();
|
||||
return;
|
||||
}
|
||||
if (is_dummy(x)) return;
|
||||
if (is_literal(x)) return;
|
||||
// End Preprocess write_memory(x)
|
||||
// End Preprocess write_memory(reagent x, vector<double> data)
|
||||
if (x.value == 0) return;
|
||||
if (size_mismatch(x, data)) {
|
||||
raise << maybe(current_recipe_name()) << "size mismatch in storing to " << x.original_string << " (" << size_of(x.type) << " vs " << SIZE(data) << ") at '" << to_original_string(current_instruction()) << "'\n" << end();
|
||||
|
|
|
@ -132,7 +132,8 @@ bool boolean_matches_literal(const reagent& to, const reagent& from) {
|
|||
|
||||
// copy arguments because later layers will want to make changes to them
|
||||
// without perturbing the caller
|
||||
bool types_strictly_match(reagent to, reagent from) {
|
||||
bool types_strictly_match(reagent/*copy*/ to, reagent/*copy*/ from) {
|
||||
// End Preprocess types_strictly_match(reagent to, reagent from)
|
||||
if (is_literal(from) && to.type->value == get(Type_ordinal, "number")) return true;
|
||||
// to sidestep type-checking, use /unsafe in the source.
|
||||
// this will be highlighted in red inside vim. just for setting up some tests.
|
||||
|
@ -145,7 +146,7 @@ bool types_strictly_match(reagent to, reagent from) {
|
|||
|
||||
// two types match if the second begins like the first
|
||||
// (trees perform the same check recursively on each subtree)
|
||||
bool types_strictly_match(type_tree* to, type_tree* from) {
|
||||
bool types_strictly_match(const type_tree* to, const type_tree* from) {
|
||||
if (!to) return true;
|
||||
if (!from) return to->value == 0;
|
||||
if (from->value == -1) return from->name == to->name;
|
||||
|
@ -169,25 +170,29 @@ bool is_unsafe(const reagent& r) {
|
|||
return has_property(r, "unsafe");
|
||||
}
|
||||
|
||||
bool is_mu_array(reagent r) {
|
||||
bool is_mu_array(reagent/*copy*/ r) {
|
||||
// End Preprocess is_mu_array(reagent r)
|
||||
if (!r.type) return false;
|
||||
if (is_literal(r)) return false;
|
||||
return r.type->value == get(Type_ordinal, "array");
|
||||
}
|
||||
|
||||
bool is_mu_address(reagent r) {
|
||||
bool is_mu_address(reagent/*copy*/ r) {
|
||||
// End Preprocess is_mu_address(reagent r)
|
||||
if (!r.type) return false;
|
||||
if (is_literal(r)) return false;
|
||||
return r.type->value == get(Type_ordinal, "address");
|
||||
}
|
||||
|
||||
bool is_mu_boolean(reagent r) {
|
||||
bool is_mu_boolean(reagent/*copy*/ r) {
|
||||
// End Preprocess is_mu_boolean(reagent r)
|
||||
if (!r.type) return false;
|
||||
if (is_literal(r)) return false;
|
||||
return r.type->value == get(Type_ordinal, "boolean");
|
||||
}
|
||||
|
||||
bool is_mu_number(reagent r) {
|
||||
bool is_mu_number(reagent/*copy*/ r) {
|
||||
// End Preprocess is_mu_number(reagent r)
|
||||
if (!r.type) return false;
|
||||
if (is_literal(r)) {
|
||||
if (!r.type) return false;
|
||||
|
@ -198,7 +203,7 @@ bool is_mu_number(reagent r) {
|
|||
return r.type->value == get(Type_ordinal, "number");
|
||||
}
|
||||
|
||||
bool is_mu_scalar(reagent r) {
|
||||
bool is_mu_scalar(reagent/*copy*/ r) {
|
||||
if (!r.type) return false;
|
||||
if (is_literal(r))
|
||||
return !r.type || r.type->name != "literal-string";
|
||||
|
|
|
@ -30,7 +30,7 @@ next_ingredient_to_process = 0;
|
|||
:(before "End Call Housekeeping")
|
||||
for (int i = 0; i < SIZE(ingredients); ++i) {
|
||||
current_call().ingredient_atoms.push_back(ingredients.at(i));
|
||||
reagent ingredient = call_instruction.ingredients.at(i);
|
||||
reagent/*copy*/ ingredient = call_instruction.ingredients.at(i);
|
||||
// End Compute Call Ingredient
|
||||
current_call().ingredients.push_back(ingredient);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ case NEXT_INGREDIENT: {
|
|||
case NEXT_INGREDIENT: {
|
||||
assert(!Current_routine->calls.empty());
|
||||
if (current_call().next_ingredient_to_process < SIZE(current_call().ingredient_atoms)) {
|
||||
reagent product = current_instruction().products.at(0);
|
||||
reagent/*copy*/ product = current_instruction().products.at(0);
|
||||
// End Preprocess NEXT_INGREDIENT product
|
||||
if (current_recipe_name() == "main") {
|
||||
// no ingredient types since the call might be implicit; assume ingredients are always strings
|
||||
|
|
|
@ -68,8 +68,8 @@ void check_types_of_reply_instructions(recipe_ordinal r) {
|
|||
break;
|
||||
}
|
||||
for (int i = 0; i < SIZE(caller_instruction.products); ++i) {
|
||||
reagent lhs = reply_inst.ingredients.at(i);
|
||||
reagent rhs = caller_instruction.products.at(i);
|
||||
reagent/*copy*/ lhs = reply_inst.ingredients.at(i);
|
||||
reagent/*copy*/ rhs = caller_instruction.products.at(i);
|
||||
// End Check RETURN Copy(lhs, rhs)
|
||||
if (!types_coercible(rhs, lhs)) {
|
||||
raise << maybe(callee.name) << reply_inst.name << " ingredient " << lhs.original_string << " can't be saved in " << rhs.original_string << '\n' << end();
|
||||
|
|
|
@ -180,7 +180,7 @@ void compute_container_metadata(const type_tree* type, set<type_ordinal>& pendin
|
|||
if (info.kind == CONTAINER) {
|
||||
container_metadata metadata;
|
||||
for (int i = 0; i < SIZE(info.elements); ++i) {
|
||||
reagent element = info.elements.at(i);
|
||||
reagent/*copy*/ element = info.elements.at(i);
|
||||
// Compute Container Metadata(element)
|
||||
compute_container_metadata(element.type, pending_metadata);
|
||||
metadata.offset.push_back(metadata.size); // save previous size as offset
|
||||
|
@ -244,14 +244,14 @@ case GET: {
|
|||
raise << maybe(get(Recipe, r).name) << "'get' expects exactly 2 ingredients in '" << to_original_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent base = inst.ingredients.at(0); // new copy for every invocation
|
||||
reagent/*copy*/ base = inst.ingredients.at(0); // new copy for every invocation
|
||||
// Update GET base in Check
|
||||
if (!base.type || !base.type->value || !contains_key(Type, base.type->value) || get(Type, base.type->value).kind != CONTAINER) {
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'get' should be a container, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
type_ordinal base_type = base.type->value;
|
||||
reagent offset = inst.ingredients.at(1);
|
||||
const reagent& offset = inst.ingredients.at(1);
|
||||
if (!is_literal(offset) || !is_mu_scalar(offset)) {
|
||||
raise << maybe(get(Recipe, r).name) << "second ingredient of 'get' should have type 'offset', but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
break;
|
||||
|
@ -266,9 +266,9 @@ case GET: {
|
|||
break;
|
||||
}
|
||||
if (inst.products.empty()) break;
|
||||
reagent product = inst.products.at(0);
|
||||
reagent/*copy*/ product = inst.products.at(0);
|
||||
// Update GET product in Check
|
||||
const reagent element = element_type(base.type, offset_value);
|
||||
const reagent& element = element_type(base.type, offset_value);
|
||||
if (!types_coercible(product, element)) {
|
||||
raise << maybe(get(Recipe, r).name) << "'get " << base.original_string << ", " << offset.original_string << "' should write to " << names_to_string_without_quotes(element.type) << " but " << product.name << " has type " << names_to_string_without_quotes(product.type) << '\n' << end();
|
||||
break;
|
||||
|
@ -277,7 +277,7 @@ case GET: {
|
|||
}
|
||||
:(before "End Primitive Recipe Implementations")
|
||||
case GET: {
|
||||
reagent base = current_instruction().ingredients.at(0);
|
||||
reagent/*copy*/ base = current_instruction().ingredients.at(0);
|
||||
// Update GET base in Run
|
||||
int base_address = base.value;
|
||||
if (base_address == 0) {
|
||||
|
@ -290,7 +290,7 @@ case GET: {
|
|||
assert(base.metadata.size);
|
||||
int src = base_address + base.metadata.offset.at(offset);
|
||||
trace(9998, "run") << "address to copy is " << src << end();
|
||||
reagent element = element_type(base.type, offset);
|
||||
reagent/*copy*/ element = element_type(base.type, offset);
|
||||
element.set_value(src);
|
||||
trace(9998, "run") << "its type is " << names_to_string(element.type) << end();
|
||||
// Read element
|
||||
|
@ -305,7 +305,7 @@ const reagent element_type(const type_tree* type, int offset_value) {
|
|||
assert(!get(Type, type->value).name.empty());
|
||||
const type_info& info = get(Type, type->value);
|
||||
assert(info.kind == CONTAINER);
|
||||
reagent element = info.elements.at(offset_value);
|
||||
reagent/*copy*/ element = info.elements.at(offset_value);
|
||||
// End element_type Special-cases
|
||||
return element;
|
||||
}
|
||||
|
@ -381,14 +381,14 @@ case PUT: {
|
|||
raise << maybe(get(Recipe, r).name) << "'put' expects exactly 3 ingredients in '" << to_original_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent base = inst.ingredients.at(0);
|
||||
reagent/*copy*/ base = inst.ingredients.at(0);
|
||||
// Update PUT base in Check
|
||||
if (!base.type || !base.type->value || !contains_key(Type, base.type->value) || get(Type, base.type->value).kind != CONTAINER) {
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'put' should be a container, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
type_ordinal base_type = base.type->value;
|
||||
reagent offset = inst.ingredients.at(1);
|
||||
reagent/*copy*/ offset = inst.ingredients.at(1);
|
||||
// Update PUT offset in Check
|
||||
if (!is_literal(offset) || !is_mu_scalar(offset)) {
|
||||
raise << maybe(get(Recipe, r).name) << "second ingredient of 'put' should have type 'offset', but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
|
@ -405,8 +405,8 @@ case PUT: {
|
|||
else {
|
||||
offset_value = offset.value;
|
||||
}
|
||||
reagent& value = inst.ingredients.at(2);
|
||||
reagent element = element_type(base.type, offset_value);
|
||||
const reagent& value = inst.ingredients.at(2);
|
||||
const reagent& element = element_type(base.type, offset_value);
|
||||
if (!types_coercible(element, value)) {
|
||||
raise << maybe(get(Recipe, r).name) << "'put " << base.original_string << ", " << offset.original_string << "' should store " << names_to_string_without_quotes(element.type) << " but " << value.name << " has type " << names_to_string_without_quotes(value.type) << '\n' << end();
|
||||
break;
|
||||
|
@ -415,7 +415,7 @@ case PUT: {
|
|||
}
|
||||
:(before "End Primitive Recipe Implementations")
|
||||
case PUT: {
|
||||
reagent base = current_instruction().ingredients.at(0);
|
||||
reagent/*copy*/ base = current_instruction().ingredients.at(0);
|
||||
// Update PUT base in Run
|
||||
int base_address = base.value;
|
||||
if (base_address == 0) {
|
||||
|
|
|
@ -123,7 +123,7 @@ void check_merge_calls(const recipe_ordinal r) {
|
|||
raise << maybe(caller.name) << "'merge' should yield a single product in '" << to_original_string(inst) << "'\n" << end();
|
||||
continue;
|
||||
}
|
||||
reagent product = inst.products.at(0);
|
||||
reagent/*copy*/ product = inst.products.at(0);
|
||||
// Update product While Type-checking Merge
|
||||
type_ordinal product_type = product.type->value;
|
||||
if (product_type == 0 || !contains_key(Type, product_type)) {
|
||||
|
@ -157,7 +157,7 @@ void check_merge_call(const vector<reagent>& ingredients, const reagent& product
|
|||
// degenerate case: merge with the same type always succeeds
|
||||
if (state.data.top().container_element_index == 0 && types_coercible(container, inst.ingredients.at(ingredient_index)))
|
||||
return;
|
||||
reagent expected_ingredient = element_type(container.type, state.data.top().container_element_index);
|
||||
const reagent& expected_ingredient = element_type(container.type, state.data.top().container_element_index);
|
||||
trace(9999, "transform") << "checking container " << to_string(container) << " || " << to_string(expected_ingredient) << " vs ingredient " << ingredient_index << end();
|
||||
// if the current element is the ingredient we expect, move on to the next element/ingredient
|
||||
if (types_coercible(expected_ingredient, ingredients.at(ingredient_index))) {
|
||||
|
|
28
032array.cc
28
032array.cc
|
@ -23,7 +23,7 @@ case CREATE_ARRAY: {
|
|||
raise << maybe(get(Recipe, r).name) << "'create-array' needs one product and no ingredients but got '" << to_original_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
reagent product = inst.products.at(0);
|
||||
reagent/*copy*/ product = inst.products.at(0);
|
||||
// Update CREATE_ARRAY product in Check
|
||||
if (!is_mu_array(product)) {
|
||||
raise << maybe(get(Recipe, r).name) << "'create-array' cannot create non-array " << product.original_string << '\n' << end();
|
||||
|
@ -46,7 +46,7 @@ case CREATE_ARRAY: {
|
|||
}
|
||||
:(before "End Primitive Recipe Implementations")
|
||||
case CREATE_ARRAY: {
|
||||
reagent product = current_instruction().products.at(0);
|
||||
reagent/*copy*/ product = current_instruction().products.at(0);
|
||||
// Update CREATE_ARRAY product in Run
|
||||
int base_address = product.value;
|
||||
int array_length = to_integer(product.type->right->right->name);
|
||||
|
@ -173,20 +173,20 @@ case INDEX: {
|
|||
raise << maybe(get(Recipe, r).name) << "'index' expects exactly 2 ingredients in '" << to_original_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent base = inst.ingredients.at(0);
|
||||
reagent/*copy*/ base = inst.ingredients.at(0);
|
||||
// Update INDEX base in Check
|
||||
if (!is_mu_array(base)) {
|
||||
raise << maybe(get(Recipe, r).name) << "'index' on a non-array " << base.original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
reagent index = inst.ingredients.at(1);
|
||||
reagent/*copy*/ index = inst.ingredients.at(1);
|
||||
// Update INDEX index in Check
|
||||
if (!is_mu_number(index)) {
|
||||
raise << maybe(get(Recipe, r).name) << "second ingredient of 'index' should be a number, but got " << index.original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
if (inst.products.empty()) break;
|
||||
reagent product = inst.products.at(0);
|
||||
reagent/*copy*/ product = inst.products.at(0);
|
||||
// Update INDEX product in Check
|
||||
reagent element;
|
||||
element.type = copy_array_element(base.type);
|
||||
|
@ -198,7 +198,7 @@ case INDEX: {
|
|||
}
|
||||
:(before "End Primitive Recipe Implementations")
|
||||
case INDEX: {
|
||||
reagent base = current_instruction().ingredients.at(0);
|
||||
reagent/*copy*/ base = current_instruction().ingredients.at(0);
|
||||
// Update INDEX base in Run
|
||||
int base_address = base.value;
|
||||
trace(9998, "run") << "base address is " << base_address << end();
|
||||
|
@ -206,7 +206,7 @@ case INDEX: {
|
|||
raise << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_original_string(current_instruction()) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent index = current_instruction().ingredients.at(1);
|
||||
reagent/*copy*/ index = current_instruction().ingredients.at(1);
|
||||
// Update INDEX index in Run
|
||||
vector<double> index_val(read_memory(index));
|
||||
if (index_val.at(0) < 0 || index_val.at(0) >= get_or_insert(Memory, base_address)) {
|
||||
|
@ -335,19 +335,19 @@ case PUT_INDEX: {
|
|||
raise << maybe(get(Recipe, r).name) << "'put-index' expects exactly 3 ingredients in '" << to_original_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent base = inst.ingredients.at(0);
|
||||
reagent/*copy*/ base = inst.ingredients.at(0);
|
||||
// Update PUT_INDEX base in Check
|
||||
if (!is_mu_array(base)) {
|
||||
raise << maybe(get(Recipe, r).name) << "'put-index' on a non-array " << base.original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
reagent index = inst.ingredients.at(1);
|
||||
reagent/*copy*/ index = inst.ingredients.at(1);
|
||||
// Update PUT_INDEX index in Check
|
||||
if (!is_mu_number(index)) {
|
||||
raise << maybe(get(Recipe, r).name) << "second ingredient of 'put-index' should have type 'number', but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
reagent value = inst.ingredients.at(2);
|
||||
reagent/*copy*/ value = inst.ingredients.at(2);
|
||||
// Update PUT_INDEX value in Check
|
||||
reagent element;
|
||||
element.type = copy_array_element(base.type);
|
||||
|
@ -359,14 +359,14 @@ case PUT_INDEX: {
|
|||
}
|
||||
:(before "End Primitive Recipe Implementations")
|
||||
case PUT_INDEX: {
|
||||
reagent base = current_instruction().ingredients.at(0);
|
||||
reagent/*copy*/ base = current_instruction().ingredients.at(0);
|
||||
// Update PUT_INDEX base in Run
|
||||
int base_address = base.value;
|
||||
if (base_address == 0) {
|
||||
raise << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_original_string(current_instruction()) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent index = current_instruction().ingredients.at(1);
|
||||
reagent/*copy*/ index = current_instruction().ingredients.at(1);
|
||||
// Update PUT_INDEX index in Run
|
||||
vector<double> index_val(read_memory(index));
|
||||
if (index_val.at(0) < 0 || index_val.at(0) >= get_or_insert(Memory, base_address)) {
|
||||
|
@ -441,7 +441,7 @@ case LENGTH: {
|
|||
raise << maybe(get(Recipe, r).name) << "'length' expects exactly 2 ingredients in '" << to_original_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent array = inst.ingredients.at(0);
|
||||
reagent/*copy*/ array = inst.ingredients.at(0);
|
||||
// Update LENGTH array in Check
|
||||
if (!is_mu_array(array)) {
|
||||
raise << "tried to calculate length of non-array " << array.original_string << '\n' << end();
|
||||
|
@ -451,7 +451,7 @@ case LENGTH: {
|
|||
}
|
||||
:(before "End Primitive Recipe Implementations")
|
||||
case LENGTH: {
|
||||
reagent array = current_instruction().ingredients.at(0);
|
||||
reagent/*copy*/ array = current_instruction().ingredients.at(0);
|
||||
// Update LENGTH array in Run
|
||||
if (array.value == 0) {
|
||||
raise << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_original_string(current_instruction()) << "'\n" << end();
|
||||
|
|
|
@ -42,7 +42,7 @@ if (info.kind == EXCLUSIVE_CONTAINER) {
|
|||
// (So like containers, it can't contain arrays.)
|
||||
int size = 0;
|
||||
for (int i = 0; i < SIZE(info.elements); ++i) {
|
||||
reagent element = info.elements.at(i);
|
||||
reagent/*copy*/ element = info.elements.at(i);
|
||||
// Compute Exclusive Container Metadata(element)
|
||||
compute_container_metadata(element);
|
||||
int variant_size = size_of(element);
|
||||
|
@ -98,7 +98,7 @@ case MAYBE_CONVERT: {
|
|||
raise << maybe(caller.name) << "'maybe-convert' expects exactly 2 ingredients in '" << to_original_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent base = inst.ingredients.at(0);
|
||||
reagent/*copy*/ base = inst.ingredients.at(0);
|
||||
// Update MAYBE_CONVERT base in Check
|
||||
if (!base.type || !base.type->value || get(Type, base.type->value).kind != EXCLUSIVE_CONTAINER) {
|
||||
raise << maybe(caller.name) << "first ingredient of 'maybe-convert' should be an exclusive-container, but got " << base.original_string << '\n' << end();
|
||||
|
@ -113,7 +113,7 @@ case MAYBE_CONVERT: {
|
|||
raise << maybe(caller.name) << "'maybe-convert' expects exactly 2 products in '" << to_original_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent product = inst.products.at(0);
|
||||
reagent/*copy*/ product = inst.products.at(0);
|
||||
// Update MAYBE_CONVERT product in Check
|
||||
reagent& offset = inst.ingredients.at(1);
|
||||
populate_value(offset);
|
||||
|
@ -121,12 +121,12 @@ case MAYBE_CONVERT: {
|
|||
raise << maybe(caller.name) << "invalid tag " << offset.value << " in '" << to_original_string(inst) << '\n' << end();
|
||||
break;
|
||||
}
|
||||
reagent variant = variant_type(base, offset.value);
|
||||
const reagent& variant = variant_type(base, offset.value);
|
||||
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;
|
||||
}
|
||||
reagent status = inst.products.at(1);
|
||||
reagent/*copy*/ status = inst.products.at(1);
|
||||
// Update MAYBE_CONVERT status in Check
|
||||
if (!is_mu_boolean(status)) {
|
||||
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();
|
||||
|
@ -136,7 +136,7 @@ case MAYBE_CONVERT: {
|
|||
}
|
||||
:(before "End Primitive Recipe Implementations")
|
||||
case MAYBE_CONVERT: {
|
||||
reagent base = current_instruction().ingredients.at(0);
|
||||
reagent/*copy*/ base = current_instruction().ingredients.at(0);
|
||||
// Update MAYBE_CONVERT base in Run
|
||||
int base_address = base.value;
|
||||
if (base_address == 0) {
|
||||
|
@ -144,13 +144,13 @@ case MAYBE_CONVERT: {
|
|||
break;
|
||||
}
|
||||
int tag = current_instruction().ingredients.at(1).value;
|
||||
reagent product = current_instruction().products.at(0);
|
||||
reagent/*copy*/ product = current_instruction().products.at(0);
|
||||
// Update MAYBE_CONVERT product in Run
|
||||
reagent status = current_instruction().products.at(1);
|
||||
reagent/*copy*/ status = current_instruction().products.at(1);
|
||||
// Update MAYBE_CONVERT status in Run
|
||||
// optimization: directly write results to only update first product when necessary
|
||||
if (tag == static_cast<int>(get_or_insert(Memory, base_address))) {
|
||||
const reagent variant = variant_type(base, tag);
|
||||
const reagent& variant = variant_type(base, tag);
|
||||
trace(9999, "mem") << "storing 1 in location " << status.value << end();
|
||||
put(Memory, status.value, 1);
|
||||
// Write Memory in Successful MAYBE_CONVERT in Run
|
||||
|
@ -174,7 +174,7 @@ const reagent variant_type(const reagent& base, int tag) {
|
|||
assert(!get(Type, base.type->value).name.empty());
|
||||
const type_info& info = get(Type, base.type->value);
|
||||
assert(info.kind == EXCLUSIVE_CONTAINER);
|
||||
reagent element = info.elements.at(tag);
|
||||
reagent/*copy*/ element = info.elements.at(tag);
|
||||
// End variant_type Special-cases
|
||||
return element;
|
||||
}
|
||||
|
@ -279,13 +279,13 @@ case EXCLUSIVE_CONTAINER: {
|
|||
raise << maybe(caller.name) << "ingredient " << ingredient_index << " of 'merge' should be a literal, for the tag of exclusive-container " << container_info.name << '\n' << end();
|
||||
return;
|
||||
}
|
||||
reagent ingredient = ingredients.at(ingredient_index); // unnecessary copy just to keep this function from modifying caller
|
||||
reagent/*copy*/ ingredient = ingredients.at(ingredient_index); // unnecessary copy just to keep this function from modifying caller
|
||||
populate_value(ingredient);
|
||||
if (ingredient.value >= SIZE(container_info.elements)) {
|
||||
raise << maybe(caller.name) << "invalid tag at " << ingredient_index << " for " << container_info.name << " in '" << to_original_string(inst) << '\n' << end();
|
||||
return;
|
||||
}
|
||||
reagent variant = variant_type(container, ingredient.value);
|
||||
const reagent& variant = variant_type(container, ingredient.value);
|
||||
trace(9999, "transform") << "tag: " << ingredient.value << end();
|
||||
// replace union with its variant
|
||||
state.data.pop();
|
||||
|
@ -394,7 +394,7 @@ if (current_step_index() < SIZE(Current_routine->steps())
|
|||
&& current_instruction().operation == MERGE
|
||||
&& !current_instruction().products.empty()
|
||||
&& current_instruction().products.at(0).type) {
|
||||
reagent x = current_instruction().products.at(0);
|
||||
reagent/*copy*/ x = current_instruction().products.at(0);
|
||||
// Update size_mismatch Check for MERGE(x)
|
||||
if (get(Type, x.type->value).kind == EXCLUSIVE_CONTAINER)
|
||||
return size_of(x) < SIZE(data);
|
||||
|
|
|
@ -136,7 +136,7 @@ def main [
|
|||
:(before "End Mu Types Initialization")
|
||||
put(Type_ordinal, "type", 0);
|
||||
:(code)
|
||||
bool is_mu_type_literal(reagent r) {
|
||||
bool is_mu_type_literal(const reagent& r) {
|
||||
return is_literal(r) && r.type && r.type->name == "type";
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,7 @@ case NEW: {
|
|||
break;
|
||||
}
|
||||
// End NEW Check Special-cases
|
||||
reagent type = inst.ingredients.at(0);
|
||||
const reagent& type = inst.ingredients.at(0);
|
||||
if (!is_mu_type_literal(type)) {
|
||||
raise << maybe(caller.name) << "first ingredient of 'new' should be a type, but got " << type.original_string << '\n' << end();
|
||||
break;
|
||||
|
@ -169,7 +169,7 @@ case NEW: {
|
|||
}
|
||||
:(code)
|
||||
bool product_of_new_is_valid(const instruction& inst) {
|
||||
reagent product = inst.products.at(0);
|
||||
reagent/*copy*/ product = inst.products.at(0);
|
||||
// Update NEW product in Check
|
||||
if (!product.type || product.type->value != get(Type_ordinal, "address"))
|
||||
return false;
|
||||
|
@ -179,7 +179,7 @@ bool product_of_new_is_valid(const instruction& inst) {
|
|||
if (!product.type || product.type->value != get(Type_ordinal, "array")) return false;
|
||||
drop_from_type(product, "array");
|
||||
}
|
||||
reagent expected_product("x:"+inst.ingredients.at(0).name);
|
||||
reagent/*copy*/ expected_product("x:"+inst.ingredients.at(0).name);
|
||||
// End Post-processing(expected_product) When Checking 'new'
|
||||
return types_strictly_match(product, expected_product);
|
||||
}
|
||||
|
|
30
035lookup.cc
30
035lookup.cc
|
@ -42,7 +42,7 @@ def main [
|
|||
# 1 contains 10. Skip refcount and lookup location 11.
|
||||
+mem: storing 34 in location 2
|
||||
|
||||
:(before "End Preprocess read_memory(x)")
|
||||
:(before "End Preprocess read_memory(reagent x)")
|
||||
canonize(x);
|
||||
|
||||
//: similarly, write to addresses pointing at other locations using the
|
||||
|
@ -54,7 +54,7 @@ def main [
|
|||
]
|
||||
+mem: storing 34 in location 11
|
||||
|
||||
:(before "End Preprocess write_memory(x)")
|
||||
:(before "End Preprocess write_memory(reagent x, vector<double> data)")
|
||||
canonize(x);
|
||||
if (x.value == 0) {
|
||||
raise << "can't write to location 0 in '" << to_original_string(current_instruction()) << "'\n" << end();
|
||||
|
@ -117,20 +117,20 @@ void test_lookup_zero_address_does_not_skip_refcount() {
|
|||
CHECK_EQ(x.value, 0);
|
||||
}
|
||||
|
||||
:(after "bool types_strictly_match(reagent to, reagent from)")
|
||||
if (!canonize_type(to)) return false;
|
||||
if (!canonize_type(from)) return false;
|
||||
:(before "End Preprocess types_strictly_match(reagent to, reagent from)")
|
||||
if (!canonize_type(to)) return false;
|
||||
if (!canonize_type(from)) return false;
|
||||
|
||||
:(after "bool is_mu_array(reagent r)")
|
||||
if (!canonize_type(r)) return false;
|
||||
:(before "End Preprocess is_mu_array(reagent r)")
|
||||
if (!canonize_type(r)) return false;
|
||||
|
||||
:(after "bool is_mu_address(reagent r)")
|
||||
if (!canonize_type(r)) return false;
|
||||
:(before "End Preprocess is_mu_address(reagent r)")
|
||||
if (!canonize_type(r)) return false;
|
||||
|
||||
:(after "bool is_mu_number(reagent r)")
|
||||
if (!canonize_type(r)) return false;
|
||||
:(after "bool is_mu_boolean(reagent r)")
|
||||
if (!canonize_type(r)) return false;
|
||||
:(before "End Preprocess is_mu_number(reagent r)")
|
||||
if (!canonize_type(r)) return false;
|
||||
:(before "End Preprocess is_mu_boolean(reagent r)")
|
||||
if (!canonize_type(r)) return false;
|
||||
|
||||
:(after "Update product While Type-checking Merge")
|
||||
if (!canonize_type(product)) continue;
|
||||
|
@ -431,7 +431,7 @@ _DUMP,
|
|||
put(Recipe_ordinal, "$dump", _DUMP);
|
||||
:(before "End Primitive Recipe Implementations")
|
||||
case _DUMP: {
|
||||
reagent after_canonize = current_instruction().ingredients.at(0);
|
||||
reagent/*copy*/ after_canonize = current_instruction().ingredients.at(0);
|
||||
canonize(after_canonize);
|
||||
cerr << maybe(current_recipe_name()) << current_instruction().ingredients.at(0).name << ' ' << no_scientific(current_instruction().ingredients.at(0).value) << " => " << no_scientific(after_canonize.value) << " => " << no_scientific(get_or_insert(Memory, after_canonize.value)) << '\n';
|
||||
break;
|
||||
|
@ -452,7 +452,7 @@ case _BAR: {
|
|||
else cerr << '\n';
|
||||
}
|
||||
else {
|
||||
reagent tmp = current_instruction().ingredients.at(0);
|
||||
reagent/*copy*/ tmp = current_instruction().ingredients.at(0);
|
||||
canonize(tmp);
|
||||
Bar = tmp.value;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ void update_refcounts(int old_address, int new_address, int size) {
|
|||
}
|
||||
}
|
||||
|
||||
int payload_size(/*copy*/ reagent x) {
|
||||
int payload_size(reagent/*copy*/ x) {
|
||||
// lookup_memory without drop_one_lookup
|
||||
if (x.value)
|
||||
x.set_value(get_or_insert(Memory, x.value)+/*skip refcount*/1);
|
||||
|
@ -113,7 +113,7 @@ def main [
|
|||
+mem: incrementing refcount of 1000: 1 -> 2
|
||||
|
||||
:(after "Write Memory in PUT in Run")
|
||||
reagent element = element_type(base.type, offset);
|
||||
reagent/*copy*/ element = element_type(base.type, offset);
|
||||
assert(!has_property(element, "lookup"));
|
||||
element.value = address;
|
||||
if (is_mu_address(element))
|
||||
|
|
|
@ -12,7 +12,7 @@ case TO_LOCATION_ARRAY: {
|
|||
break;
|
||||
}
|
||||
:(code)
|
||||
bool is_address_of_array_of_numbers(reagent product) {
|
||||
bool is_address_of_array_of_numbers(reagent/*copy*/ product) {
|
||||
canonize_type(product);
|
||||
if (!product.type || product.type->value != get(Type_ordinal, "address")) return false;
|
||||
drop_from_type(product, "address");
|
||||
|
|
|
@ -419,7 +419,7 @@ if (curr.name == "return-unless" || curr.name == "reply-unless") {
|
|||
|
||||
:(code)
|
||||
void emit_return_block(recipe& out, const string& break_command, const vector<reagent>& ingredients) {
|
||||
reagent condition = ingredients.at(0);
|
||||
reagent/*copy*/ condition = ingredients.at(0);
|
||||
vector<reagent> return_ingredients;
|
||||
copy(++ingredients.begin(), ingredients.end(), inserter(return_ingredients, return_ingredients.end()));
|
||||
|
||||
|
|
66
043space.cc
66
043space.cc
|
@ -82,21 +82,21 @@ int address(int offset, int base) {
|
|||
|
||||
//:: reads and writes to the 'default-space' variable have special behavior
|
||||
|
||||
:(after "void write_memory(reagent x, const vector<double>& data)")
|
||||
if (x.name == "default-space") {
|
||||
if (!scalar(data)
|
||||
|| !x.type
|
||||
|| x.type->value != get(Type_ordinal, "address")
|
||||
|| !x.type->right
|
||||
|| x.type->right->value != get(Type_ordinal, "array")
|
||||
|| !x.type->right->right
|
||||
|| x.type->right->right->value != get(Type_ordinal, "location")
|
||||
|| x.type->right->right->right) {
|
||||
raise << maybe(current_recipe_name()) << "'default-space' should be of type address:array:location, but tried to write " << to_string(data) << '\n' << end();
|
||||
}
|
||||
current_call().default_space = data.at(0);
|
||||
return;
|
||||
:(after "Begin Preprocess write_memory(reagent x, vector<double> data)")
|
||||
if (x.name == "default-space") {
|
||||
if (!scalar(data)
|
||||
|| !x.type
|
||||
|| x.type->value != get(Type_ordinal, "address")
|
||||
|| !x.type->right
|
||||
|| x.type->right->value != get(Type_ordinal, "array")
|
||||
|| !x.type->right->right
|
||||
|| x.type->right->right->value != get(Type_ordinal, "location")
|
||||
|| x.type->right->right->right) {
|
||||
raise << maybe(current_recipe_name()) << "'default-space' should be of type address:array:location, but tried to write " << to_string(data) << '\n' << end();
|
||||
}
|
||||
current_call().default_space = data.at(0);
|
||||
return;
|
||||
}
|
||||
|
||||
:(scenario get_default_space)
|
||||
def main [
|
||||
|
@ -105,12 +105,12 @@ def main [
|
|||
]
|
||||
+mem: storing 10 in location 1
|
||||
|
||||
:(after "vector<double> read_memory(reagent x)")
|
||||
if (x.name == "default-space") {
|
||||
vector<double> result;
|
||||
result.push_back(current_call().default_space);
|
||||
return result;
|
||||
}
|
||||
:(after "Begin Preprocess read_memory(reagent x)")
|
||||
if (x.name == "default-space") {
|
||||
vector<double> result;
|
||||
result.push_back(current_call().default_space);
|
||||
return result;
|
||||
}
|
||||
|
||||
//:: fix 'get'
|
||||
|
||||
|
@ -178,19 +178,19 @@ if (s == "number-of-locals") return true;
|
|||
if (curr.name == "new-default-space") {
|
||||
rewrite_default_space_instruction(curr);
|
||||
}
|
||||
:(after "vector<double> read_memory(reagent x)")
|
||||
if (x.name == "number-of-locals") {
|
||||
vector<double> result;
|
||||
result.push_back(Name[get(Recipe_ordinal, current_recipe_name())][""]);
|
||||
if (result.back() == 0)
|
||||
raise << "no space allocated for default-space in recipe " << current_recipe_name() << "; are you using names?\n" << end();
|
||||
return result;
|
||||
}
|
||||
:(after "void write_memory(reagent x, const vector<double>& data)")
|
||||
if (x.name == "number-of-locals") {
|
||||
raise << maybe(current_recipe_name()) << "can't write to special name 'number-of-locals'\n" << end();
|
||||
return;
|
||||
}
|
||||
:(after "Begin Preprocess read_memory(reagent x)")
|
||||
if (x.name == "number-of-locals") {
|
||||
vector<double> result;
|
||||
result.push_back(Name[get(Recipe_ordinal, current_recipe_name())][""]);
|
||||
if (result.back() == 0)
|
||||
raise << "no space allocated for default-space in recipe " << current_recipe_name() << "; are you using names?\n" << end();
|
||||
return result;
|
||||
}
|
||||
:(after "Begin Preprocess write_memory(reagent x, vector<double> data)")
|
||||
if (x.name == "number-of-locals") {
|
||||
raise << maybe(current_recipe_name()) << "can't write to special name 'number-of-locals'\n" << end();
|
||||
return;
|
||||
}
|
||||
|
||||
//:: a little hook to automatically reclaim the default-space when returning
|
||||
//:: from a recipe
|
||||
|
|
32
046global.cc
32
046global.cc
|
@ -40,23 +40,23 @@ if (s == "global-space") return true;
|
|||
int global_space;
|
||||
:(before "End routine Constructor")
|
||||
global_space = 0;
|
||||
:(after "void write_memory(reagent x, const vector<double>& data)")
|
||||
if (x.name == "global-space") {
|
||||
if (!scalar(data)
|
||||
|| !x.type
|
||||
|| x.type->value != get(Type_ordinal, "address")
|
||||
|| !x.type->right
|
||||
|| x.type->right->value != get(Type_ordinal, "array")
|
||||
|| !x.type->right->right
|
||||
|| x.type->right->right->value != get(Type_ordinal, "location")
|
||||
|| x.type->right->right->right) {
|
||||
raise << maybe(current_recipe_name()) << "'global-space' should be of type address:array:location, but tried to write " << to_string(data) << '\n' << end();
|
||||
}
|
||||
if (Current_routine->global_space)
|
||||
raise << "routine already has a global-space; you can't over-write your globals" << end();
|
||||
Current_routine->global_space = data.at(0);
|
||||
return;
|
||||
:(after "Begin Preprocess write_memory(reagent x, vector<double> data)")
|
||||
if (x.name == "global-space") {
|
||||
if (!scalar(data)
|
||||
|| !x.type
|
||||
|| x.type->value != get(Type_ordinal, "address")
|
||||
|| !x.type->right
|
||||
|| x.type->right->value != get(Type_ordinal, "array")
|
||||
|| !x.type->right->right
|
||||
|| x.type->right->right->value != get(Type_ordinal, "location")
|
||||
|| x.type->right->right->right) {
|
||||
raise << maybe(current_recipe_name()) << "'global-space' should be of type address:array:location, but tried to write " << to_string(data) << '\n' << end();
|
||||
}
|
||||
if (Current_routine->global_space)
|
||||
raise << "routine already has a global-space; you can't over-write your globals" << end();
|
||||
Current_routine->global_space = data.at(0);
|
||||
return;
|
||||
}
|
||||
|
||||
//: now marking variables as /space:global looks them up inside this field
|
||||
:(after "int space_base(const reagent& x)")
|
||||
|
|
|
@ -162,7 +162,7 @@ bool any_type_ingredient_in_header(recipe_ordinal variant) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool concrete_type_names_strictly_match(reagent to, reagent from) {
|
||||
bool concrete_type_names_strictly_match(reagent/*copy*/ to, reagent/*copy*/ from) {
|
||||
canonize_type(to);
|
||||
canonize_type(from);
|
||||
return concrete_type_names_strictly_match(to.type, from.type, from);
|
||||
|
@ -293,7 +293,7 @@ void compute_type_ingredient_mappings(const recipe& exemplar, const instruction&
|
|||
int limit = min(SIZE(inst.ingredients), SIZE(exemplar.ingredients));
|
||||
for (int i = 0; i < limit; ++i) {
|
||||
const reagent& exemplar_reagent = exemplar.ingredients.at(i);
|
||||
reagent ingredient = inst.ingredients.at(i);
|
||||
reagent/*copy*/ ingredient = inst.ingredients.at(i);
|
||||
canonize_type(ingredient);
|
||||
if (is_mu_address(exemplar_reagent) && ingredient.name == "0") continue; // assume it matches
|
||||
accumulate_type_ingredients(exemplar_reagent, ingredient, mappings, exemplar, inst, caller_recipe, error);
|
||||
|
@ -301,7 +301,7 @@ void compute_type_ingredient_mappings(const recipe& exemplar, const instruction&
|
|||
limit = min(SIZE(inst.products), SIZE(exemplar.products));
|
||||
for (int i = 0; i < limit; ++i) {
|
||||
const reagent& exemplar_reagent = exemplar.products.at(i);
|
||||
reagent product = inst.products.at(i);
|
||||
reagent/*copy*/ product = inst.products.at(i);
|
||||
if (is_dummy(product)) continue;
|
||||
canonize_type(product);
|
||||
accumulate_type_ingredients(exemplar_reagent, product, mappings, exemplar, inst, caller_recipe, error);
|
||||
|
|
|
@ -143,7 +143,7 @@ recipe from_reagent(const reagent& r) {
|
|||
return result_header;
|
||||
}
|
||||
|
||||
bool is_mu_recipe(reagent r) {
|
||||
bool is_mu_recipe(const reagent& r) {
|
||||
if (!r.type) return false;
|
||||
if (r.type->name == "recipe") return true;
|
||||
if (r.type->name == "recipe-literal") return true;
|
||||
|
|
|
@ -168,7 +168,7 @@ case START_RUNNING: {
|
|||
// populate ingredients
|
||||
for (int i = 1; i < SIZE(current_instruction().ingredients); ++i) {
|
||||
new_routine->calls.front().ingredient_atoms.push_back(ingredients.at(i));
|
||||
reagent ingredient = current_instruction().ingredients.at(i);
|
||||
reagent/*copy*/ ingredient = current_instruction().ingredients.at(i);
|
||||
canonize_type(ingredient);
|
||||
new_routine->calls.front().ingredients.push_back(ingredient);
|
||||
}
|
||||
|
|
|
@ -112,14 +112,14 @@ case GET_LOCATION: {
|
|||
raise << maybe(get(Recipe, r).name) << "'get-location' expects exactly 2 ingredients in '" << to_original_string(inst) << "'\n" << end();
|
||||
break;
|
||||
}
|
||||
reagent base = inst.ingredients.at(0);
|
||||
reagent/*copy*/ base = inst.ingredients.at(0);
|
||||
if (!canonize_type(base)) break;
|
||||
if (!base.type || !base.type->value || !contains_key(Type, base.type->value) || get(Type, base.type->value).kind != CONTAINER) {
|
||||
raise << maybe(get(Recipe, r).name) << "first ingredient of 'get-location' should be a container, but got " << inst.ingredients.at(0).original_string << '\n' << end();
|
||||
break;
|
||||
}
|
||||
type_ordinal base_type = base.type->value;
|
||||
reagent offset = inst.ingredients.at(1);
|
||||
const reagent& offset = inst.ingredients.at(1);
|
||||
if (!is_literal(offset) || !is_mu_scalar(offset)) {
|
||||
raise << maybe(get(Recipe, r).name) << "second ingredient of 'get-location' should have type 'offset', but got " << inst.ingredients.at(1).original_string << '\n' << end();
|
||||
break;
|
||||
|
@ -144,7 +144,7 @@ case GET_LOCATION: {
|
|||
}
|
||||
:(before "End Primitive Recipe Implementations")
|
||||
case GET_LOCATION: {
|
||||
reagent base = current_instruction().ingredients.at(0);
|
||||
reagent/*copy*/ base = current_instruction().ingredients.at(0);
|
||||
canonize(base);
|
||||
int base_address = base.value;
|
||||
if (base_address == 0) {
|
||||
|
@ -164,7 +164,7 @@ case GET_LOCATION: {
|
|||
}
|
||||
|
||||
:(code)
|
||||
bool is_mu_location(reagent x) {
|
||||
bool is_mu_location(reagent/*copy*/ x) {
|
||||
if (!canonize_type(x)) return false;
|
||||
if (!x.type) return false;
|
||||
if (x.type->right) return false;
|
||||
|
|
|
@ -61,7 +61,7 @@ void rewrite_stashes_to_text(recipe& caller) {
|
|||
instruction def;
|
||||
if (is_lookup_of_address_of_array(inst.ingredients.at(j))) {
|
||||
def.name = "array-to-text-line";
|
||||
reagent tmp = inst.ingredients.at(j);
|
||||
reagent/*copy*/ tmp = inst.ingredients.at(j);
|
||||
drop_one_lookup(tmp);
|
||||
def.ingredients.push_back(tmp);
|
||||
}
|
||||
|
@ -84,13 +84,13 @@ void rewrite_stashes_to_text(recipe& caller) {
|
|||
caller.steps.swap(new_instructions);
|
||||
}
|
||||
|
||||
bool is_lookup_of_address_of_array(reagent x) {
|
||||
bool is_lookup_of_address_of_array(reagent/*copy*/ x) {
|
||||
if (x.type->name != "address") return false;
|
||||
if (!canonize_type(x)) return false;
|
||||
return x.type->name == "array";
|
||||
}
|
||||
|
||||
bool is_static_array(reagent x) {
|
||||
bool is_static_array(const reagent& x) {
|
||||
// no canonize_type()
|
||||
return x.type->name == "array";
|
||||
}
|
||||
|
|
10
078hash.cc
10
078hash.cc
|
@ -22,7 +22,7 @@ case HASH: {
|
|||
}
|
||||
:(before "End Primitive Recipe Implementations")
|
||||
case HASH: {
|
||||
reagent input = current_instruction().ingredients.at(0); // copy
|
||||
reagent/*copy*/ input = current_instruction().ingredients.at(0);
|
||||
products.resize(1);
|
||||
products.at(0).push_back(hash(0, input));
|
||||
break;
|
||||
|
@ -76,11 +76,11 @@ size_t hash_mu_string(size_t h, const reagent& r) {
|
|||
|
||||
size_t hash_mu_array(size_t h, const reagent& r) {
|
||||
int size = get_or_insert(Memory, r.value);
|
||||
reagent elem = r;
|
||||
reagent/*copy*/ elem = r;
|
||||
delete elem.type;
|
||||
elem.type = copy_array_element(r.type);
|
||||
for (int i=0, address = r.value+1; i < size; ++i, address += size_of(elem)) {
|
||||
reagent tmp = elem;
|
||||
reagent/*copy*/ tmp = elem;
|
||||
tmp.value = address;
|
||||
h = hash(h, tmp);
|
||||
//? cerr << i << " (" << address << "): " << h << '\n';
|
||||
|
@ -100,7 +100,7 @@ size_t hash_mu_container(size_t h, const reagent& r) {
|
|||
int address = r.value;
|
||||
int offset = 0;
|
||||
for (int i = 0; i < SIZE(info.elements); ++i) {
|
||||
reagent element = element_type(r.type, i);
|
||||
reagent/*copy*/ element = element_type(r.type, i);
|
||||
if (has_property(element, "ignore-for-hash")) continue;
|
||||
element.set_value(address+offset);
|
||||
h = hash(h, element);
|
||||
|
@ -119,7 +119,7 @@ bool is_mu_exclusive_container(const reagent& r) {
|
|||
size_t hash_mu_exclusive_container(size_t h, const reagent& r) {
|
||||
assert(r.type->value);
|
||||
int tag = get(Memory, r.value);
|
||||
reagent variant = variant_type(r, tag);
|
||||
reagent/*copy*/ variant = variant_type(r, tag);
|
||||
// todo: move this error to container definition time
|
||||
if (has_property(variant, "ignore-for-hash"))
|
||||
raise << get(Type, r.type->value).name << ": /ignore-for-hash won't work in exclusive containers\n" << end();
|
||||
|
|
Loading…
Reference in New Issue