diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-11-10 19:19:53 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-11-10 19:19:53 -0800 |
commit | c1585c88fa61918a9c464f7d6eb5b1b4b107048b (patch) | |
tree | df2f317f1b5c4edfe21ebb0d9382e9dc68203521 | |
parent | c4e7c10d158fafb2289b2349a2aebe0459b8946f (diff) | |
download | mu-c1585c88fa61918a9c464f7d6eb5b1b4b107048b.tar.gz |
2417 - support mutable ingredients in headers
If a name repeats between ingredients, we raise an error. If a name repeats across ingredients and products, every call should share the same name across the corresponding ingredients and products.
-rw-r--r-- | 036call_reply.cc | 4 | ||||
-rw-r--r-- | 056recipe_header.cc | 105 | ||||
-rw-r--r-- | edit/002-typing.mu | 2 | ||||
-rw-r--r-- | edit/005-sandbox.mu | 13 | ||||
-rw-r--r-- | edit/006-sandbox-edit.mu | 8 | ||||
-rw-r--r-- | edit/008-sandbox-test.mu | 10 | ||||
-rw-r--r-- | edit/009-sandbox-trace.mu | 6 |
7 files changed, 96 insertions, 52 deletions
diff --git a/036call_reply.cc b/036call_reply.cc index 68bc533c..97853a2b 100644 --- a/036call_reply.cc +++ b/036call_reply.cc @@ -67,7 +67,7 @@ case REPLY: { if (ingredient_index >= SIZE(caller_instruction.ingredients)) raise_error << maybe(current_recipe_name()) << "'same-as-ingredient' metadata overflows ingredients in: " << caller_instruction.to_string() << '\n' << end(); if (!is_dummy(caller_instruction.products.at(i)) && caller_instruction.products.at(i).value != caller_instruction.ingredients.at(ingredient_index).value) - raise_error << maybe(current_recipe_name()) << "'same-as-ingredient' product from call to " << callee << " must be " << caller_instruction.ingredients.at(ingredient_index).original_string << " rather than " << caller_instruction.products.at(i).original_string << '\n' << end(); + raise_error << maybe(current_recipe_name()) << "'" << caller_instruction.to_string() << "' should write to " << caller_instruction.ingredients.at(ingredient_index).original_string << " rather than " << caller_instruction.products.at(i).original_string << '\n' << end(); } } // End Reply @@ -117,7 +117,7 @@ recipe test1 [ 10:number <- next-ingredient reply 10:number/same-as-ingredient:0 ] -+error: main: 'same-as-ingredient' product from call to test1 must be 1:number rather than 2:number ++error: main: '2:number <- test1 1:number' should write to 1:number rather than 2:number :(scenario reply_same_as_ingredient_dummy) # % Hide_errors = true; diff --git a/056recipe_header.cc b/056recipe_header.cc index 53670931..f59c26a4 100644 --- a/056recipe_header.cc +++ b/056recipe_header.cc @@ -134,10 +134,10 @@ recipe add2 x:number, y:number -> z:number [ +error: add2: replied with the wrong type at 'reply z' :(after "Transform.push_back(check_types_by_name)") -Transform.push_back(check_header_products); // idempotent +Transform.push_back(check_reply_instructions_against_header); // idempotent :(code) -void check_header_products(const recipe_ordinal r) { +void check_reply_instructions_against_header(const recipe_ordinal r) { const recipe& rr = get(Recipe, r); if (rr.products.empty()) return; trace(9991, "transform") << "--- checking reply instructions against header for " << rr.name << end(); @@ -154,6 +154,33 @@ void check_header_products(const recipe_ordinal r) { } } +:(scenario recipe_headers_check_for_duplicate_names) +% Hide_errors = true; +recipe add2 x:number, x:number -> z:number [ + local-scope + load-ingredients + reply z +] ++error: add2: x can't repeat in the ingredients + +:(before "End recipe Fields") +map<string, int> ingredient_index; + +:(after "Transform.push_back(insert_fragments)") +Transform.push_back(check_and_update_header_reagents); // idempotent + +:(code) +void check_and_update_header_reagents(const recipe_ordinal r) { + recipe& rr = get(Recipe, r); + if (rr.products.empty()) return; + trace(9991, "transform") << "--- checking reply instructions against header for " << rr.name << end(); + for (long long int i = 0; i < SIZE(rr.ingredients); ++i) { + if (contains_key(rr.ingredient_index, rr.ingredients.at(i).name)) + raise_error << maybe(rr.name) << rr.ingredients.at(i).name << " can't repeat in the ingredients\n" << end(); + put(rr.ingredient_index, rr.ingredients.at(i).name, i); + } +} + //: Deduce types from the header if possible. :(scenarios run) @@ -169,7 +196,7 @@ recipe add2 x:number, y:number -> z:number [ ] +mem: storing 8 in location 1 -:(before "Transform.push_back(check_header_products)") +:(before "Transform.push_back(check_reply_instructions_against_header)") Transform.push_back(deduce_types_from_header); // idempotent :(code) @@ -236,18 +263,40 @@ recipe add2 x:number, y:number -> z:number [ ] +mem: storing 8 in location 1 -:(after "Transform.push_back(insert_fragments)") -Transform.push_back(fill_in_reply_ingredients); +:(after "Transform.push_back(check_and_update_header_reagents)") +Transform.push_back(fill_in_reply_ingredients); // idempotent :(code) void fill_in_reply_ingredients(recipe_ordinal r) { - if (!get(Recipe, r).has_header) return; - trace(9991, "transform") << "--- fill in reply ingredients from header for recipe " << get(Recipe, r).name << end(); - for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) { - instruction& inst = get(Recipe, r).steps.at(i); - if (inst.name == "reply" && inst.ingredients.empty()) { - for (long long int i = 0; i < SIZE(get(Recipe, r).products); ++i) - inst.ingredients.push_back(get(Recipe, r).products.at(i)); + recipe& rr = get(Recipe, r); + if (!rr.has_header) return; + trace(9991, "transform") << "--- fill in reply ingredients from header for recipe " << rr.name << end(); + for (long long int i = 0; i < SIZE(rr.steps); ++i) { + instruction& inst = rr.steps.at(i); + if (inst.name == "reply" && inst.ingredients.empty()) + add_header_products(inst, rr); + } + // fall through reply + if (rr.steps.at(SIZE(rr.steps)-1).name != "reply") { + instruction inst; + inst.name = "reply"; + add_header_products(inst, rr); + rr.steps.push_back(inst); + } +} + +void add_header_products(instruction& inst, const recipe& rr) { + assert(inst.name == "reply"); + // collect any products with the same names as ingredients + for (long long int i = 0; i < SIZE(rr.products); ++i) { + // if the ingredient is missing, add it from the header + if (SIZE(inst.ingredients) == i) + inst.ingredients.push_back(rr.products.at(i)); + // if it's missing /same_as_ingredient, try to fill it in + if (contains_key(rr.ingredient_index, rr.products.at(i).name) && !has_property(inst.ingredients.at(i), "same_as_ingredient")) { + ostringstream same_as_ingredient; + same_as_ingredient << get(rr.ingredient_index, rr.products.at(i).name); + inst.ingredients.at(i).properties.push_back(pair<string, string_tree*>("same-as-ingredient", new string_tree(same_as_ingredient.str()))); } } } @@ -278,25 +327,6 @@ recipe add2 x:number, y:number -> z:number [ +transform: instruction: reply z:number +mem: storing 8 in location 1 -:(after "Transform.push_back(insert_fragments)") -Transform.push_back(deduce_fallthrough_reply); - -:(code) -void deduce_fallthrough_reply(const recipe_ordinal r) { - recipe& rr = get(Recipe, r); - if (rr.products.empty()) return; - if (rr.steps.empty()) return; - if (rr.steps.at(SIZE(rr.steps)-1).name != "reply") { - instruction inst; - inst.operation = REPLY; - inst.name = "reply"; - for (long long int i = 0; i < SIZE(rr.products); ++i) { - inst.ingredients.push_back(rr.products.at(i)); - } - rr.steps.push_back(inst); - } -} - :(scenario reply_on_fallthrough_already_exists) recipe main [ 1:number/raw <- add2 3, 5 @@ -310,3 +340,16 @@ recipe add2 x:number, y:number -> z:number [ +transform: instruction: reply z -transform: instruction: reply z:number +mem: storing 8 in location 1 + +:(scenario recipe_headers_perform_same_ingredient_check) +% Hide_errors = true; +recipe main [ + 1:number <- copy 34 + 2:number <- copy 34 + 3:number <- add2 1:number, 2:number +] +recipe add2 x:number, y:number -> x:number [ + local-scope + load-ingredients +] ++error: main: '3:number <- add2 1:number, 2:number' should write to 1:number rather than 3:number diff --git a/edit/002-typing.mu b/edit/002-typing.mu index bd69ae16..e766926a 100644 --- a/edit/002-typing.mu +++ b/edit/002-typing.mu @@ -259,7 +259,7 @@ recipe insert-at-cursor editor:address:editor-data, c:character, screen:address: ] # helper for tests -recipe editor-render screen:address:screen, editor:address:editor-data [ +recipe editor-render screen:address:screen, editor:address:editor-data -> screen:address:screen [ local-scope load-ingredients left:number <- get *editor, left:offset diff --git a/edit/005-sandbox.mu b/edit/005-sandbox.mu index 22d7ab68..358d148c 100644 --- a/edit/005-sandbox.mu +++ b/edit/005-sandbox.mu @@ -391,6 +391,7 @@ scenario run-updates-results [ 1:address:array:character <- new [ recipe foo [ z:number <- add 2, 2 +reply z ]] # sandbox editor contains an instruction without storing outputs 2:address:array:character <- new [foo] @@ -405,9 +406,9 @@ z:number <- add 2, 2 . ┊ . .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. .z:number <- add 2, 2 ┊ x. - .] ┊foo . - .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . - . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + .reply z ┊foo . + .] ┊4 . + .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. . ┊ . ] # make a change (incrementing one of the args to 'add'), then rerun @@ -426,9 +427,9 @@ z:number <- add 2, 2 . ┊ . .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. .z:number <- add 2, 3 ┊ x. - .] ┊foo . - .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊5 . - . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. + .reply z ┊foo . + .] ┊5 . + .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━. . ┊ . ] ] diff --git a/edit/006-sandbox-edit.mu b/edit/006-sandbox-edit.mu index 6c61916d..6f1af1d6 100644 --- a/edit/006-sandbox-edit.mu +++ b/edit/006-sandbox-edit.mu @@ -6,7 +6,7 @@ scenario clicking-on-a-sandbox-moves-it-to-editor [ # basic recipe 1:address:array:character <- new [ recipe foo [ - add 2, 2 + reply 4 ]] # run it 2:address:array:character <- new [foo] @@ -19,7 +19,7 @@ recipe foo [ . run (F4) . . ┊ . .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━. - . add 2, 2 ┊ x. + . reply 4 ┊ x. .] ┊foo . .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . . ┊━━━━━━━━━━━━━━━━━━━. @@ -37,7 +37,7 @@ recipe foo [ . run (F4) . . ┊foo . .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━. - . add 2, 2 ┊ . + . reply 4 ┊ . .] ┊ . .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ . . ┊ . @@ -54,7 +54,7 @@ recipe foo [ . run (F4) . . ┊0foo . .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━. - . add 2, 2 ┊ . + . reply 4 ┊ . .] ┊ . .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ . . ┊ . diff --git a/edit/008-sandbox-test.mu b/edit/008-sandbox-test.mu index fbc66aad..2c557c17 100644 --- a/edit/008-sandbox-test.mu +++ b/edit/008-sandbox-test.mu @@ -6,7 +6,7 @@ scenario sandbox-click-on-result-toggles-color-to-green [ # basic recipe 1:address:array:character <- new [ recipe foo [ - add 2, 2 + reply 4 ]] # run it 2:address:array:character <- new [foo] @@ -19,7 +19,7 @@ recipe foo [ . run (F4) . . ┊ . .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━. - . add 2, 2 ┊ x. + . reply 4 ┊ x. .] ┊foo . .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . . ┊━━━━━━━━━━━━━━━━━━━. @@ -51,13 +51,13 @@ recipe foo [ . run (F4) . .␣ ┊ . .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━. - . add 2, 2 ┊ x. + . reply 4 ┊ x. .] ┊foo . .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . . ┊━━━━━━━━━━━━━━━━━━━. . ┊ . ] - # now change the second arg of the 'add' + # now change the result # then rerun assume-console [ left-click 3, 11 # cursor to end of line @@ -75,7 +75,7 @@ recipe foo [ . . . . . . - . 5 . + . 3 . . . . . ] diff --git a/edit/009-sandbox-trace.mu b/edit/009-sandbox-trace.mu index 5e34e8d1..a67dc999 100644 --- a/edit/009-sandbox-trace.mu +++ b/edit/009-sandbox-trace.mu @@ -80,7 +80,7 @@ scenario sandbox-shows-app-trace-and-result [ 1:address:array:character <- new [ recipe foo [ stash [abc] - add 2, 2 + reply 4 ]] # run it 2:address:array:character <- new [foo] @@ -94,7 +94,7 @@ recipe foo [ . ┊ . .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━. . stash [abc] ┊ x. - . add 2, 2 ┊foo . + . reply 4 ┊foo . .] ┊4 . .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━. . ┊ . @@ -112,7 +112,7 @@ recipe foo [ . ┊ . .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━. . stash [abc] ┊ x. - . add 2, 2 ┊foo . + . reply 4 ┊foo . .] ┊abc . .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 . . ┊━━━━━━━━━━━━━━━━━━━. |