diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-05-07 15:06:53 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-05-07 15:29:13 -0700 |
commit | 0487a30e7078861ed7de42bdb21b5c71fb9b54a1 (patch) | |
tree | f7ccc4040b510403da90477947c1cf07ea91b627 /030container.cc | |
parent | 94fa5c95ad9c8beead183bb7c4b88c7c2c7ca6ec (diff) | |
download | mu-0487a30e7078861ed7de42bdb21b5c71fb9b54a1.tar.gz |
1298 - better ingredient/product handling
All primitives now always write to all their products. If a product is not used that's fine, but if an instruction seems to expect too many products mu will complain. In the process, many primitives can operate on more than two ingredients where it seems intuitive. You can add or divide more than two numbers together, copy or negate multiple corresponding locations, etc. There's one remaining bit of ugliness. Some instructions like get/get-address, index/index-address, wait-for-location, these can unnecessarily load values from memory when they don't need to. Useful vim commands: %s/ingredients\[\([^\]]*\)\]/ingredients.at(\1)/gc %s/products\[\([^\]]*\)\]/products.at(\1)/gc .,$s/\[\(.\)]/.at(\1)/gc
Diffstat (limited to '030container.cc')
-rw-r--r-- | 030container.cc | 82 |
1 files changed, 52 insertions, 30 deletions
diff --git a/030container.cc b/030container.cc index 9de3aad7..071e3ea5 100644 --- a/030container.cc +++ b/030container.cc @@ -11,9 +11,10 @@ i.push_back(integer); Type[point].elements.push_back(i); Type[point].elements.push_back(i); +//: Containers can be copied around with a single instruction just like +//: integers, no matter how large they are. + :(scenario copy_multiple_locations) -# Containers can be copied around with a single instruction just like integers, -# no matter how large they are. recipe main [ 1:integer <- copy 34:literal 2:integer <- copy 35:literal @@ -48,13 +49,40 @@ recipe main [ ] +mem: storing 36 in location 17 +//: Containers can be checked for equality with a single instruction just like +//: integers, no matter how large they are. + +:(scenario compare_multiple_locations) +recipe main [ + 1:integer <- copy 34:literal # first + 2:integer <- copy 35:literal + 3:integer <- copy 36:literal + 4:integer <- copy 34:literal # second + 5:integer <- copy 35:literal + 6:integer <- copy 36:literal + 7:boolean <- equal 1:point-integer, 4:point-integer +] ++mem: storing 1 in location 7 + +:(scenario compare_multiple_locations2) +recipe main [ + 1:integer <- copy 34:literal # first + 2:integer <- copy 35:literal + 3:integer <- copy 36:literal + 4:integer <- copy 34:literal # second + 5:integer <- copy 35:literal + 6:integer <- copy 37:literal # different + 7:boolean <- equal 1:point-integer, 4:point-integer +] ++mem: storing 0 in location 7 + :(before "End size_of(types) Cases") -type_info t = Type[types[0]]; +type_info t = Type[types.at(0)]; if (t.kind == container) { // size of a container is the sum of the sizes of its elements size_t result = 0; for (index_t i = 0; i < t.elements.size(); ++i) { - result += size_of(t.elements[i]); + result += size_of(t.elements.at(i)); } return result; } @@ -72,7 +100,7 @@ recipe main [ +run: address to copy is 13 +run: its type is 1 +mem: location 13 is 35 -+run: product 0 is 35 ++run: product 0 is 15 +mem: storing 35 in location 15 :(before "End Primitive Recipe Declarations") @@ -81,29 +109,26 @@ GET, Recipe_number["get"] = GET; :(before "End Primitive Recipe Implementations") case GET: { - trace("run") << "ingredient 0 is " << current_instruction().ingredients[0].name; - reagent base = current_instruction().ingredients[0]; + reagent base = current_instruction().ingredients.at(0); index_t base_address = base.value; - type_number base_type = base.types[0]; + type_number base_type = base.types.at(0); assert(Type[base_type].kind == container); - trace("run") << "ingredient 1 is " << current_instruction().ingredients[1].name; - assert(isa_literal(current_instruction().ingredients[1])); - index_t offset = current_instruction().ingredients[1].value; + assert(isa_literal(current_instruction().ingredients.at(1))); + assert(ingredients.at(1).size() == 1); // scalar + index_t offset = ingredients.at(1).at(0); index_t src = base_address; for (index_t i = 0; i < offset; ++i) { - src += size_of(Type[base_type].elements[i]); + src += size_of(Type[base_type].elements.at(i)); } trace("run") << "address to copy is " << src; assert(Type[base_type].kind == container); assert(Type[base_type].elements.size() > offset); - type_number src_type = Type[base_type].elements[offset][0]; + type_number src_type = Type[base_type].elements[offset].at(0); trace("run") << "its type is " << src_type; reagent tmp; tmp.set_value(src); tmp.types.push_back(src_type); - vector<long long int> result(read_memory(tmp)); - trace("run") << "product 0 is " << result[0]; - write_memory(current_instruction().products[0], result); + products.push_back(read_memory(tmp)); break; } @@ -125,7 +150,7 @@ recipe main [ +run: address to copy is 14 +run: its type is 1 +mem: location 14 is 36 -+run: product 0 is 36 ++run: product 0 is 15 +mem: storing 36 in location 15 //:: To write to elements of containers, you need their address. @@ -148,22 +173,19 @@ GET_ADDRESS, Recipe_number["get-address"] = GET_ADDRESS; :(before "End Primitive Recipe Implementations") case GET_ADDRESS: { - trace("run") << "ingredient 0 is " << current_instruction().ingredients[0].name; - reagent base = current_instruction().ingredients[0]; + reagent base = current_instruction().ingredients.at(0); index_t base_address = base.value; - type_number base_type = base.types[0]; + type_number base_type = base.types.at(0); assert(Type[base_type].kind == container); - trace("run") << "ingredient 1 is " << current_instruction().ingredients[1].name; - assert(isa_literal(current_instruction().ingredients[1])); - index_t offset = current_instruction().ingredients[1].value; - index_t src = base_address; + assert(isa_literal(current_instruction().ingredients.at(1))); + assert(ingredients.at(1).size() == 1); // scalar + index_t offset = ingredients.at(1).at(0); + index_t result = base_address; for (index_t i = 0; i < offset; ++i) { - src += size_of(Type[base_type].elements[i]); + result += size_of(Type[base_type].elements.at(i)); } - trace("run") << "address to copy is " << src; - vector<long long int> result; - result.push_back(src); - trace("run") << "product 0 is " << result[0]; - write_memory(current_instruction().products[0], result); + trace("run") << "address to copy is " << result; + products.resize(1); + products.at(0).push_back(result); break; } |