about summary refs log tree commit diff stats
path: root/mu.arc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2014-11-07 14:09:59 -0800
committerKartik K. Agaram <vc@akkartik.com>2014-11-07 14:09:59 -0800
commit66741bc8ef82776b480713fcfc298f315bfa6530 (patch)
treea6396d2574894eb5d1679b85fe8b9fc69dce9e84 /mu.arc
parent0a52288c41f6f9a65ac3a598fec30a0804353845 (diff)
downloadmu-66741bc8ef82776b480713fcfc298f315bfa6530.tar.gz
258 - new channel helpers: empty? and full?
Diffstat (limited to 'mu.arc')
-rw-r--r--mu.arc30
1 files changed, 30 insertions, 0 deletions
diff --git a/mu.arc b/mu.arc
index d9e96210..ba5b39d3 100644
--- a/mu.arc
+++ b/mu.arc
@@ -602,6 +602,7 @@
 
 (def sizeof (type)
   (trace "sizeof" type)
+  (assert types*.type "sizeof: no such type @type")
   (if (~or types*.type!record types*.type!array)
         types*.type!size
       types*.type!record
@@ -715,6 +716,7 @@
           (if (in op 'get 'get-address)
             (with (basetype  (typeinfo args.0)
                    field  (v args.1))
+              (assert basetype "no such type @args.0")
               (trace "cn0" "field-access " field)
               ; todo: need to rename args.0 as well?
               (when (pos 'deref (metadata args.0))
@@ -889,6 +891,34 @@
   ((watch boolean-address deref) <- copy (t literal))
   (reply (result tagged-value) (chan channel)))
 
+; An empty channel has first-empty and first-full both at the same value.
+; A full channel has first-empty just before first-full, wasting one slot.
+; (Other alternatives: https://en.wikipedia.org/wiki/Circular_buffer#Full_.2F_Empty_Buffer_Distinction)
+
+(init-fn empty?
+  ((default-scope scope-address) <- new (scope literal) (30 literal))
+  ((chan channel) <- arg)
+  ((full integer) <- get (chan channel) (first-full offset))
+  ((free integer) <- get (chan channel) (first-free offset))
+  ((result boolean) <- eq (full integer) (free integer))
+  (reply (result boolean)))
+
+(init-fn full?
+  ((default-scope scope-address) <- new (scope literal) (30 literal))
+  ((chan channel) <- arg)
+  ((full integer) <- get (chan channel) (first-full offset))
+  ((curr integer) <- get (chan channel) (first-free offset))
+  ((q tagged-value-array-address) <- get (chan channel) (circular-buffer offset))
+  ((qlen integer) <- len (q tagged-value-array-address deref))
+  ((curr integer) <- add (curr integer) (1 literal))
+  { begin
+    ((remaining? boolean) <- lt (curr integer) (qlen integer))
+    (break-if (remaining? boolean))
+    ((curr integer) <- copy (0 literal))
+  }
+  ((result boolean) <- eq (full integer) (curr integer))
+  (reply (result boolean)))
+
 ; drop all traces while processing above functions
 (on-init
   (= traces* (queue)))