about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2014-12-30 01:27:26 -0800
committerKartik K. Agaram <vc@akkartik.com>2014-12-30 01:27:26 -0800
commit9c729fb4464d1eab956fc20bb2717381a1409e16 (patch)
tree8c45972de45cfee8b0eebdabda2b5ed5aefce8ba
parent7f6a670209feb1c99604c40274f9886d56e92371 (diff)
downloadmu-9c729fb4464d1eab956fc20bb2717381a1409e16.tar.gz
463 - mu now has closures
-rw-r--r--mu.arc22
-rw-r--r--mu.arc.t29
2 files changed, 44 insertions, 7 deletions
diff --git a/mu.arc b/mu.arc
index 6a22c69b..c53a6ccd 100644
--- a/mu.arc
+++ b/mu.arc
@@ -750,15 +750,23 @@
           (die "routine has no globals: @operand"))
       :else
         (iflet base rep.routine*!call-stack.0!default-scope
-;?                (do (prn 313 " " operand " " base)
-          (if (< v.operand memory*.base)
-            `((,(+ base 1 v.operand) ,@(cdr operand.0))
-              ,@metadata.operand
-              (raw))
-            (die "no room for var @operand in routine of size @memory*.base"))
-;?                 )
+          (lookup-space (rem [caris _ 'space] operand)
+                        base
+                        space.operand)
           operand)))
 
+(def lookup-space (operand base space)
+  (if (is 0 space)
+    ; base case
+    (if (< v.operand memory*.base)
+      `((,(+ base 1 v.operand) ,@(cdr operand.0))
+        ,@metadata.operand
+        (raw))
+      (die "no room for var @operand in routine of size @memory*.base"))
+    ; recursive case
+    (lookup-space operand (memory* (+ base 1))  ; location 0 points to parent space
+                  (- space 1))))
+
 (def space (operand)
   (or (alref operand 'space)
       0))
diff --git a/mu.arc.t b/mu.arc.t
index 4f33dd6d..b1d6937b 100644
--- a/mu.arc.t
+++ b/mu.arc.t
@@ -2038,6 +2038,35 @@
   (prn "F - multiple calls to a function can share locals"))
 ;? (quit)
 
+(reset)
+(new-trace "default-scope-closure")
+(add-code
+  '((function init-counter [
+      (default-scope:scope-address <- new scope:literal 30:literal)
+      (1:integer <- copy 3:literal)  ; initialize to 3
+      (reply default-scope:scope-address)
+     ])
+    (function increment-counter [
+      (default-scope:scope-address <- new scope:literal 30:literal)
+      (0:scope-address <- next-input)  ; share outer scope
+      (1:integer/space:1 <- add 1:integer/space:1 1:literal)  ; increment
+      (1:integer <- copy 34:literal)  ; dummy
+      (reply 1:integer/space:1)
+     ])
+    (function main [
+      (1:scope-address <- init-counter)
+      (2:integer <- increment-counter 1:scope-address)
+      (3:integer <- increment-counter 1:scope-address)
+     ])))
+(run 'main)
+(each routine completed-routines*
+  (aif rep.routine!error (prn "error - " it)))
+;? (prn memory*)
+(if (or (~is memory*.2 4)
+        (~is memory*.3 5))
+  (prn "F - multiple calls to a function can share locals"))
+;? (quit)
+
 )  ; section 20
 
 (section 100