about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--mu.arc13
-rw-r--r--mu.arc.t8
2 files changed, 21 insertions, 0 deletions
diff --git a/mu.arc b/mu.arc
index 5c1b0455..6f214be1 100644
--- a/mu.arc
+++ b/mu.arc
@@ -703,6 +703,19 @@
         :else
           (err "sizeof can't handle @type (arrays require a specific variable)")))))
 
+(def deref (operand)
+  (assert (pos 'deref metadata.operand))
+  (assert typeinfo.operand!address)
+  (apply list (memory* v.operand)
+              typeinfo.operand!elem
+              (drop-one 'deref (cut operand 2))))
+
+(def drop-one (f x)
+  (when acons.x  ; proper lists only
+    (if (testify.f car.x)
+      cdr.x
+      (cons car.x (drop-one f x)))))
+
 ;; desugar structured assembly based on blocks
 
 (def convert-braces (instrs)
diff --git a/mu.arc.t b/mu.arc.t
index 0c85f4a8..87926a9e 100644
--- a/mu.arc.t
+++ b/mu.arc.t
@@ -743,6 +743,14 @@
 (if (~is 23 (addr '(4 integer-address deref)))
   (prn "F - 'addr' adds default-scope before 'deref', not after"))
 
+; unit tests for 'deref' helper
+(reset)
+(= memory*.3 4)
+(if (~iso '(4 integer) (deref '(3 integer-address deref)))
+  (prn "F - 'deref' handles simple addresses"))
+(if (~iso '(4 integer deref) (deref '(3 integer-address deref deref)))
+  (prn "F - 'deref' deletes just one deref"))
+
 ; unit tests for 'sizeof' helper
 (reset)
 (if (~is 1 sizeof!integer)