:(scenarios run) :(scenario copy_literal) recipe main [ 1:integer <- copy 23:literal ] +run: instruction 0 +run: ingredient 0 is 23 +mem: storing in location 1 :(scenario copy) recipe main [ 1:integer <- copy 23:literal 2:integer <- copy 1:integer ] +run: instruction 1 +run: ingredient 0 is 1 +mem: location 1 is 23 +mem: storing in location 2 :(code) void run(string form) { run(add_recipe(form)); } void run(recipe_number r) { vector& instructions(Recipe[r].steps); int n = 0; vector::iterator p; for (n = 0, p = instructions.begin(); p != instructions.end(); ++p, ++n) { trace("run") << "instruction " << n; switch (p->operation) { // Primitive Recipe Implementations. case 1: { // copy trace("run") << "ingredient 0 is " << p->ingredients[0].name; vector data = read_memory(p->ingredients[0]); write_memory(p->products[0], data); break; } // End Primitive Recipe Implementations. default: raise << "undefined operation " << p->operation; } } } vector read_memory(reagent x) { vector result; if (x.types[0] == 0) { // literal result.push_back(to_int(x.name)); return result; } int val = Memory[to_int(x.name)]; trace("mem") << "location " << x.name << " is " << val; result.push_back(val); return result; } void write_memory(reagent x, vector data) { int dest = to_int(x.name); trace("mem") << "storing in location " << dest; Memory[dest] = data[0]; } :(before "End Primitive Recipe Numbers") // Arithmetic ops. Recipe_number["add"] = 2; Next_recipe_number++; Recipe_number["subtract"] = 3; Next_recipe_number++; Recipe_number["multiply"] = 4; Next_recipe_number++; Recipe_number["divide"] = 5; Next_recipe_number++; Recipe_number["divide_with_remainder"] = 6; Next_recipe_number++; :(before "End Primitive Recipe Implementations") case 2: { // add trace("run") << "ingredient 0 is " << p->ingredients[0].name; vector arg0 = read_memory(p->ingredients[0]); assert(arg0.size() == 1); trace("run") << "ingredient 1 is " << p->ingredients[1].name; vector arg1 = read_memory(p->ingredients[1]); assert(arg1.size() == 1); vector result; result.push_back(arg0[0]+arg1[0]); trace("run") << "product 0 is " << result[0]; write_memory(p->products[0], result); break; } case 3: { // subtract trace("run") << "ingredient 0 is " << p->ingredients[0].name; vector arg0 = read_memory(p->ingredients[0]); assert(arg0.size() == 1); trace("run") << "ingredient 1 is " << p->ingredients[1].name; vector arg1 = read_memory(p->ingredients[1]); assert(arg1.size() == 1); vector result; result.push_back(arg0[0]-arg1[0]); trace("run") << "product 0 is " << result[0]; write_memory(p->products[0], result); break; } case 4: { // multiply trace("run") << "ingredient 0 is " << p->ingredients[0].name; vector arg0 = read_memory(p->ingredients[0]); assert(arg0.size() == 1); trace("run") << "ingredient 1 is " << p->ingredients[1].name; vector arg1 = read_memory(p->ingredients[1]); assert(arg1.size() == 1); trace("run") << "ingredient 1 is " << arg1[0]; vector result; result.push_back(arg0[0]*arg1[0]); trace("run") << "product 0 is " << result[0]; write_memory(p->products[0], result); break; } case 5: { // divide trace("run") << "ingredient 0 is " << p->ingredients[0].name; vector arg0 = read_memory(p->ingredients[0]); assert(arg0.size() == 1); trace("run") << "ingredient 1 is " << p->ingredients[1].name; vector arg1 = read_memory(p->ingredients[1]); assert(arg1.size() == 1); trace("run") << "ingredient 1 is " << arg1[0]; vector result; result.push_back(arg0[0]/arg1[0]); trace("run") << "product 0 is " << result[0]; write_memory(p->products[0], result); break; } case 6: { // divide_with_remainder trace("run") << "ingredient 0 is " << p->ingredients[0].name; vector arg0 = read_memory(p->ingredients[0]); assert(arg0.size() == 1); trace("run") << "ingredient 1 is " << p->ingredients[1].name; vector arg1 = read_memory(p->ingredients[1]); assert(arg1.size() == 1); vector result0; result0.push_back(arg0[0]/arg1[0]); trace("run") << "product 0 is " << result0[0]; write_memory(p->products[0], result0); vector result1; result1.push_back(arg0[0]%arg1[0]); trace("run") << "product 1 is " << result1[0]; write_memory(p->products[1], result1); break; } :(scenario "add_literal") recipe main [ 1:integer <- add 23:literal, 34:literal ] +run: instruction 0 +run: ingredient 0 is 23 +run: ingredient 1 is 34 +run: product 0 is 57 +mem: storing in location 1 :(scenario "add") recipe main [ 1:integer <- copy 23:literal 2:integer <- copy 34:literal 3:integer <- add 1:integer, 2:integer ] +run: instruction 2 +run: ingredient 0 is 1 +mem: location 1 is 23 +run: ingredient 1 is 2 +mem: location 2 is 34 +run: product 0 is 57 +mem: storing in location 3 :(scenario "subtract_literal") recipe main [ 1:integer <- subtract 5:literal, 2:literal ] +run: instruction 0 +run: ingredient 0 is 5 +run: ingredient 1 is 2 +run: product 0 is 3 +mem: storing in location 1 :(scenario "subtract") recipe main [ 1:integer <- copy 23:literal 2:integer <- copy 34:literal 3:integer <- subtract 1:integer, 2:integer ] +run: instruction 2 +run: ingredient 0 is 1 +mem: location 1 is 23 +run: ingredient 1 is 2 +mem: location 2 is 34 +run: product 0 is -11 +mem: storing in location 3 :(scenario "multiply_literal") recipe main [ 1:integer <- multiply 2:literal, 3:literal ] +run: instruction 0 +run: ingredient 0 is 2 +run: ingredient 1 is 3 +run: product 0 is 6 +mem: storing in location 1 :(scenario "multiply") recipe main [ 1:integer <- copy 4:literal 2:integer <- copy 6:literal 3:integer <- multiply 1:integer, 2:integer ] +run: instruction 2 +run: ingredient 0 is 1 +mem: location 1 is 4 +run: ingredient 1 is 2 +mem: location 2 is 6 +run: product 0 is 24 +mem: storing in location 3 :(scenario "divide_literal") recipe main [ 1:integer <- divide 8:literal, 2:literal ] +run: instruction 0 +run: ingredient 0 is 8 +run: ingredient 1 is 2 +run: product 0 is 4 +mem: storing in location 1 :(scenario "divide") recipe main [ 1:integer <- copy 27:literal 2:integer <- copy 3:literal 3:integer <- divide 1:integer, 2:integer ] +run: instruction 2 +run: ingredient 0 is 1 +mem: location 1 is 27 +run: ingredient 1 is 2 +mem: location 2 is 3 +run: product 0 is 9 +mem: storing in location 3 :(scenario "divide_with_remainder_literal") recipe main [ 1:integer, 2:integer <- divide_with_remainder 9:literal, 2:literal ] +run: instruction 0 +run: ingredient 0 is 9 +run: ingredient 1 is 2 +run: product 0 is 4 +mem: storing in location 1 +run: product 1 is 1 +mem: storing in location 2 :(scenario "divide_with_remainder") recipe main [ 1:integer <- copy 27:literal 2:integer <- copy 11:literal 3:integer, 4:integer <- divide_with_remainder 1:integer, 2:integer ] +run: instruction 2 +run: ingredient 0 is 1 +mem: location 1 is 27 +run: ingredient 1 is 2 +mem: location 2 is 11 +run: product 0 is 2 +mem: storing in location 3 +run: product 1 is 5 +mem: storing in location 4 :(code) int to_int(string n) { char* end = NULL; int result = strtol(n.c_str(), &end, /*any base*/0); assert(*end == '\0'); return result; }