From dea902172dd62d14eebc5fed9e11542ebcdc88e6 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Wed, 27 Apr 2016 15:40:46 -0700 Subject: 2875 --- html/040brace.cc.html | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 'html/040brace.cc.html') diff --git a/html/040brace.cc.html b/html/040brace.cc.html index 6077150d..b0912d1e 100644 --- a/html/040brace.cc.html +++ b/html/040brace.cc.html @@ -396,6 +396,91 @@ def main [ ] +error: break-if expects 1 or 2 ingredients, but got none +//: Using break we can now implement conditional returns. + +:(scenario return_if) +def main [ + 1:number <- test1 +] +def test1 [ + return-if 0, 34 + return 35 +] ++mem: storing 35 in location 1 + +:(scenario return_if_2) +def main [ + 1:number <- test1 +] +def test1 [ + return-if 1, 34 + return 35 +] ++mem: storing 34 in location 1 + +:(before "End Rewrite Instruction(curr, recipe result)") +// rewrite `return-if a, b, c, ...` to +// ``` +// { +// break-unless a +// return b, c, ... +// } +// ``` +if (curr.name == "return-if" || curr.name == "reply-if") { + if (curr.products.empty()) { + emit_return_block(result, "break-unless", curr.ingredients); + curr.clear(); + } + else { + raise << "'" << curr.name << "' never yields any products\n" << end(); + } +} +// rewrite `return-unless a, b, c, ...` to +// ``` +// { +// break-if a +// return b, c, ... +// } +// ``` +if (curr.name == "return-unless" || curr.name == "reply-unless") { + if (curr.products.empty()) { + emit_return_block(result, "break-if", curr.ingredients); + curr.clear(); + } + else { + raise << "'" << curr.name << "' never yields any products\n" << end(); + } +} + +:(code) +void emit_return_block(recipe& out, const string& break_command, const vector<reagent>& ingredients) { + reagent condition = ingredients.at(0); + vector<reagent> return_ingredients; + copy(++ingredients.begin(), ingredients.end(), inserter(return_ingredients, return_ingredients.end())); + + // { + instruction open_label; open_label.is_label=true; open_label.label = "{"; + out.steps.push_back(open_label); + + // <break command> <condition> + instruction break_inst; + break_inst.operation = get(Recipe_ordinal, break_command); + break_inst.name = break_inst.old_name = break_command; + break_inst.ingredients.push_back(condition); + out.steps.push_back(break_inst); + + // return <return ingredients> + instruction return_inst; + return_inst.operation = get(Recipe_ordinal, "return"); + return_inst.name = "return"; + return_inst.ingredients.swap(return_ingredients); + out.steps.push_back(return_inst); + + // } + instruction close_label; close_label.is_label=true; close_label.label = "}"; + out.steps.push_back(close_label); +} + //: Make sure these pseudo recipes get consistent numbers in all tests, even //: though they aren't implemented. Allows greater flexibility in ordering //: transforms. -- cgit 1.4.1-2-gfad0