about summary refs log tree commit diff stats
path: root/074console.mu
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-07-28 15:03:46 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-07-28 15:03:46 -0700
commit286ca5a4e85c2c3d4e5bd5e303990188a727131c (patch)
tree5157820360fdd44397954aa35a96d46e9dba03f5 /074console.mu
parentbc6436927640603675e2e700007f53c5ab213869 (diff)
downloadmu-286ca5a4e85c2c3d4e5bd5e303990188a727131c.tar.gz
1869 - rename the /deref property to /lookup
Should be a little bit more mnemonic.
Diffstat (limited to '074console.mu')
-rw-r--r--074console.mu24
1 files changed, 12 insertions, 12 deletions
diff --git a/074console.mu b/074console.mu
index d405f6bd..031f0781 100644
--- a/074console.mu
+++ b/074console.mu
@@ -22,12 +22,12 @@ container console [
 recipe new-fake-console [
   local-scope
   result:address:console <- new console:type
-  buf:address:address:array:character <- get-address result:address:console/deref, data:offset
+  buf:address:address:array:character <- get-address result:address:console/lookup, data:offset
 #?   $start-tracing #? 1
-  buf:address:address:array:character/deref <- next-ingredient
+  buf:address:address:array:character/lookup <- next-ingredient
 #?   $stop-tracing #? 1
-  idx:address:number <- get-address result:address:console/deref, index:offset
-  idx:address:number/deref <- copy 0
+  idx:address:number <- get-address result:address:console/lookup, index:offset
+  idx:address:number/lookup <- copy 0
   reply result:address:console
 ]
 
@@ -36,17 +36,17 @@ recipe read-event [
   x:address:console <- next-ingredient
   {
     break-unless x:address:console
-    idx:address:number <- get-address x:address:console/deref, index:offset
-    buf:address:array:event <- get x:address:console/deref, data:offset
+    idx:address:number <- get-address x:address:console/lookup, index:offset
+    buf:address:array:event <- get x:address:console/lookup, data:offset
     {
-      max:number <- length buf:address:array:event/deref
-      done?:boolean <- greater-or-equal idx:address:number/deref, max:number
+      max:number <- length buf:address:array:event/lookup
+      done?:boolean <- greater-or-equal idx:address:number/lookup, max:number
       break-unless done?:boolean
       dummy:address:event <- new event:type
-      reply dummy:address:event/deref, x:address:console/same-as-ingredient:0, 1/found, 1/quit
+      reply dummy:address:event/lookup, x:address:console/same-as-ingredient:0, 1/found, 1/quit
     }
-    result:event <- index buf:address:array:event/deref, idx:address:number/deref
-    idx:address:number/deref <- add idx:address:number/deref, 1
+    result:event <- index buf:address:array:event/lookup, idx:address:number/lookup
+    idx:address:number/lookup <- add idx:address:number/lookup, 1
     reply result:event, x:address:console/same-as-ingredient:0, 1/found, 0/quit
   }
   # real event source is infrequent; avoid polling it too much
@@ -73,7 +73,7 @@ recipe read-key [
   c:address:character <- maybe-convert x:event, text:variant
   reply-unless c:address:character, 0, console:address/same-as-ingredient:0, 0/found, 0/quit
 #?   $print [aaa 4] #? 1
-  reply c:address:character/deref, console:address/same-as-ingredient:0, 1/found, 0/quit
+  reply c:address:character/lookup, console:address/same-as-ingredient:0, 1/found, 0/quit
 ]
 
 recipe send-keys-to-channel [
{ color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
//: Calls can also generate products, using 'reply'.

:(scenario reply)
recipe main [
  1:number, 2:number <- f 34
]
recipe f [
  12:number <- next-ingredient
  13:number <- add 1, 12:number
  reply 12:number, 13:number
]
+mem: storing 34 in location 1
+mem: storing 35 in location 2

:(before "End Primitive Recipe Declarations")
REPLY,
:(before "End Primitive Recipe Numbers")
Recipe_ordinal["reply"] = REPLY;
:(before "End Primitive Recipe Implementations")
case REPLY: {
  // Starting Reply
  const instruction& reply_inst = current_instruction();  // save pointer into recipe before pop
  const string& callee = current_recipe_name();
  --Callstack_depth;
  Current_routine->calls.pop_front();
  // just in case 'main' returns a value, drop it for now
  if (Current_routine->calls.empty()) goto stop_running_current_routine;
  const instruction& caller_instruction = current_instruction();
  // make reply products available to caller
  copy(ingredients.begin(), ingredients.end(), inserter(products, products.begin()));
  // check that any reply ingredients with /same-as-ingredient connect up
  // the corresponding ingredient and product in the caller.
  if (SIZE(caller_instruction.products) > SIZE(ingredients))
    raise << "too few values replied from " << callee << '\n' << end();
  for (long long int i = 0; i < SIZE(caller_instruction.products); ++i) {
    trace(Primitive_recipe_depth, "run") << "result " << i << " is " << to_string(ingredients.at(i)) << end();
    if (has_property(reply_inst.ingredients.at(i), "same-as-ingredient")) {
      vector<string> tmp = property(reply_inst.ingredients.at(i), "same-as-ingredient");
      if (SIZE(tmp) != 1) {
        raise << current_recipe_name() << ": 'same-as-ingredient' metadata should take exactly one value in " << reply_inst.to_string() << '\n' << end();
        goto finish_reply;
      }
      long long int ingredient_index = to_integer(tmp.at(0));
      if (ingredient_index >= SIZE(caller_instruction.ingredients))
        raise << 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 << current_recipe_name() << ": 'same-as-ingredient' result " << caller_instruction.products.at(i).value << " from call to " << callee << " must be location " << caller_instruction.ingredients.at(ingredient_index).value << '\n' << end();
    }
  }
  // End Reply
  finish_reply:
  break;  // continue to process rest of *caller* instruction
}

//: Products can include containers and exclusive containers, addresses and arrays.
:(scenario reply_container)
recipe main [
  3:point <- f 2
]
recipe f [
  12:number <- next-ingredient
  13:number <- copy 35
  reply 12:point/raw  # unsafe
]
+run: result 0 is [2, 35]
+mem: storing 2 in location 3
+mem: storing 35 in location 4

//: In mu we'd like to assume that any instruction doesn't modify its
//: ingredients unless they're also products. The /same-as-ingredient inside
//: the recipe's 'reply' will help catch accidental misuse of such
//: 'ingredient-products' (sometimes called in-out parameters in other languages).

:(scenario reply_same_as_ingredient)
% Hide_warnings = true;
recipe main [
  1:number <- copy 0
  2:number <- test1 1:number  # call with different ingredient and product
]
recipe test1 [
  10:address:number <- next-ingredient
  reply 10:address:number/same-as-ingredient:0
]
+warn: main: 'same-as-ingredient' result 2 from call to test1 must be location 1

:(scenario reply_same_as_ingredient_dummy)
% Hide_warnings = true;
recipe main [
  1:number <- copy 0
  _ <- test1 1:number  # call with different ingredient and product
]
recipe test1 [
  10:address:number <- next-ingredient
  reply 10:address:number/same-as-ingredient:0
]
$warn: 0

:(code)
string to_string(const vector<double>& in) {
  if (in.empty()) return "[]";
  ostringstream out;
  if (SIZE(in) == 1) {
    out << in.at(0);
    return out.str();
  }
  out << "[";
  for (long long int i = 0; i < SIZE(in); ++i) {
    if (i > 0) out << ", ";
    out << in.at(i);
  }
  out << "]";
  return out.str();
}

//: Conditional reply.

:(scenario reply_if)
recipe main [
  1:number <- test1
]
recipe test1 [
  reply-if 0, 34
  reply 35
]
+mem: storing 35 in location 1

:(scenario reply_if2)
recipe main [
  1:number <- test1
]
recipe test1 [
  reply-if 1, 34
  reply 35
]
+mem: storing 34 in location 1

:(before "End Rewrite Instruction(curr)")
// rewrite `reply-if a, b, c, ...` to
//   ```
//   jump-unless a, 1:offset
//   reply b, c, ...
//   ```
if (curr.name == "reply-if") {
  if (curr.products.empty()) {
    curr.operation = Recipe_ordinal["jump-unless"];
    curr.name = "jump-unless";
    vector<reagent> results;
    copy(++curr.ingredients.begin(), curr.ingredients.end(), inserter(results, results.end()));
    curr.ingredients.resize(1);
    curr.ingredients.push_back(reagent("1:offset"));
    result.steps.push_back(curr);
    curr.clear();
    curr.operation = Recipe_ordinal["reply"];
    curr.name = "reply";
    curr.ingredients.swap(results);
  }
  else {
    raise << "'reply-if' never yields any products\n" << end();
  }
}
// rewrite `reply-unless a, b, c, ...` to
//   ```
//   jump-if a, 1:offset
//   reply b, c, ...
//   ```
if (curr.name == "reply-unless") {
  if (curr.products.empty()) {
    curr.operation = Recipe_ordinal["jump-if"];
    curr.name = "jump-if";
    vector<reagent> results;
    copy(++curr.ingredients.begin(), curr.ingredients.end(), inserter(results, results.end()));
    curr.ingredients.resize(1);
    curr.ingredients.push_back(reagent("1:offset"));
    result.steps.push_back(curr);
    curr.clear();
    curr.operation = Recipe_ordinal["reply"];
    curr.name = "reply";
    curr.ingredients.swap(results);
  }
  else {
    raise << "'reply-unless' never yields any products\n" << end();
  }
}