1 //: Calls can take ingredients just like primitives. To access a recipe's
  2 //: ingredients, use 'next-ingredient'.
  3 
  4 :(scenario next_ingredient)
  5 def main [
  6   f 2
  7 ]
  8 def f [
  9   12:num <- next-ingredient
 10   13:num <- add 1, 12:num
 11 ]
 12 +mem: storing 3 in location 13
 13 
 14 :(scenario next_ingredient_missing)
 15 def main [
 16   f
 17 ]
 18 def f [
 19   _, 12:num <- next-ingredient
 20 ]
 21 +mem: storing 0 in location 12
 22 
 23 :(before "End call Fields")
 24 vector<vector<double> > ingredient_atoms;
 25 vector<reagent> ingredients;
 26 int next_ingredient_to_process;
 27 :(before "End call Constructor")
 28 next_ingredient_to_process = 0;
 29 
 30 :(before "End Call Housekeeping")
 31 for (int i = 0;  i < SIZE(ingredients);  ++i) {
 32   current_call().ingredient_atoms.push_back(ingredients.at(i));
 33   reagent/*copy*/ ingredient = call_instruction.ingredients.at(i);
 34   // End Compute Call Ingredient
 35   current_call().ingredients.push_back(ingredient);
 36   // End Populate Call Ingredient
 37 }
 38 
 39 :(before "End Primitive Recipe Declarations")
 40 NEXT_INGREDIENT,
 41 :(before "End Primitive Recipe Numbers")
 42 put(Recipe_ordinal, "next-ingredient", NEXT_INGREDIENT);
 43 :(before "End Primitive Recipe Checks")
 44 case NEXT_INGREDIENT: {
 45   if (!inst.ingredients.empty()) {
 46     raise << maybe(get(Recipe, r).name) << "'next-ingredient' didn't expect any ingredients in '" << inst.original_string << "'\n" << end();
 47     break;
 48   }
 49   break;
 50 }
 51 :(before "End Primitive Recipe Implementations")
 52 case NEXT_INGREDIENT: {
 53   assert(!Current_routine->calls.empty());
 54   if (current_call().next_ingredient_to_process < SIZE(current_call().ingredient_atoms)) {
 55     reagent/*copy*/ product = current_instruction().products.at(0);
 56     // End Preprocess NEXT_INGREDIENT product
 57     if (current_recipe_name() == "main") {
 58       // no ingredient types since the call might be implicit; assume ingredients are always strings
 59       // todo: how to test this?
 60       if (!is_mu_text(product))
 61         raise << "main: wrong type for ingredient '" << product.original_string << "'\n" << end();
 62     }
 63     else if (!types_coercible(product,
 64                               current_call().ingredients.at(current_call().next_ingredient_to_process))) {
 65       raise << maybe(current_recipe_name()) << "wrong type for ingredient '" << product.original_string << "'\n" << end();
 66       // End next-ingredient Type Mismatch Error
 67     }
 68     products.push_back(
 69         current_call().ingredient_atoms.at(current_call().next_ingredient_to_process));
 70     assert(SIZE(products) == 1);  products.resize(2);  // push a new vector
 71     products.at(1).push_back(1);
 72     ++current_call().next_ingredient_to_process;
 73   }
 74   else {
 75     if (SIZE(current_instruction().products) < 2)
 76       raise << maybe(current_recipe_name()) << "no ingredient to save in '" << current_instruction().products.at(0).original_string << "'\n" << end();
 77     if (current_instruction().products.empty()) break;
 78     products.resize(2);
 79     // pad the first product with sufficient zeros to match its type
 80     products.at(0).resize(size_of(current_instruction().products.at(0)));
 81     products.at(1).push_back(0);
 82   }
 83   break;
 84 }
 85 
 86 :(scenario next_ingredient_fail_on_missing)
 87 % Hide_errors = true;
 88 def main [
 89   f
 90 ]
 91 def f [
 92   11:num <- next-ingredient
 93 ]
 94 +error: f: no ingredient to save in '11:num'
 95 
 96 :(scenario rewind_ingredients)
 97 def main [
 98   f 2
 99 ]
100 def f [
101   12:num <- next-ingredient  # consume ingredient
102   _, 1:bool <- next-ingredient  # will not find any ingredients
103   rewind-ingredients
104   13:num, 2:bool <- next-ingredient  # will find ingredient again
105 ]
106 +mem: storing 2 in location 12
107 +mem: storing 0 in location 1
108 +mem: storing 2 in location 13
109 +mem: storing 1 in location 2
110 
111 :(before "End Primitive Recipe Declarations")
112 REWIND_INGREDIENTS,
113 :(before "End Primitive Recipe Numbers")
114 put(Recipe_ordinal, "rewind-ingredients", REWIND_INGREDIENTS);
115 :(before "End Primitive Recipe Checks")
116 case REWIND_INGREDIE#39;+lineNum;
  }
  lineElem = document.getElementById(lineNum);
  /* Always jump to new location even if the line was hidden inside a fold, or
   * we corrected the raw number to a line ID.
   */
  if (lineElem) {
    lineElem.scrollIntoView(true);
  }
  return true;
}
if ('onhashchange' in window) {
  window.onhashchange = JumpToLine;
}

-->
</script>
</head>
<body onload='JumpToLine();'>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr"> 1 </span><span class="Comment"># compare immutable-error.mu</span>
<span id="L2" class="LineNr"> 2 </span>
<span id="L3" class="LineNr"> 3 </span><span class="muRecipe">def</span> <a href='mutable.mu.html#L3'>main</a> [
<span id="L4" class="LineNr"> 4 </span>  <span class="Constant">local-scope</span>
<span id="L5" class="LineNr"> 5 </span>  x:&amp;:num <span class="Special">&lt;-</span> new <span class="Constant">number:type</span>
<span id="L6" class="LineNr"> 6 </span>  <a href='mutable.mu.html#L9'>foo</a> x
<span id="L7" class="LineNr"> 7 </span>]
<span id="L8" class="LineNr"> 8 </span>
<span id="L9" class="LineNr"> 9 </span><span class="muRecipe">def</span> <a href='mutable.mu.html#L9'>foo</a> x:&amp;:num<span class="muRecipe"> -&gt; </span>x:&amp;:num [
<span id="L10" class="LineNr">10 </span>  <span class="Constant">local-scope</span>
<span id="L11" class="LineNr">11 </span>  <span class="Constant">load-inputs</span>
<span id="L12" class="LineNr">12 </span>  *x <span class="Special">&lt;-</span> copy<span class="Constant"> 34</span>
<span id="L13" class="LineNr">13 </span>]
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->
ss="Identifier">return x.type 177 && !x.type->atom 178 && x.type->left->atom 179 && x.type->left->value == get(Type_ordinal, "address") 180 && x.type->right 181 && !x.type->right->atom 182 && x.type->right->left->atom 183 && x.type->right->left->value == get(Type_ordinal, "array") 184 && x.type->right->right 185 && !x.type->right->right->atom 186 && x.type->right->right->left->value == get(Type_ordinal, "character") 187 && x.type->right->right->right == NULL; 188 }