about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-04-10 20:47:44 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-04-10 20:55:10 -0700
commit5f141f6a461bfaf23cb75603b18c09d65a8d79af (patch)
treee246faa3c58ef1a4db34b8739ad1bb249b62f230
parent5939c226b41d6876aa7a36833a01a241925ddd00 (diff)
downloadmu-5f141f6a461bfaf23cb75603b18c09d65a8d79af.tar.gz
2829 - issues while switching to 'put'
1. It turns out we couldn't overload 'get' and 'get-address' until now,
because transform_names looks for those names, and the
resolve_ambiguous_calls transform happens before transform_names. Why
does resolve_ambiguous_calls happen before transform_names? Because if
my students made mistakes in the ingredients to an instruction they got
overzealous errors from resolve_ambiguous_calls. Now this impacts 'put'
as well, which is already overloaded for tables. Not sure what to do
about this; I'm going to go back to the overzealous errors, and just
teach students to visually scan past them for now.

2. I need addresses in a third place besides storing to containers and
arrays, and managing the heap -- to synchronize routines.
wait-for-location requires an address. Not sure what to do about this..
-rw-r--r--042name.cc10
-rw-r--r--056static_dispatch.cc20
-rw-r--r--070text.mu29
-rw-r--r--072channel.mu19
4 files changed, 27 insertions, 51 deletions
diff --git a/042name.cc b/042name.cc
index 8cd6cd4f..503589c7 100644
--- a/042name.cc
+++ b/042name.cc
@@ -197,7 +197,7 @@ def main [
 -error: main: mixing variable names and numeric addresses
 $error: 0
 
-//:: Support element names for containers in 'get' and 'get-address'.
+//:: Support element names for containers in 'get' and 'get-address' and 'put'.
 
 :(scenario transform_names_transforms_container_elements)
 def main [
@@ -210,13 +210,13 @@ def main [
 
 :(before "End transform_names(inst) Special-cases")
 // replace element names of containers with offsets
-if (inst.name == "get" || inst.name == "get-address") {
-  if (SIZE(inst.ingredients) != 2) {
-    raise << maybe(get(Recipe, r).name) << "exactly 2 ingredients expected in '" << to_original_string(inst) << "'\n" << end();
+if (inst.name == "get" || inst.name == "get-address" || inst.name == "put") {
+  if (SIZE(inst.ingredients) < 2) {
+    raise << maybe(get(Recipe, r).name) << "2 or more ingredients expected in '" << to_original_string(inst) << "'\n" << end();
     break;
   }
   if (!is_literal(inst.ingredients.at(1)))
-    raise << maybe(get(Recipe, r).name) << "expected ingredient 1 of " << (inst.name == "get" ? "'get'" : "'get-address'") << " to have type 'offset'; got " << inst.ingredients.at(1).original_string << '\n' << end();
+    raise << maybe(get(Recipe, r).name) << "expected ingredient 1 of '" << inst.name << "' to have type 'offset'; got " << inst.ingredients.at(1).original_string << '\n' << end();
   if (inst.ingredients.at(1).name.find_first_not_of("0123456789") != string::npos) {
     // since first non-address in base type must be a container, we don't have to canonize
     type_ordinal base_type = skip_addresses(inst.ingredients.at(0).type);
diff --git a/056static_dispatch.cc b/056static_dispatch.cc
index 1d57872d..8d1d27b7 100644
--- a/056static_dispatch.cc
+++ b/056static_dispatch.cc
@@ -134,7 +134,7 @@ for (int i = 0; i < SIZE(caller.products); ++i)
   check_or_set_invalid_types(caller.products.at(i).type, maybe(caller.name), "recipe header product");
 
 //: after filling in all missing types (because we'll be introducing 'blank' types in this transform in a later layer, for shape-shifting recipes)
-:(after "Transform.push_back(transform_names)")
+:(after "End Type Modifying Transforms")
 Transform.push_back(resolve_ambiguous_calls);  // idempotent
 
 //: In a later layer we'll introduce recursion in resolve_ambiguous_calls, by
@@ -545,23 +545,5 @@ def! foo x:address:number -> y:number [
 +mem: storing 34 in location 2
 $error: 0
 
-:(scenario dispatch_errors_come_after_unknown_name_errors)
-% Hide_errors = true;
-def main [
-  y:number <- foo x
-]
-def foo a:number -> b:number [
-  local-scope
-  load-ingredients
-  return 34
-]
-def foo a:boolean -> b:number [
-  local-scope
-  load-ingredients
-  return 35
-]
-+error: main: missing type for x in 'y:number <- foo x'
-+error: main: failed to find a matching call for 'y:number <- foo x'
-
 :(before "End Includes")
 using std::abs;
diff --git a/070text.mu b/070text.mu
index 24317a59..386fee22 100644
--- a/070text.mu
+++ b/070text.mu
@@ -128,10 +128,9 @@ def new-buffer capacity:number -> result:address:shared:buffer [
   local-scope
   load-ingredients
   result <- new buffer:type
-  len:address:number <- get-address *result, length:offset
-  *len:address:number <- copy 0
-  s:address:address:shared:array:character <- get-address *result, data:offset
-  *s <- new character:type, capacity
+  *result <- put *result, length:offset, 0
+  data:address:shared:array:character <- new character:type, capacity
+  *result <- put *result, data:offset, data
   return result
 ]
 
@@ -139,18 +138,18 @@ def grow-buffer in:address:shared:buffer -> in:address:shared:buffer [
   local-scope
   load-ingredients
   # double buffer size
-  x:address:address:shared:array:character <- get-address *in, data:offset
-  oldlen:number <- length **x
+  olddata:address:shared:array:character <- get *in, data:offset
+  oldlen:number <- length *olddata
   newlen:number <- multiply oldlen, 2
-  olddata:address:shared:array:character <- copy *x
-  *x <- new character:type, newlen
+  newdata:address:shared:array:character <- new character:type, newlen
+  *in <- put *in, data:offset, newdata
   # copy old contents
   i:number <- copy 0
   {
     done?:boolean <- greater-or-equal i, oldlen
     break-if done?
     src:character <- index *olddata, i
-    dest:address:character <- index-address **x, i
+    dest:address:character <- index-address *newdata, i
     *dest <- copy src
     i <- add i, 1
     loop
@@ -186,14 +185,15 @@ def append buf:address:shared:buffer, x:_elem -> buf:address:shared:buffer [
 def append in:address:shared:buffer, c:character -> in:address:shared:buffer [
   local-scope
   load-ingredients
-  len:address:number <- get-address *in, length:offset
+  len:number <- get *in, length:offset
   {
     # backspace? just drop last character if it exists and return
     backspace?:boolean <- equal c, 8/backspace
     break-unless backspace?
-    empty?:boolean <- lesser-or-equal *len, 0
+    empty?:boolean <- lesser-or-equal len, 0
     return-if empty?
-    *len <- subtract *len, 1
+    len <- subtract len, 1
+    put *in, length:offset, len
     return
   }
   {
@@ -203,9 +203,10 @@ def append in:address:shared:buffer, c:character -> in:address:shared:buffer [
     in <- grow-buffer in
   }
   s:address:shared:array:character <- get *in, data:offset
-  dest:address:character <- index-address *s, *len
+  dest:address:character <- index-address *s, len
   *dest <- copy c
-  *len <- add *len, 1
+  len <- add len, 1
+  put *in, length:offset, len
 ]
 
 scenario buffer-append-works [
diff --git a/072channel.mu b/072channel.mu
index f1a4480d..0e9b0041 100644
--- a/072channel.mu
+++ b/072channel.mu
@@ -46,22 +46,15 @@ def new-channel capacity:number -> in:address:shared:source:_elem, out:address:s
   local-scope
   load-ingredients
   result:address:shared:channel:_elem <- new {(channel _elem): type}
-  # result.first-full = 0
-  full:address:number <- get-address *result, first-full:offset
-  *full <- copy 0
-  # result.first-free = 0
-  free:address:number <- get-address *result, first-free:offset
-  *free <- copy 0
-  # result.data = new location[ingredient+1]
+  *result <- put *result, first-full:offset, 0
+  *result <- put *result, first-free:offset, 0
   capacity <- add capacity, 1  # unused slot for 'full?' below
-  dest:address:address:shared:array:_elem <- get-address *result, data:offset
-  *dest <- new _elem:type, capacity
+  data:address:shared:array:_elem <- new _elem:type, capacity
+  *result <- put *result, data:offset, data
   in <- new {(source _elem): type}
-  chan:address:address:shared:channel:_elem <- get-address *in, chan:offset
-  *chan <- copy result
+  *in <- put *in, chan:offset, result
   out <- new {(sink _elem): type}
-  chan:address:address:shared:channel:_elem <- get-address *out, chan:offset
-  *chan <- copy result
+  *out <- put *out, chan:offset, result
 ]
 
 def write out:address:shared:sink:_elem, val:_elem -> out:address:shared:sink:_elem [