about summary refs log tree commit diff stats
path: root/cpp
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-03-18 00:01:43 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-03-18 00:02:15 -0700
commit15ab959d64e65c313ec9741a64e906f986597078 (patch)
tree3a43d9b15e136b6e6af49b4f5ab55ff31044068b /cpp
parent32f6079fc3f43e774f17eae7b36aa8c9a3706952 (diff)
downloadmu-15ab959d64e65c313ec9741a64e906f986597078.tar.gz
951 - done with break/loop
Diffstat (limited to 'cpp')
-rw-r--r--cpp/.traces/brace_conversion5
-rw-r--r--cpp/.traces/break_cascading7
-rw-r--r--cpp/.traces/break_cascading213
-rw-r--r--cpp/.traces/break_empty_block5
-rw-r--r--cpp/.traces/break_if15
-rw-r--r--cpp/.traces/break_label5
-rw-r--r--cpp/.traces/break_nested14
-rw-r--r--cpp/.traces/break_nested_degenerate11
-rw-r--r--cpp/.traces/break_nested_degenerate28
-rw-r--r--cpp/.traces/break_unless14
-rw-r--r--cpp/.traces/factorial168
-rw-r--r--cpp/.traces/jump_backward3
-rw-r--r--cpp/.traces/jump_can_skip_instructions1
-rw-r--r--cpp/.traces/loop13
-rw-r--r--cpp/.traces/loop_label10
-rw-r--r--cpp/.traces/loop_nested28
-rw-r--r--cpp/.traces/loop_unless14
-rw-r--r--cpp/012transform1
-rw-r--r--cpp/016jump3
-rw-r--r--cpp/024brace58
20 files changed, 273 insertions, 123 deletions
diff --git a/cpp/.traces/brace_conversion b/cpp/.traces/brace_conversion
index 2c082bad..22021677 100644
--- a/cpp/.traces/brace_conversion
+++ b/cpp/.traces/brace_conversion
@@ -9,8 +9,3 @@ brace/0: push (close, 3)
 after-brace/0: recipe main
 after-brace/0: jump 1:offset
 after-brace/0: copy ...
-run/0: instruction main/1
-run/0: ingredient 0 is 
-run/0: instruction main/2
-run/0: ingredient 0 is 0
-mem/0: storing in location 1
diff --git a/cpp/.traces/break_cascading b/cpp/.traces/break_cascading
index 56a532a7..c89a1698 100644
--- a/cpp/.traces/break_cascading
+++ b/cpp/.traces/break_cascading
@@ -15,10 +15,3 @@ after-brace/0: recipe main
 after-brace/0: copy ...
 after-brace/0: jump 0:offset
 after-brace/0: jump 0:offset
-run/0: instruction main/0
-run/0: ingredient 0 is 0
-mem/0: storing in location 1
-run/0: instruction main/2
-run/0: ingredient 0 is 
-run/0: instruction main/5
-run/0: ingredient 0 is 
diff --git a/cpp/.traces/break_cascading2 b/cpp/.traces/break_cascading2
index 7b837b2a..6492fb8f 100644
--- a/cpp/.traces/break_cascading2
+++ b/cpp/.traces/break_cascading2
@@ -23,16 +23,3 @@ after-brace/0: copy ...
 after-brace/0: jump 1:offset
 after-brace/0: copy ...
 after-brace/0: jump 0:offset
-run/0: instruction main/0
-run/0: ingredient 0 is 0
-mem/0: storing in location 1
-run/0: instruction main/1
-run/0: ingredient 0 is 0
-mem/0: storing in location 2
-run/0: instruction main/3
-run/0: ingredient 0 is 
-run/0: instruction main/4
-run/0: ingredient 0 is 0
-mem/0: storing in location 3
-run/0: instruction main/7
-run/0: ingredient 0 is 
diff --git a/cpp/.traces/break_empty_block b/cpp/.traces/break_empty_block
index d66fe136..305e2a1e 100644
--- a/cpp/.traces/break_empty_block
+++ b/cpp/.traces/break_empty_block
@@ -9,8 +9,3 @@ brace/0: push (close, 3)
 after-brace/0: recipe main
 after-brace/0: copy ...
 after-brace/0: jump 0:offset
-run/0: instruction main/0
-run/0: ingredient 0 is 0
-mem/0: storing in location 1
-run/0: instruction main/2
-run/0: ingredient 0 is 
diff --git a/cpp/.traces/break_if b/cpp/.traces/break_if
index 34274a91..1e7ff661 100644
--- a/cpp/.traces/break_if
+++ b/cpp/.traces/break_if
@@ -24,18 +24,3 @@ after-brace/0: copy ...
 after-brace/0: jump-if 2, 1:offset
 after-brace/0: copy ...
 after-brace/0: jump 0:offset
-run/0: instruction main/0
-run/0: ingredient 0 is 0
-mem/0: storing in location 1
-run/0: instruction main/1
-run/0: ingredient 0 is 0
-mem/0: storing in location 2
-run/0: instruction main/3
-mem/0: location 2 is 0
-run/0: ingredient 0 is 0
-run/0: jump-if fell through
-run/0: instruction main/4
-run/0: ingredient 0 is 0
-mem/0: storing in location 3
-run/0: instruction main/7
-run/0: ingredient 0 is 
diff --git a/cpp/.traces/break_label b/cpp/.traces/break_label
index 23ce2727..5230e22e 100644
--- a/cpp/.traces/break_label
+++ b/cpp/.traces/break_label
@@ -10,8 +10,3 @@ brace/0: push (close, 3)
 after-brace/0: recipe main
 after-brace/0: copy ...
 after-brace/0: jump +foo:offset
-run/0: instruction main/0
-run/0: ingredient 0 is 0
-mem/0: storing in location 1
-run/0: instruction main/2
-run/0: ingredient 0 is +foo
diff --git a/cpp/.traces/break_nested b/cpp/.traces/break_nested
index ed3afda6..a4d242ce 100644
--- a/cpp/.traces/break_nested
+++ b/cpp/.traces/break_nested
@@ -25,17 +25,3 @@ after-brace/0: copy ...
 after-brace/0: jump 4:offset
 after-brace/0: copy ...
 after-brace/0: copy ...
-run/0: instruction main/0
-run/0: ingredient 0 is 0
-mem/0: storing in location 1
-run/0: instruction main/2
-run/0: ingredient 0 is 0
-mem/0: storing in location 2
-run/0: instruction main/3
-run/0: ingredient 0 is 
-run/0: instruction main/5
-run/0: ingredient 0 is 0
-mem/0: storing in location 3
-run/0: instruction main/7
-run/0: ingredient 0 is 0
-mem/0: storing in location 4
diff --git a/cpp/.traces/break_nested_degenerate b/cpp/.traces/break_nested_degenerate
index 2f09b01d..2a113ff9 100644
--- a/cpp/.traces/break_nested_degenerate
+++ b/cpp/.traces/break_nested_degenerate
@@ -21,14 +21,3 @@ after-brace/0: copy ...
 after-brace/0: copy ...
 after-brace/0: jump 3:offset
 after-brace/0: copy ...
-run/0: instruction main/0
-run/0: ingredient 0 is 0
-mem/0: storing in location 1
-run/0: instruction main/2
-run/0: ingredient 0 is 0
-mem/0: storing in location 2
-run/0: instruction main/3
-run/0: ingredient 0 is 
-run/0: instruction main/6
-run/0: ingredient 0 is 0
-mem/0: storing in location 4
diff --git a/cpp/.traces/break_nested_degenerate2 b/cpp/.traces/break_nested_degenerate2
index 7dd3ba16..586a73eb 100644
--- a/cpp/.traces/break_nested_degenerate2
+++ b/cpp/.traces/break_nested_degenerate2
@@ -17,11 +17,3 @@ after-brace/0: recipe main
 after-brace/0: copy ...
 after-brace/0: copy ...
 after-brace/0: jump 2:offset
-run/0: instruction main/0
-run/0: ingredient 0 is 0
-mem/0: storing in location 1
-run/0: instruction main/2
-run/0: ingredient 0 is 0
-mem/0: storing in location 2
-run/0: instruction main/3
-run/0: ingredient 0 is 
diff --git a/cpp/.traces/break_unless b/cpp/.traces/break_unless
index b227e1ab..5528ce60 100644
--- a/cpp/.traces/break_unless
+++ b/cpp/.traces/break_unless
@@ -18,17 +18,3 @@ after-brace/0: copy ...
 after-brace/0: copy ...
 after-brace/0: jump-unless 2, 1:offset
 after-brace/0: copy ...
-run/0: instruction main/0
-run/0: ingredient 0 is 0
-mem/0: storing in location 1
-run/0: instruction main/1
-run/0: ingredient 0 is 0
-mem/0: storing in location 2
-run/0: instruction main/3
-mem/0: location 2 is 0
-run/0: ingredient 0 is 0
-run/0: ingredient 1 is 
-run/0: jumping to instruction 4
-run/0: instruction main/4
-run/0: ingredient 0 is 0
-mem/0: storing in location 3
diff --git a/cpp/.traces/factorial b/cpp/.traces/factorial
new file mode 100644
index 00000000..ef8fff86
--- /dev/null
+++ b/cpp/.traces/factorial
@@ -0,0 +1,168 @@
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "5", value: 0, type: 0, properties: [5: literal]}
+parse/0:   product: {name: "1", value: 0, type: 1, properties: [1: integer]}
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "1", value: 0, type: 0, properties: [1: literal]}
+parse/0:   product: {name: "2", value: 0, type: 1, properties: [2: integer]}
+parse/0: label: {
+parse/0: instruction: 13
+parse/0:   ingredient: {name: "1", value: 0, type: 1, properties: [1: integer]}
+parse/0:   ingredient: {name: "1", value: 0, type: 0, properties: [1: literal]}
+parse/0:   product: {name: "3", value: 0, type: 3, properties: [3: boolean]}
+parse/0: instruction: 25
+parse/0:   ingredient: {name: "3", value: 0, type: 3, properties: [3: boolean]}
+parse/0: instruction: 4
+parse/0:   ingredient: {name: "2", value: 0, type: 1, properties: [2: integer]}
+parse/0:   ingredient: {name: "1", value: 0, type: 1, properties: [1: integer]}
+parse/0:   product: {name: "2", value: 0, type: 1, properties: [2: integer]}
+parse/0: instruction: 3
+parse/0:   ingredient: {name: "1", value: 0, type: 1, properties: [1: integer]}
+parse/0:   ingredient: {name: "1", value: 0, type: 0, properties: [1: literal]}
+parse/0:   product: {name: "1", value: 0, type: 1, properties: [1: integer]}
+parse/0: instruction: 26
+parse/0: label: }
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "2", value: 0, type: 1, properties: [2: integer]}
+parse/0:   product: {name: "4", value: 0, type: 1, properties: [4: integer]}
+brace/0: 24: push (open, 2)
+brace/0: push (close, 8)
+after-brace/0: recipe factorial
+after-brace/0: copy ...
+after-brace/0: copy ...
+after-brace/0: equal ...
+after-brace/0: jump-if 3, 3:offset
+after-brace/0: multiply ...
+after-brace/0: subtract ...
+after-brace/0: jump -5:offset
+after-brace/0: 7: {name: "", value: -5, type: 0}
+after-brace/0: 7: {name: "", value: -5, type: 0}
+after-brace/0: copy ...
+run/0: instruction factorial/0
+run/0: ingredient 0 is 5
+mem/0: storing in location 1
+run/0: instruction factorial/1
+run/0: ingredient 0 is 1
+mem/0: storing in location 2
+run/0: instruction factorial/3
+run/0: ingredient 0 is 1
+mem/0: location 1 is 5
+run/0: ingredient 1 is 1
+run/0: product 0 is 0
+mem/0: storing in location 3
+run/0: instruction factorial/4
+mem/0: location 3 is 0
+run/0: ingredient 0 is 0
+run/0: jump-if fell through
+run/0: instruction factorial/5
+run/0: ingredient 0 is 2
+mem/0: location 2 is 1
+run/0: ingredient 1 is 1
+mem/0: location 1 is 5
+run/0: ingredient 1 is 5
+run/0: product 0 is 5
+mem/0: storing in location 2
+run/0: instruction factorial/6
+run/0: ingredient 0 is 1
+mem/0: location 1 is 5
+run/0: ingredient 1 is 1
+run/0: product 0 is 4
+mem/0: storing in location 1
+run/0: instruction factorial/7
+run/0: ingredient 0 is -5
+run/0: pc now 2
+run/0: instruction factorial/3
+run/0: ingredient 0 is 1
+mem/0: location 1 is 4
+run/0: ingredient 1 is 1
+run/0: product 0 is 0
+mem/0: storing in location 3
+run/0: instruction factorial/4
+mem/0: location 3 is 0
+run/0: ingredient 0 is 0
+run/0: jump-if fell through
+run/0: instruction factorial/5
+run/0: ingredient 0 is 2
+mem/0: location 2 is 5
+run/0: ingredient 1 is 1
+mem/0: location 1 is 4
+run/0: ingredient 1 is 4
+run/0: product 0 is 20
+mem/0: storing in location 2
+run/0: instruction factorial/6
+run/0: ingredient 0 is 1
+mem/0: location 1 is 4
+run/0: ingredient 1 is 1
+run/0: product 0 is 3
+mem/0: storing in location 1
+run/0: instruction factorial/7
+run/0: ingredient 0 is -5
+run/0: pc now 2
+run/0: instruction factorial/3
+run/0: ingredient 0 is 1
+mem/0: location 1 is 3
+run/0: ingredient 1 is 1
+run/0: product 0 is 0
+mem/0: storing in location 3
+run/0: instruction factorial/4
+mem/0: location 3 is 0
+run/0: ingredient 0 is 0
+run/0: jump-if fell through
+run/0: instruction factorial/5
+run/0: ingredient 0 is 2
+mem/0: location 2 is 20
+run/0: ingredient 1 is 1
+mem/0: location 1 is 3
+run/0: ingredient 1 is 3
+run/0: product 0 is 60
+mem/0: storing in location 2
+run/0: instruction factorial/6
+run/0: ingredient 0 is 1
+mem/0: location 1 is 3
+run/0: ingredient 1 is 1
+run/0: product 0 is 2
+mem/0: storing in location 1
+run/0: instruction factorial/7
+run/0: ingredient 0 is -5
+run/0: pc now 2
+run/0: instruction factorial/3
+run/0: ingredient 0 is 1
+mem/0: location 1 is 2
+run/0: ingredient 1 is 1
+run/0: product 0 is 0
+mem/0: storing in location 3
+run/0: instruction factorial/4
+mem/0: location 3 is 0
+run/0: ingredient 0 is 0
+run/0: jump-if fell through
+run/0: instruction factorial/5
+run/0: ingredient 0 is 2
+mem/0: location 2 is 60
+run/0: ingredient 1 is 1
+mem/0: location 1 is 2
+run/0: ingredient 1 is 2
+run/0: product 0 is 120
+mem/0: storing in location 2
+run/0: instruction factorial/6
+run/0: ingredient 0 is 1
+mem/0: location 1 is 2
+run/0: ingredient 1 is 1
+run/0: product 0 is 1
+mem/0: storing in location 1
+run/0: instruction factorial/7
+run/0: ingredient 0 is -5
+run/0: pc now 2
+run/0: instruction factorial/3
+run/0: ingredient 0 is 1
+mem/0: location 1 is 1
+run/0: ingredient 1 is 1
+run/0: product 0 is 1
+mem/0: storing in location 3
+run/0: instruction factorial/4
+mem/0: location 3 is 1
+run/0: ingredient 0 is 1
+run/0: ingredient 1 is 
+run/0: jumping to instruction 8
+run/0: instruction factorial/9
+run/0: ingredient 0 is 2
+mem/0: location 2 is 120
+mem/0: storing in location 4
diff --git a/cpp/.traces/jump_backward b/cpp/.traces/jump_backward
index b9cf549c..4b9f17df 100644
--- a/cpp/.traces/jump_backward
+++ b/cpp/.traces/jump_backward
@@ -10,7 +10,10 @@ after-brace/0: jump ...
 after-brace/0: jump ...
 run/0: instruction main/0
 run/0: ingredient 0 is 1
+run/0: pc now 1
 run/0: instruction main/2
 run/0: ingredient 0 is -2
+run/0: pc now 0
 run/0: instruction main/1
 run/0: ingredient 0 is 1
+run/0: pc now 2
diff --git a/cpp/.traces/jump_can_skip_instructions b/cpp/.traces/jump_can_skip_instructions
index 3e0f1bfd..3a42a0f1 100644
--- a/cpp/.traces/jump_can_skip_instructions
+++ b/cpp/.traces/jump_can_skip_instructions
@@ -8,3 +8,4 @@ after-brace/0: jump ...
 after-brace/0: copy ...
 run/0: instruction main/0
 run/0: ingredient 0 is 1
+run/0: pc now 1
diff --git a/cpp/.traces/loop b/cpp/.traces/loop
index 2c05c2fb..26d2dbc8 100644
--- a/cpp/.traces/loop
+++ b/cpp/.traces/loop
@@ -17,14 +17,5 @@ after-brace/0: copy ...
 after-brace/0: copy ...
 after-brace/0: copy ...
 after-brace/0: jump -2:offset
-run/0: instruction main/0
-run/0: ingredient 0 is 0
-mem/0: storing in location 1
-run/0: instruction main/1
-run/0: ingredient 0 is 0
-mem/0: storing in location 2
-run/0: instruction main/3
-run/0: ingredient 0 is 0
-mem/0: storing in location 3
-run/0: instruction main/4
-run/0: ingredient 0 is 
+after-brace/0: 4: {name: "", value: -2, type: 0}
+after-brace/0: 4: {name: "", value: -2, type: 0}
diff --git a/cpp/.traces/loop_label b/cpp/.traces/loop_label
new file mode 100644
index 00000000..990c175f
--- /dev/null
+++ b/cpp/.traces/loop_label
@@ -0,0 +1,10 @@
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: [0: literal]}
+parse/0:   product: {name: "1", value: 0, type: 1, properties: [1: integer]}
+parse/0: label: +foo
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: [0: literal]}
+parse/0:   product: {name: "2", value: 0, type: 1, properties: [2: integer]}
+after-brace/0: recipe main
+after-brace/0: copy ...
+after-brace/0: copy ...
diff --git a/cpp/.traces/loop_nested b/cpp/.traces/loop_nested
new file mode 100644
index 00000000..9e865605
--- /dev/null
+++ b/cpp/.traces/loop_nested
@@ -0,0 +1,28 @@
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: [0: literal]}
+parse/0:   product: {name: "1", value: 0, type: 1, properties: [1: integer]}
+parse/0: label: {
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: [0: literal]}
+parse/0:   product: {name: "2", value: 0, type: 1, properties: [2: integer]}
+parse/0: label: {
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: [0: literal]}
+parse/0:   product: {name: "3", value: 0, type: 1, properties: [3: integer]}
+parse/0: label: }
+parse/0: instruction: 25
+parse/0:   ingredient: {name: "4", value: 0, type: 3, properties: [4: boolean]}
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: [0: literal]}
+parse/0:   product: {name: "5", value: 0, type: 1, properties: [5: integer]}
+parse/0: label: }
+brace/0: 24: push (open, 1)
+brace/0: 24: push (open, 3)
+brace/0: push (close, 5)
+brace/0: push (close, 8)
+after-brace/0: recipe main
+after-brace/0: copy ...
+after-brace/0: copy ...
+after-brace/0: copy ...
+after-brace/0: jump-if 4, -5:offset
+after-brace/0: copy ...
diff --git a/cpp/.traces/loop_unless b/cpp/.traces/loop_unless
index 35a3cc8a..ef736ca6 100644
--- a/cpp/.traces/loop_unless
+++ b/cpp/.traces/loop_unless
@@ -18,17 +18,3 @@ after-brace/0: copy ...
 after-brace/0: copy ...
 after-brace/0: jump-unless 2, -1:offset
 after-brace/0: copy ...
-run/0: instruction main/0
-run/0: ingredient 0 is 0
-mem/0: storing in location 1
-run/0: instruction main/1
-run/0: ingredient 0 is 0
-mem/0: storing in location 2
-run/0: instruction main/3
-mem/0: location 2 is 0
-run/0: ingredient 0 is 0
-run/0: ingredient 1 is 
-run/0: jumping to instruction 4
-run/0: instruction main/4
-run/0: ingredient 0 is 0
-mem/0: storing in location 3
diff --git a/cpp/012transform b/cpp/012transform
index 8cd29c94..7a591a87 100644
--- a/cpp/012transform
+++ b/cpp/012transform
@@ -46,6 +46,7 @@ void parse_int_reagents() {
 }
 
 void populate_value(reagent& r) {
+  if (r.name.empty()) return;
   char* end = NULL;
   int result = strtol(r.name.c_str(), &end, /*any base*/0);
   if (*end != '\0') return;
diff --git a/cpp/016jump b/cpp/016jump
index 827e70f4..9d192e96 100644
--- a/cpp/016jump
+++ b/cpp/016jump
@@ -7,8 +7,9 @@ assert(Next_recipe_number == JUMP);
 Next_recipe_number++;
 :(before "End Primitive Recipe Implementations")
 case JUMP: {
-  trace("run") << "ingredient 0 is " << instructions[pc].ingredients[0].name;
+  trace("run") << "ingredient 0 is " << instructions[pc].ingredients[0].value;
   pc += instructions[pc].ingredients[0].value;
+  trace("run") << "pc now " << pc;
   break;
 }
 
diff --git a/cpp/024brace b/cpp/024brace
index f5fbbb87..d97f228f 100644
--- a/cpp/024brace
+++ b/cpp/024brace
@@ -19,6 +19,7 @@
 //: benefits of the control-flow primitives we're used to in other languages,
 //: like 'if', 'while', 'for', etc.
 
+:(scenarios transform_test)
 :(scenario "brace_conversion")
 recipe main [
   {
@@ -66,8 +67,11 @@ void transform_braces(const recipe_number r) {
       else {
         reagent ing(0);  // literal
         ing.value = open_braces.top()-index;
+        ing.name.clear();
         inst.ingredients.push_back(ing);
         trace("after-brace") << "jump " << ing.value << ":offset";
+        trace("after-brace") << index << ": " << ing.to_string();
+        trace("after-brace") << index << ": " << Recipe[r].steps[index].ingredients[0].to_string();
       }
     }
     else if (inst.operation == Recipe_number["break"]) {
@@ -79,6 +83,7 @@ void transform_braces(const recipe_number r) {
       else {
         reagent ing(0);  // literal
         ing.value = matching_brace(open_braces.top(), braces) - index - 1;
+        ing.name.clear();
         inst.ingredients.push_back(ing);
         trace("after-brace") << "jump " << ing.value << ":offset";
       }
@@ -92,6 +97,7 @@ void transform_braces(const recipe_number r) {
       else {
         reagent ing(0);  // literal
         ing.value = open_braces.top()-index;
+        ing.name.clear();
         inst.ingredients.push_back(ing);
         trace("after-brace") << "jump-if " << inst.ingredients[0].name << ", " << ing.value << ":offset";
       }
@@ -105,6 +111,7 @@ void transform_braces(const recipe_number r) {
       else {
         reagent ing(0);  // literal
         ing.value = matching_brace(open_braces.top(), braces) - index - 1;
+        ing.name.clear();
         inst.ingredients.push_back(ing);
         trace("after-brace") << "jump-if " << inst.ingredients[0].name << ", " << ing.value << ":offset";
       }
@@ -118,6 +125,7 @@ void transform_braces(const recipe_number r) {
       else {
         reagent ing(0);  // literal
         ing.value = open_braces.top()-index;
+        ing.name.clear();
         inst.ingredients.push_back(ing);
         trace("after-brace") << "jump-unless " << inst.ingredients[0].name << ", " << ing.value << ":offset";
       }
@@ -131,6 +139,7 @@ void transform_braces(const recipe_number r) {
       else {
         reagent ing(0);  // literal
         ing.value = matching_brace(open_braces.top(), braces) - index - 1;
+        ing.name.clear();
         inst.ingredients.push_back(ing);
         trace("after-brace") << "jump-unless " << inst.ingredients[0].name << ", " << ing.value << ":offset";
       }
@@ -152,6 +161,13 @@ size_t matching_brace(size_t index, const list<pair<int, size_t> >& braces) {
   return -1;
 }
 
+// temporarily suppress run
+void transform_test(string form) {
+  vector<recipe_number> tmp = add_recipes(form);
+  recipes_added_by_test.insert(recipes_added_by_test.end(), tmp.begin(), tmp.end());
+  transform_all();
+}
+
 :(scenario "loop")
 recipe main [
   1:integer <- copy 0:literal
@@ -308,3 +324,45 @@ recipe main [
 +after-brace: copy ...
 +after-brace: jump-unless 2, -1:offset
 +after-brace: copy ...
+
+:(scenario "loop_nested")
+recipe main [
+  1:integer <- copy 0:literal
+  {
+    2:integer <- copy 0:literal
+    {
+      3:integer <- copy 0:literal
+    }
+    loop-if 4:boolean
+    5:integer <- copy 0:literal
+  }
+]
++after-brace: recipe main
++after-brace: jump-if 4, -5:offset
+
+:(scenario "loop_label")
+recipe main [
+  1:integer <- copy 0:literal
+  +foo
+  2:integer <- copy 0:literal
+]
++after-brace: recipe main
++after-brace: copy ...
++after-brace: copy ...
+
+//: test how things actually run
+:(scenarios run)
+:(scenario "factorial")
+recipe factorial [
+  1:integer <- copy 5:literal
+  2:integer <- copy 1:literal
+  {
+    3:boolean <- equal 1:integer 1:literal
+    break-if 3:boolean
+    2:integer <- multiply 2:integer, 1:integer
+    1:integer <- subtract 1:integer, 1:literal
+    loop
+  }
+  4:integer <- copy 2:integer  # trigger a read
+]
++mem: location 2 is 120