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 /021arithmetic.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 '021arithmetic.cc')
-rw-r--r-- | 021arithmetic.cc | 139 |
1 files changed, 71 insertions, 68 deletions
diff --git a/021arithmetic.cc b/021arithmetic.cc index e9496248..307bcb18 100644 --- a/021arithmetic.cc +++ b/021arithmetic.cc @@ -6,16 +6,13 @@ ADD, Recipe_number["add"] = ADD; :(before "End Primitive Recipe Implementations") case ADD: { - trace("run") << "ingredient 0 is " << current_instruction().ingredients[0].name; - vector<long long int> arg0 = read_memory(current_instruction().ingredients[0]); - assert(arg0.size() == 1); - trace("run") << "ingredient 1 is " << current_instruction().ingredients[1].name; - vector<long long int> arg1 = read_memory(current_instruction().ingredients[1]); - assert(arg1.size() == 1); - vector<long long int> result; - result.push_back(arg0[0] + arg1[0]); - trace("run") << "product 0 is " << result[0]; - write_memory(current_instruction().products[0], result); + long long int result = 0; + for (index_t i = 0; i < ingredients.size(); ++i) { + assert(ingredients.at(i).size() == 1); // scalar + result += ingredients.at(i).at(0); + } + products.resize(1); + products.at(0).push_back(result); break; } @@ -26,7 +23,7 @@ recipe main [ +run: instruction main/0 +run: ingredient 0 is 23 +run: ingredient 1 is 34 -+run: product 0 is 57 ++run: product 0 is 1 +mem: storing 57 in location 1 :(scenario add) @@ -40,25 +37,29 @@ recipe main [ +mem: location 1 is 23 +run: ingredient 1 is 2 +mem: location 2 is 34 -+run: product 0 is 57 ++run: product 0 is 3 +mem: storing 57 in location 3 +:(scenario add_multiple) +recipe main [ + 1:integer <- add 3:literal, 4:literal, 5:literal +] ++mem: storing 12 in location 1 + :(before "End Primitive Recipe Declarations") SUBTRACT, :(before "End Primitive Recipe Numbers") Recipe_number["subtract"] = SUBTRACT; :(before "End Primitive Recipe Implementations") case SUBTRACT: { - trace("run") << "ingredient 0 is " << current_instruction().ingredients[0].name; - vector<long long int> arg0 = read_memory(current_instruction().ingredients[0]); - assert(arg0.size() == 1); - trace("run") << "ingredient 1 is " << current_instruction().ingredients[1].name; - vector<long long int> arg1 = read_memory(current_instruction().ingredients[1]); - assert(arg1.size() == 1); - vector<long long int> result; - result.push_back(arg0[0] - arg1[0]); - trace("run") << "product 0 is " << result[0]; - write_memory(current_instruction().products[0], result); + assert(ingredients.at(0).size() == 1); // scalar + long long int result = ingredients.at(0).at(0); + for (index_t i = 1; i < ingredients.size(); ++i) { + assert(ingredients.at(i).size() == 1); // scalar + result -= ingredients.at(i).at(0); + } + products.resize(1); + products.at(0).push_back(result); break; } @@ -69,7 +70,7 @@ recipe main [ +run: instruction main/0 +run: ingredient 0 is 5 +run: ingredient 1 is 2 -+run: product 0 is 3 ++run: product 0 is 1 +mem: storing 3 in location 1 :(scenario subtract) @@ -83,26 +84,28 @@ recipe main [ +mem: location 1 is 23 +run: ingredient 1 is 2 +mem: location 2 is 34 -+run: product 0 is -11 ++run: product 0 is 3 +mem: storing -11 in location 3 +:(scenario subtract_multiple) +recipe main [ + 1:integer <- subtract 6:literal, 3:literal, 2:literal +] ++mem: storing 1 in location 1 + :(before "End Primitive Recipe Declarations") MULTIPLY, :(before "End Primitive Recipe Numbers") Recipe_number["multiply"] = MULTIPLY; :(before "End Primitive Recipe Implementations") case MULTIPLY: { - trace("run") << "ingredient 0 is " << current_instruction().ingredients[0].name; - vector<long long int> arg0 = read_memory(current_instruction().ingredients[0]); - assert(arg0.size() == 1); - trace("run") << "ingredient 1 is " << current_instruction().ingredients[1].name; - vector<long long int> arg1 = read_memory(current_instruction().ingredients[1]); - assert(arg1.size() == 1); - trace("run") << "ingredient 1 is " << arg1[0]; - vector<long long int> result; - result.push_back(arg0[0] * arg1[0]); - trace("run") << "product 0 is " << result[0]; - write_memory(current_instruction().products[0], result); + long long int result = 1; + for (index_t i = 0; i < ingredients.size(); ++i) { + assert(ingredients.at(i).size() == 1); // scalar + result *= ingredients.at(i).at(0); + } + products.resize(1); + products.at(0).push_back(result); break; } @@ -113,7 +116,7 @@ recipe main [ +run: instruction main/0 +run: ingredient 0 is 2 +run: ingredient 1 is 3 -+run: product 0 is 6 ++run: product 0 is 1 +mem: storing 6 in location 1 :(scenario multiply) @@ -127,26 +130,29 @@ recipe main [ +mem: location 1 is 4 +run: ingredient 1 is 2 +mem: location 2 is 6 -+run: product 0 is 24 ++run: product 0 is 3 +mem: storing 24 in location 3 +:(scenario multiply_multiple) +recipe main [ + 1:integer <- multiply 2:literal, 3:literal, 4:literal +] ++mem: storing 24 in location 1 + :(before "End Primitive Recipe Declarations") DIVIDE, :(before "End Primitive Recipe Numbers") Recipe_number["divide"] = DIVIDE; :(before "End Primitive Recipe Implementations") case DIVIDE: { - trace("run") << "ingredient 0 is " << current_instruction().ingredients[0].name; - vector<long long int> arg0 = read_memory(current_instruction().ingredients[0]); - assert(arg0.size() == 1); - trace("run") << "ingredient 1 is " << current_instruction().ingredients[1].name; - vector<long long int> arg1 = read_memory(current_instruction().ingredients[1]); - assert(arg1.size() == 1); - trace("run") << "ingredient 1 is " << arg1[0]; - vector<long long int> result; - result.push_back(arg0[0] / arg1[0]); - trace("run") << "product 0 is " << result[0]; - write_memory(current_instruction().products[0], result); + assert(ingredients.at(0).size() == 1); // scalar + long long int result = ingredients.at(0).at(0); + for (index_t i = 1; i < ingredients.size(); ++i) { + assert(ingredients.at(i).size() == 1); // scalar + result /= ingredients.at(i).at(0); + } + products.resize(1); + products.at(0).push_back(result); break; } @@ -157,7 +163,7 @@ recipe main [ +run: instruction main/0 +run: ingredient 0 is 8 +run: ingredient 1 is 2 -+run: product 0 is 4 ++run: product 0 is 1 +mem: storing 4 in location 1 :(scenario divide) @@ -171,29 +177,26 @@ recipe main [ +mem: location 1 is 27 +run: ingredient 1 is 2 +mem: location 2 is 3 -+run: product 0 is 9 ++run: product 0 is 3 +mem: storing 9 in location 3 +:(scenario divide_multiple) +recipe main [ + 1:integer <- divide 12:literal, 3:literal, 2:literal +] ++mem: storing 2 in location 1 + :(before "End Primitive Recipe Declarations") DIVIDE_WITH_REMAINDER, :(before "End Primitive Recipe Numbers") Recipe_number["divide-with-remainder"] = DIVIDE_WITH_REMAINDER; :(before "End Primitive Recipe Implementations") case DIVIDE_WITH_REMAINDER: { - trace("run") << "ingredient 0 is " << current_instruction().ingredients[0].name; - vector<long long int> arg0 = read_memory(current_instruction().ingredients[0]); - assert(arg0.size() == 1); - trace("run") << "ingredient 1 is " << current_instruction().ingredients[1].name; - vector<long long int> arg1 = read_memory(current_instruction().ingredients[1]); - assert(arg1.size() == 1); - vector<long long int> result0; - result0.push_back(arg0[0] / arg1[0]); - trace("run") << "product 0 is " << result0[0]; - write_memory(current_instruction().products[0], result0); - vector<long long int> result1; - result1.push_back(arg0[0] % arg1[0]); - trace("run") << "product 1 is " << result1[0]; - write_memory(current_instruction().products[1], result1); + long long int quotient = ingredients.at(0).at(0) / ingredients.at(1).at(0); + long long int remainder = ingredients.at(0).at(0) % ingredients.at(1).at(0); + products.resize(2); + products.at(0).push_back(quotient); + products.at(1).push_back(remainder); break; } @@ -204,9 +207,9 @@ recipe main [ +run: instruction main/0 +run: ingredient 0 is 9 +run: ingredient 1 is 2 -+run: product 0 is 4 ++run: product 0 is 1 +mem: storing 4 in location 1 -+run: product 1 is 1 ++run: product 1 is 2 +mem: storing 1 in location 2 :(scenario divide_with_remainder) @@ -220,7 +223,7 @@ recipe main [ +mem: location 1 is 27 +run: ingredient 1 is 2 +mem: location 2 is 11 -+run: product 0 is 2 ++run: product 0 is 3 +mem: storing 2 in location 3 -+run: product 1 is 5 ++run: product 1 is 4 +mem: storing 5 in location 4 |