about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--021check_instruction.cc9
-rw-r--r--034exclusive_container.cc36
-rw-r--r--037abandon.cc12
-rw-r--r--061text.mu2
-rw-r--r--064list.mu4
-rw-r--r--065duplex_list.mu4
-rw-r--r--072recipe.cc2
7 files changed, 48 insertions, 21 deletions
diff --git a/021check_instruction.cc b/021check_instruction.cc
index d7628008..44f08f3f 100644
--- a/021check_instruction.cc
+++ b/021check_instruction.cc
@@ -71,14 +71,6 @@ def main [
 ]
 +error: main: can't copy '34' to '1:address:num'; types don't match
 
-:(scenario write_address_to_number_allowed)
-def main [
-  1:address:num <- copy 12/unsafe
-  2:num <- copy 1:address:num
-]
-+mem: storing 12 in location 2
-$error: 0
-
 :(scenario write_address_to_character_disallowed)
 % Hide_errors = true;
 def main [
@@ -114,7 +106,6 @@ def main [
 // types_match with some leniency
 bool types_coercible(const reagent& to, const reagent& from) {
   if (types_match(to, from)) return true;
-  if (is_mu_address(from) && is_real_mu_number(to)) return true;
   if (is_mu_boolean(from) && is_real_mu_number(to)) return true;
   if (is_real_mu_number(from) && is_mu_character(to)) return true;
   // End types_coercible Special-cases
diff --git a/034exclusive_container.cc b/034exclusive_container.cc
index 44161d7c..7704560a 100644
--- a/034exclusive_container.cc
+++ b/034exclusive_container.cc
@@ -457,3 +457,39 @@ def main [
 +mem: storing 1 in location 6
 +mem: storing 34 in location 7
 +mem: storing 35 in location 8
+
+//: a little helper: convert address to number
+
+:(before "End Primitive Recipe Declarations")
+DEADDRESS,
+:(before "End Primitive Recipe Numbers")
+put(Recipe_ordinal, "deaddress", DEADDRESS);
+:(before "End Primitive Recipe Checks")
+case DEADDRESS: {
+  // primary goal of these checks is to forbid address arithmetic
+  for (int i = 0;  i < SIZE(inst.ingredients);  ++i) {
+    if (!is_mu_address(inst.ingredients.at(i))) {
+      raise << maybe(get(Recipe, r).name) << "'deaddress' requires address ingredients, but got '" << inst.ingredients.at(i).original_string << "'\n" << end();
+      goto finish_checking_instruction;
+    }
+  }
+  if (SIZE(inst.products) > SIZE(inst.ingredients)) {
+    raise << maybe(get(Recipe, r).name) << "too many products in '" << to_original_string(inst) << "'\n" << end();
+    break;
+  }
+  for (int i = 0;  i < SIZE(inst.products);  ++i) {
+    if (!is_real_mu_number(inst.products.at(i))) {
+      raise << maybe(get(Recipe, r).name) << "'deaddress' requires number products, but got '" << inst.products.at(i).original_string << "'\n" << end();
+      goto finish_checking_instruction;
+    }
+  }
+  break;
+}
+:(before "End Primitive Recipe Implementations")
+case DEADDRESS: {
+  products.resize(SIZE(ingredients));
+  for (int i = 0;  i < SIZE(ingredients);  ++i) {
+    products.at(i).push_back(ingredients.at(i).at(0));
+  }
+  break;
+}
diff --git a/037abandon.cc b/037abandon.cc
index 5a4adbd1..d863b819 100644
--- a/037abandon.cc
+++ b/037abandon.cc
@@ -3,10 +3,10 @@
 :(scenario new_reclaim)
 def main [
   1:address:num <- new number:type
-  2:num <- copy 1:address:num  # because 1 will get reset during abandon below
+  2:num <- deaddress 1:address:num  # because 1 will get reset during abandon below
   abandon 1:address:num
   3:address:num <- new number:type  # must be same size as abandoned memory to reuse
-  4:num <- copy 3:address:num
+  4:num <- deaddress 3:address:num
   5:bool <- equal 2:num, 4:num
 ]
 # both allocations should have returned the same address
@@ -80,10 +80,10 @@ if (get_or_insert(Current_routine->free_list, size)) {
 :(scenario new_differing_size_no_reclaim)
 def main [
   1:address:num <- new number:type
-  2:num <- copy 1:address:num
+  2:num <- deaddress 1:address:num
   abandon 1:address:num
   3:address:array:num <- new number:type, 2  # different size
-  4:num <- copy 3:address:array:num
+  4:num <- deaddress 3:address:array:num
   5:bool <- equal 2:num, 4:num
 ]
 # no reuse
@@ -92,10 +92,10 @@ def main [
 :(scenario new_reclaim_array)
 def main [
   1:address:array:num <- new number:type, 2
-  2:num <- copy 1:address:array:num
+  2:num <- deaddress 1:address:array:num
   abandon 1:address:array:num
   3:address:array:num <- new number:type, 2  # same size
-  4:num <- copy 3:address:array:num
+  4:num <- deaddress 3:address:array:num
   5:bool <- equal 2:num, 4:num
 ]
 # both calls to new returned identical addresses
diff --git a/061text.mu b/061text.mu
index c2c8915e..ffc87140 100644
--- a/061text.mu
+++ b/061text.mu
@@ -3,7 +3,7 @@
 def equal a:text, b:text -> result:bool [
   local-scope
   load-inputs
-  an:num, bn:num <- copy a, b
+  an:num, bn:num <- deaddress a, b
   address-equal?:boolean <- equal an, bn
   return-if address-equal?, 1/true
   return-unless a, 0/false
diff --git a/064list.mu b/064list.mu
index 6177e3f3..eca3ded1 100644
--- a/064list.mu
+++ b/064list.mu
@@ -254,7 +254,7 @@ scenario removing-from-singleton-list [
   list:&:list:num <- push 3, 0
   run [
     list <- remove list, list
-    1:num/raw <- copy list
+    1:num/raw <- deaddress list
   ]
   memory-should-contain [
     1 <- 0  # back to an empty list
@@ -332,7 +332,7 @@ def to-buffer in:&:list:_elem, buf:&:buffer:char -> buf:&:buffer:char [
   buf <- append buf, val
   # now prepare next
   next:&:list:_elem <- rest in
-  nextn:num <- copy next
+  nextn:num <- deaddress next
   return-unless next
   buf <- append buf, [ -> ]
   # and recurse
diff --git a/065duplex_list.mu b/065duplex_list.mu
index 037cb923..bf0c896a 100644
--- a/065duplex_list.mu
+++ b/065duplex_list.mu
@@ -338,7 +338,7 @@ scenario removing-from-singleton-duplex-list [
   list:&:duplex-list:num <- push 3, 0
   run [
     list <- remove list, list
-    1:num/raw <- copy list
+    1:num/raw <- deaddress list
   ]
   memory-should-contain [
     1 <- 0  # back to an empty list
@@ -690,7 +690,7 @@ def to-buffer in:&:duplex-list:_elem, buf:&:buffer:char -> buf:&:buffer:char [
   buf <- append buf, val
   # now prepare next
   next:&:duplex-list:_elem <- next in
-  nextn:num <- copy next
+  nextn:num <- deaddress next
   return-unless next
   buf <- append buf, [ <-> ]
   # and recurse
diff --git a/072recipe.cc b/072recipe.cc
index 532491e7..dd71830d 100644
--- a/072recipe.cc
+++ b/072recipe.cc
@@ -395,7 +395,7 @@ def main [
 def f x:&:num -> y:num [
   local-scope
   load-ingredients
-  y <- copy x
+  y <- deaddress x
 ]
 $error: 0