about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-04-19 20:49:30 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-04-19 20:49:30 -0700
commit717ab65913f1585221632303f0ab53ac42d4b348 (patch)
tree645e537eea155ff2221ace71f80924a66c92116a
parente4a97d87a17a8edc5a2049bdc21143695d20dcfc (diff)
downloadmu-717ab65913f1585221632303f0ab53ac42d4b348.tar.gz
1105 - more primitives for managing ingredients
-rw-r--r--cpp/.traces/brace_conversion2
-rw-r--r--cpp/.traces/break_cascading4
-rw-r--r--cpp/.traces/break_cascading24
-rw-r--r--cpp/.traces/break_empty_block2
-rw-r--r--cpp/.traces/break_if4
-rw-r--r--cpp/.traces/break_label2
-rw-r--r--cpp/.traces/break_nested2
-rw-r--r--cpp/.traces/break_nested_degenerate2
-rw-r--r--cpp/.traces/break_nested_degenerate22
-rw-r--r--cpp/.traces/break_unless2
-rw-r--r--cpp/.traces/buffer-append-works2
-rw-r--r--cpp/.traces/closure10
-rw-r--r--cpp/.traces/factorial4
-rw-r--r--cpp/.traces/ingredient20
-rw-r--r--cpp/.traces/loop2
-rw-r--r--cpp/.traces/loop_nested2
-rw-r--r--cpp/.traces/loop_unless2
-rw-r--r--cpp/.traces/new4
-rw-r--r--cpp/.traces/new_array4
-rw-r--r--cpp/.traces/new_string2
-rw-r--r--cpp/.traces/reply2
-rw-r--r--cpp/.traces/reply_container2
-rw-r--r--cpp/.traces/rewind_ingredients29
-rw-r--r--cpp/.traces/string-append-14
-rw-r--r--cpp/.traces/string-equal-common-lengths-but-distinct6
-rw-r--r--cpp/.traces/string-equal-distinct-lengths6
-rw-r--r--cpp/.traces/string-equal-identical6
-rw-r--r--cpp/.traces/string-equal-reflexive4
-rw-r--r--cpp/.traces/string-equal-with-empty6
-rw-r--r--cpp/.traces/string_literal2
-rw-r--r--cpp/.traces/string_literal_nested2
-rw-r--r--cpp/.traces/string_literal_with_colons2
-rw-r--r--cpp/036call_ingredient65
33 files changed, 164 insertions, 50 deletions
diff --git a/cpp/.traces/brace_conversion b/cpp/.traces/brace_conversion
index 87f49881..bf7e037a 100644
--- a/cpp/.traces/brace_conversion
+++ b/cpp/.traces/brace_conversion
@@ -1,5 +1,5 @@
 parse/0: label: {
-parse/0: instruction: 27
+parse/0: instruction: 29
 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"]}
diff --git a/cpp/.traces/break_cascading b/cpp/.traces/break_cascading
index 71751935..5dbfdb24 100644
--- a/cpp/.traces/break_cascading
+++ b/cpp/.traces/break_cascading
@@ -2,10 +2,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: {
-parse/0: instruction: 27
+parse/0: instruction: 29
 parse/0: label: }
 parse/0: label: {
-parse/0: instruction: 27
+parse/0: instruction: 29
 parse/0: label: }
 brace/0: 1000: push (open, 1)
 brace/0: push (close, 3)
diff --git a/cpp/.traces/break_cascading2 b/cpp/.traces/break_cascading2
index 707d40dc..f42aea33 100644
--- a/cpp/.traces/break_cascading2
+++ b/cpp/.traces/break_cascading2
@@ -5,13 +5,13 @@ 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: 27
+parse/0: instruction: 29
 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: label: {
-parse/0: instruction: 27
+parse/0: instruction: 29
 parse/0: label: }
 brace/0: 1000: push (open, 2)
 brace/0: push (close, 5)
diff --git a/cpp/.traces/break_empty_block b/cpp/.traces/break_empty_block
index b8ddb6ea..4fa219a3 100644
--- a/cpp/.traces/break_empty_block
+++ b/cpp/.traces/break_empty_block
@@ -2,7 +2,7 @@ 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: 27
+parse/0: instruction: 29
 parse/0: label: }
 brace/0: 1000: push (open, 1)
 brace/0: push (close, 3)
diff --git a/cpp/.traces/break_if b/cpp/.traces/break_if
index 20039d80..cef9f6be 100644
--- a/cpp/.traces/break_if
+++ b/cpp/.traces/break_if
@@ -5,14 +5,14 @@ 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: 28
+parse/0: instruction: 30
 parse/0:   ingredient: {name: "2", value: 0, type: 1, properties: ["2": "integer"]}
 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: label: {
-parse/0: instruction: 27
+parse/0: instruction: 29
 parse/0: label: }
 brace/0: 1000: push (open, 2)
 brace/0: push (close, 5)
diff --git a/cpp/.traces/break_label b/cpp/.traces/break_label
index 07ff1543..85fca7fc 100644
--- a/cpp/.traces/break_label
+++ b/cpp/.traces/break_label
@@ -2,7 +2,7 @@ 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: 27
+parse/0: instruction: 29
 parse/0:   ingredient: {name: "+foo", value: 0, type: 0, properties: ["+foo": "offset"]}
 parse/0: label: }
 brace/0: 1000: push (open, 1)
diff --git a/cpp/.traces/break_nested b/cpp/.traces/break_nested
index e2e99975..cf764b7a 100644
--- a/cpp/.traces/break_nested
+++ b/cpp/.traces/break_nested
@@ -5,7 +5,7 @@ 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: instruction: 27
+parse/0: instruction: 29
 parse/0: label: {
 parse/0: instruction: 1
 parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]}
diff --git a/cpp/.traces/break_nested_degenerate b/cpp/.traces/break_nested_degenerate
index 7c67c974..5713f0ef 100644
--- a/cpp/.traces/break_nested_degenerate
+++ b/cpp/.traces/break_nested_degenerate
@@ -5,7 +5,7 @@ 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: instruction: 27
+parse/0: instruction: 29
 parse/0: label: {
 parse/0: label: }
 parse/0: instruction: 1
diff --git a/cpp/.traces/break_nested_degenerate2 b/cpp/.traces/break_nested_degenerate2
index 89469290..4573115e 100644
--- a/cpp/.traces/break_nested_degenerate2
+++ b/cpp/.traces/break_nested_degenerate2
@@ -5,7 +5,7 @@ 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: instruction: 27
+parse/0: instruction: 29
 parse/0: label: {
 parse/0: label: }
 parse/0: label: }
diff --git a/cpp/.traces/break_unless b/cpp/.traces/break_unless
index ffba9947..9e2ad94c 100644
--- a/cpp/.traces/break_unless
+++ b/cpp/.traces/break_unless
@@ -5,7 +5,7 @@ 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: 29
+parse/0: instruction: 31
 parse/0:   ingredient: {name: "2", value: 0, type: 1, properties: ["2": "integer"]}
 parse/0: instruction: 1
 parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]}
diff --git a/cpp/.traces/buffer-append-works b/cpp/.traces/buffer-append-works
index bef17f83..06f665a2 100644
--- a/cpp/.traces/buffer-append-works
+++ b/cpp/.traces/buffer-append-works
@@ -1,4 +1,4 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "location", value: 0, type: 0, properties: ["location": "type"]}
 parse/0:   ingredient: {name: "30", value: 0, type: 0, properties: ["30": "literal"]}
 parse/0:   product: {name: "default-space", value: 0, type: 2-5-1, properties: ["default-space": "address":"array":"location"]}
diff --git a/cpp/.traces/closure b/cpp/.traces/closure
index 4a6fc50b..73ba0a6e 100644
--- a/cpp/.traces/closure
+++ b/cpp/.traces/closure
@@ -1,4 +1,4 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "location", value: 0, type: 0, properties: ["location": "type"]}
 parse/0:   ingredient: {name: "30", value: 0, type: 0, properties: ["30": "literal"]}
 parse/0:   product: {name: "default-space", value: 0, type: 2-5-1, properties: ["default-space": "address":"array":"location"]}
@@ -10,7 +10,7 @@ parse/0:   product: {name: "2", value: 0, type: 1, properties: ["2": "integer",
 parse/0: instruction: 1002
 parse/0:   ingredient: {name: "1", value: 0, type: 2-5-1, properties: ["1": "address":"array":"location", "names": "init-counter"]}
 parse/0:   product: {name: "3", value: 0, type: 1, properties: ["3": "integer", "raw": ]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "location", value: 0, type: 0, properties: ["location": "type"]}
 parse/0:   ingredient: {name: "30", value: 0, type: 0, properties: ["30": "literal"]}
 parse/0:   product: {name: "default-space", value: 0, type: 2-5-1, properties: ["default-space": "address":"array":"location"]}
@@ -20,9 +20,9 @@ parse/0:   product: {name: "x", value: 0, type: 1, properties: ["x": "integer"]}
 parse/0: instruction: 1
 parse/0:   ingredient: {name: "3", value: 0, type: 0, properties: ["3": "literal"]}
 parse/0:   product: {name: "y", value: 0, type: 1, properties: ["y": "integer"]}
-parse/0: instruction: 26
+parse/0: instruction: 28
 parse/0:   ingredient: {name: "default-space", value: 0, type: 2-5-1, properties: ["default-space": "address":"array":"location"]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "space", value: 0, type: 0, properties: ["space": "literal"]}
 parse/0:   ingredient: {name: "30", value: 0, type: 0, properties: ["30": "literal"]}
 parse/0:   product: {name: "default-space", value: 0, type: 2-5-1, properties: ["default-space": "address":"array":"location"]}
@@ -35,7 +35,7 @@ parse/0:   product: {name: "y", value: 0, type: 1, properties: ["y": "integer",
 parse/0: instruction: 1
 parse/0:   ingredient: {name: "234", value: 0, type: 0, properties: ["234": "literal"]}
 parse/0:   product: {name: "y", value: 0, type: 1, properties: ["y": "integer"]}
-parse/0: instruction: 26
+parse/0: instruction: 28
 parse/0:   ingredient: {name: "y", value: 0, type: 1, properties: ["y": "integer", "space": "1"]}
 name/0: recipe increment-counter is surrounded by init-counter
 new/0: location -> 1
diff --git a/cpp/.traces/factorial b/cpp/.traces/factorial
index 15c4d3a1..55e60320 100644
--- a/cpp/.traces/factorial
+++ b/cpp/.traces/factorial
@@ -9,7 +9,7 @@ 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: 28
+parse/0: instruction: 30
 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"]}
@@ -19,7 +19,7 @@ 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: 30
+parse/0: instruction: 32
 parse/0: label: }
 parse/0: instruction: 1
 parse/0:   ingredient: {name: "2", value: 0, type: 1, properties: ["2": "integer"]}
diff --git a/cpp/.traces/ingredient b/cpp/.traces/ingredient
new file mode 100644
index 00000000..4b028b84
--- /dev/null
+++ b/cpp/.traces/ingredient
@@ -0,0 +1,20 @@
+parse/0: instruction: 1001
+parse/0:   ingredient: {name: "1", value: 0, type: 0, properties: ["1": "literal"]}
+parse/0:   ingredient: {name: "2", value: 0, type: 0, properties: ["2": "literal"]}
+parse/0: instruction: 27
+parse/0:   ingredient: {name: "1", value: 0, type: 0, properties: ["1": "literal"]}
+parse/0:   product: {name: "12", value: 0, type: 1, properties: ["12": "integer"]}
+parse/0: instruction: 25
+parse/0:   product: {name: "13", value: 0, type: 1, properties: ["13": "integer"]}
+parse/0:   product: {name: "1", value: 0, type: 3, properties: ["1": "boolean"]}
+after-brace/0: recipe f
+after-brace/0: ingredient ...
+after-brace/0: next-ingredient ...
+after-brace/0: recipe main
+after-brace/0: f ...
+run/0: instruction main/0
+run/0: instruction f/0
+run/0: product 0 is 2
+mem/0: storing 2 in location 12
+run/0: instruction f/1
+mem/0: storing 0 in location 1
diff --git a/cpp/.traces/loop b/cpp/.traces/loop
index 17b07293..5e08df9b 100644
--- a/cpp/.traces/loop
+++ b/cpp/.traces/loop
@@ -8,7 +8,7 @@ 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: instruction: 30
+parse/0: instruction: 32
 parse/0: label: }
 brace/0: 1000: push (open, 2)
 brace/0: push (close, 5)
diff --git a/cpp/.traces/loop_nested b/cpp/.traces/loop_nested
index 92278cab..e31766d2 100644
--- a/cpp/.traces/loop_nested
+++ b/cpp/.traces/loop_nested
@@ -10,7 +10,7 @@ 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: 31
+parse/0: instruction: 33
 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"]}
diff --git a/cpp/.traces/loop_unless b/cpp/.traces/loop_unless
index a90ea0eb..b4678763 100644
--- a/cpp/.traces/loop_unless
+++ b/cpp/.traces/loop_unless
@@ -5,7 +5,7 @@ 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: 32
+parse/0: instruction: 34
 parse/0:   ingredient: {name: "2", value: 0, type: 1, properties: ["2": "integer"]}
 parse/0: instruction: 1
 parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]}
diff --git a/cpp/.traces/new b/cpp/.traces/new
index 22438e09..3f16daba 100644
--- a/cpp/.traces/new
+++ b/cpp/.traces/new
@@ -1,7 +1,7 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "integer", value: 0, type: 0, properties: ["integer": "type"]}
 parse/0:   product: {name: "1", value: 0, type: 2-1, properties: ["1": "address":"integer", "raw": ]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "integer", value: 0, type: 0, properties: ["integer": "type"]}
 parse/0:   product: {name: "2", value: 0, type: 2-1, properties: ["2": "address":"integer", "raw": ]}
 parse/0: instruction: 13
diff --git a/cpp/.traces/new_array b/cpp/.traces/new_array
index 2fbe8673..6f818ed7 100644
--- a/cpp/.traces/new_array
+++ b/cpp/.traces/new_array
@@ -1,8 +1,8 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "integer", value: 0, type: 0, properties: ["integer": "type"]}
 parse/0:   ingredient: {name: "5", value: 0, type: 0, properties: ["5": "literal"]}
 parse/0:   product: {name: "1", value: 0, type: 2-5-1, properties: ["1": "address":"array":"integer", "raw": ]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "integer", value: 0, type: 0, properties: ["integer": "type"]}
 parse/0:   product: {name: "2", value: 0, type: 2-1, properties: ["2": "address":"integer", "raw": ]}
 parse/0: instruction: 3
diff --git a/cpp/.traces/new_string b/cpp/.traces/new_string
index ac3d86d7..aa944a2c 100644
--- a/cpp/.traces/new_string
+++ b/cpp/.traces/new_string
@@ -1,4 +1,4 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "abc def", value: 0, type: 0, properties: ["abc def": "literal-string"]}
 parse/0:   product: {name: "1", value: 0, type: 2-5-4, properties: ["1": "address":"array":"character"]}
 parse/0: instruction: 21
diff --git a/cpp/.traces/reply b/cpp/.traces/reply
index c438cb79..a58a1193 100644
--- a/cpp/.traces/reply
+++ b/cpp/.traces/reply
@@ -8,7 +8,7 @@ parse/0: instruction: 2
 parse/0:   ingredient: {name: "1", value: 0, type: 0, properties: ["1": "literal"]}
 parse/0:   ingredient: {name: "12", value: 0, type: 1, properties: ["12": "integer"]}
 parse/0:   product: {name: "13", value: 0, type: 1, properties: ["13": "integer"]}
-parse/0: instruction: 26
+parse/0: instruction: 28
 parse/0:   ingredient: {name: "12", value: 0, type: 1, properties: ["12": "integer"]}
 parse/0:   ingredient: {name: "13", value: 0, type: 1, properties: ["13": "integer"]}
 after-brace/0: recipe f
diff --git a/cpp/.traces/reply_container b/cpp/.traces/reply_container
index b496a201..9a5d430f 100644
--- a/cpp/.traces/reply_container
+++ b/cpp/.traces/reply_container
@@ -6,7 +6,7 @@ parse/0:   product: {name: "12", value: 0, type: 1, properties: ["12": "integer"
 parse/0: instruction: 1
 parse/0:   ingredient: {name: "35", value: 0, type: 0, properties: ["35": "literal"]}
 parse/0:   product: {name: "13", value: 0, type: 1, properties: ["13": "integer"]}
-parse/0: instruction: 26
+parse/0: instruction: 28
 parse/0:   ingredient: {name: "12", value: 0, type: 6, properties: ["12": "point"]}
 after-brace/0: recipe f
 after-brace/0: next-ingredient ...
diff --git a/cpp/.traces/rewind_ingredients b/cpp/.traces/rewind_ingredients
new file mode 100644
index 00000000..9c36302a
--- /dev/null
+++ b/cpp/.traces/rewind_ingredients
@@ -0,0 +1,29 @@
+parse/0: instruction: 1001
+parse/0:   ingredient: {name: "2", value: 0, type: 0, properties: ["2": "literal"]}
+parse/0: instruction: 25
+parse/0:   product: {name: "12", value: 0, type: 1, properties: ["12": "integer"]}
+parse/0: instruction: 25
+parse/0:   product: {name: "_", value: 0, type: 0, properties: ["_": "dummy"]}
+parse/0:   product: {name: "1", value: 0, type: 3, properties: ["1": "boolean"]}
+parse/0: instruction: 26
+parse/0: instruction: 25
+parse/0:   product: {name: "13", value: 0, type: 1, properties: ["13": "integer"]}
+parse/0:   product: {name: "2", value: 0, type: 3, properties: ["2": "boolean"]}
+after-brace/0: recipe f
+after-brace/0: next-ingredient ...
+after-brace/0: next-ingredient ...
+after-brace/0: rewind-ingredients ...
+after-brace/0: next-ingredient ...
+after-brace/0: recipe main
+after-brace/0: f ...
+run/0: instruction main/0
+run/0: instruction f/0
+run/0: product 0 is 2
+mem/0: storing 2 in location 12
+run/0: instruction f/1
+mem/0: storing 0 in location 1
+run/0: instruction f/2
+run/0: instruction f/3
+run/0: product 0 is 2
+mem/0: storing 2 in location 13
+mem/0: storing 1 in location 2
diff --git a/cpp/.traces/string-append-1 b/cpp/.traces/string-append-1
index 6af54b66..cb775809 100644
--- a/cpp/.traces/string-append-1
+++ b/cpp/.traces/string-append-1
@@ -1,7 +1,7 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "hello,", value: 0, type: 0, properties: ["hello,": "literal-string"]}
 parse/0:   product: {name: "1", value: 0, type: 2-5-4, properties: ["1": "address":"array":"character", "raw": ]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: " world!", value: 0, type: 0, properties: [" world!": "literal-string"]}
 parse/0:   product: {name: "2", value: 0, type: 2-5-4, properties: ["2": "address":"array":"character", "raw": ]}
 parse/0: instruction: 106
diff --git a/cpp/.traces/string-equal-common-lengths-but-distinct b/cpp/.traces/string-equal-common-lengths-but-distinct
index 8cb6a307..2a35f900 100644
--- a/cpp/.traces/string-equal-common-lengths-but-distinct
+++ b/cpp/.traces/string-equal-common-lengths-but-distinct
@@ -1,11 +1,11 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "location", value: 0, type: 0, properties: ["location": "type"]}
 parse/0:   ingredient: {name: "30", value: 0, type: 0, properties: ["30": "literal"]}
 parse/0:   product: {name: "default-space", value: 0, type: 2-5-1, properties: ["default-space": "address":"array":"location"]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "abc", value: 0, type: 0, properties: ["abc": "literal-string"]}
 parse/0:   product: {name: "x", value: 0, type: 2-5-4, properties: ["x": "address":"array":"character"]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "abd", value: 0, type: 0, properties: ["abd": "literal-string"]}
 parse/0:   product: {name: "y", value: 0, type: 2-5-4, properties: ["y": "address":"array":"character"]}
 parse/0: instruction: 100
diff --git a/cpp/.traces/string-equal-distinct-lengths b/cpp/.traces/string-equal-distinct-lengths
index 62d0518b..0d8e4a43 100644
--- a/cpp/.traces/string-equal-distinct-lengths
+++ b/cpp/.traces/string-equal-distinct-lengths
@@ -1,11 +1,11 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "location", value: 0, type: 0, properties: ["location": "type"]}
 parse/0:   ingredient: {name: "30", value: 0, type: 0, properties: ["30": "literal"]}
 parse/0:   product: {name: "default-space", value: 0, type: 2-5-1, properties: ["default-space": "address":"array":"location"]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "abc", value: 0, type: 0, properties: ["abc": "literal-string"]}
 parse/0:   product: {name: "x", value: 0, type: 2-5-4, properties: ["x": "address":"array":"character"]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "abcd", value: 0, type: 0, properties: ["abcd": "literal-string"]}
 parse/0:   product: {name: "y", value: 0, type: 2-5-4, properties: ["y": "address":"array":"character"]}
 parse/0: instruction: 100
diff --git a/cpp/.traces/string-equal-identical b/cpp/.traces/string-equal-identical
index 41e08402..c81ae818 100644
--- a/cpp/.traces/string-equal-identical
+++ b/cpp/.traces/string-equal-identical
@@ -1,11 +1,11 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "location", value: 0, type: 0, properties: ["location": "type"]}
 parse/0:   ingredient: {name: "30", value: 0, type: 0, properties: ["30": "literal"]}
 parse/0:   product: {name: "default-space", value: 0, type: 2-5-1, properties: ["default-space": "address":"array":"location"]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "abc", value: 0, type: 0, properties: ["abc": "literal-string"]}
 parse/0:   product: {name: "x", value: 0, type: 2-5-4, properties: ["x": "address":"array":"character"]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "abc", value: 0, type: 0, properties: ["abc": "literal-string"]}
 parse/0:   product: {name: "y", value: 0, type: 2-5-4, properties: ["y": "address":"array":"character"]}
 parse/0: instruction: 100
diff --git a/cpp/.traces/string-equal-reflexive b/cpp/.traces/string-equal-reflexive
index c9de76a7..0a73b72f 100644
--- a/cpp/.traces/string-equal-reflexive
+++ b/cpp/.traces/string-equal-reflexive
@@ -1,8 +1,8 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "location", value: 0, type: 0, properties: ["location": "type"]}
 parse/0:   ingredient: {name: "30", value: 0, type: 0, properties: ["30": "literal"]}
 parse/0:   product: {name: "default-space", value: 0, type: 2-5-1, properties: ["default-space": "address":"array":"location"]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "abc", value: 0, type: 0, properties: ["abc": "literal-string"]}
 parse/0:   product: {name: "x", value: 0, type: 2-5-4, properties: ["x": "address":"array":"character"]}
 parse/0: instruction: 100
diff --git a/cpp/.traces/string-equal-with-empty b/cpp/.traces/string-equal-with-empty
index 56be4087..dd3fe782 100644
--- a/cpp/.traces/string-equal-with-empty
+++ b/cpp/.traces/string-equal-with-empty
@@ -1,11 +1,11 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "location", value: 0, type: 0, properties: ["location": "type"]}
 parse/0:   ingredient: {name: "30", value: 0, type: 0, properties: ["30": "literal"]}
 parse/0:   product: {name: "default-space", value: 0, type: 2-5-1, properties: ["default-space": "address":"array":"location"]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "", value: 0, type: 0, properties: ["": "literal-string"]}
 parse/0:   product: {name: "x", value: 0, type: 2-5-4, properties: ["x": "address":"array":"character"]}
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "abcd", value: 0, type: 0, properties: ["abcd": "literal-string"]}
 parse/0:   product: {name: "y", value: 0, type: 2-5-4, properties: ["y": "address":"array":"character"]}
 parse/0: instruction: 100
diff --git a/cpp/.traces/string_literal b/cpp/.traces/string_literal
index 5bdbb1bf..47954e92 100644
--- a/cpp/.traces/string_literal
+++ b/cpp/.traces/string_literal
@@ -1,3 +1,3 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "abc def", value: 0, type: 0, properties: ["abc def": "literal-string"]}
 parse/0:   product: {name: "1", value: 0, type: 2-5-4, properties: ["1": "address":"array":"character"]}
diff --git a/cpp/.traces/string_literal_nested b/cpp/.traces/string_literal_nested
index 23f3c6f3..3609140b 100644
--- a/cpp/.traces/string_literal_nested
+++ b/cpp/.traces/string_literal_nested
@@ -1,3 +1,3 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "abc [def]", value: 0, type: 0, properties: ["abc [def]": "literal-string"]}
 parse/0:   product: {name: "1", value: 0, type: 2-5-4, properties: ["1": "address":"array":"character"]}
diff --git a/cpp/.traces/string_literal_with_colons b/cpp/.traces/string_literal_with_colons
index dcd49ba6..520ccf74 100644
--- a/cpp/.traces/string_literal_with_colons
+++ b/cpp/.traces/string_literal_with_colons
@@ -1,3 +1,3 @@
-parse/0: instruction: 33
+parse/0: instruction: 35
 parse/0:   ingredient: {name: "abc:def/ghi", value: 0, type: 0, properties: ["abc:def/ghi": "literal-string"]}
 parse/0:   product: {name: "1", value: 0, type: 2-5-4, properties: ["1": "address":"array":"character"]}
diff --git a/cpp/036call_ingredient b/cpp/036call_ingredient
index 9f156d65..f71be902 100644
--- a/cpp/036call_ingredient
+++ b/cpp/036call_ingredient
@@ -62,3 +62,68 @@ case NEXT_INGREDIENT: {
   }
   break;
 }
+
+:(scenario "rewind_ingredients")
+recipe main [
+  f 2:literal
+]
+recipe f [
+  12:integer <- next-ingredient  # consume ingredient
+  _, 1:boolean <- next-ingredient  # will not find any ingredients
+  rewind-ingredients
+  13:integer, 2:boolean <- next-ingredient  # will find ingredient again
+]
++mem: storing 2 in location 12
++mem: storing 0 in location 1
++mem: storing 2 in location 13
++mem: storing 1 in location 2
+
+:(before "End Primitive Recipe Declarations")
+REWIND_INGREDIENTS,
+:(before "End Primitive Recipe Numbers")
+Recipe_number["rewind-ingredients"] = REWIND_INGREDIENTS;
+:(before "End Primitive Recipe Implementations")
+case REWIND_INGREDIENTS: {
+  rr.calls.top().next_ingredient_to_process = 0;
+  break;
+}
+
+:(scenario "ingredient")
+recipe main [
+  f 1:literal, 2:literal
+]
+recipe f [
+  12:integer <- ingredient 1:literal  # consume second ingredient first
+  13:integer, 1:boolean <- next-ingredient  # next-ingredient tries to scan past that
+]
++mem: storing 2 in location 12
++mem: storing 0 in location 1
+
+:(before "End Primitive Recipe Declarations")
+INGREDIENT,
+:(before "End Primitive Recipe Numbers")
+Recipe_number["ingredient"] = INGREDIENT;
+:(before "End Primitive Recipe Implementations")
+case INGREDIENT: {
+  if (static_cast<size_t>(instructions[pc].ingredients[0].value) < rr.calls.top().ingredient_atoms.size()) {
+    rr.calls.top().next_ingredient_to_process = instructions[pc].ingredients[0].value;
+    trace("run") << "product 0 is "
+        << rr.calls.top().ingredient_atoms[rr.calls.top().next_ingredient_to_process][0];
+    write_memory(instructions[pc].products[0],
+        rr.calls.top().ingredient_atoms[rr.calls.top().next_ingredient_to_process]);
+    if (instructions[pc].products.size() > 1) {
+      vector<int> ingredient_exists;
+      ingredient_exists.push_back(1);
+      write_memory(instructions[pc].products[1], ingredient_exists);
+    }
+    ++rr.calls.top().next_ingredient_to_process;
+  }
+  else {
+    if (instructions[pc].products.size() > 1) {
+      vector<int> no_ingredient;
+      no_ingredient.push_back(0);
+      write_memory(instructions[pc].products[1], no_ingredient);
+    }
+  }
+  break;
+}