;; -*- Mode: Irken -*-
;; based on ocaml/stdlib/queue.ml
(define (queue/make)
{length = 0 tail = (maybe:no)}
)
(define (queue/add q x)
(set! q.length (+ 1 q.length))
(match q.tail with
(maybe:no)
-> (let ((cell {content=x next=(magic #u)}))
(set! cell.next cell)
(set! q.tail (maybe:yes cell)))
(maybe:yes tail)
-> (let ((head tail.next)
(cell {content=x next=head}))
(set! tail.next cell)
(set! q.tail (maybe:yes cell)))))
;; ocaml raises an exception rather than using maybe
(define (queue/peek q)
(match q.tail with
(maybe:no) -> (maybe:no)
(maybe:yes {content=x next=_}) -> (maybe:yes x)))
(define (queue/iterate p q)
(match q.tail with
(maybe:no) -> #u
(maybe:yes tail)
-> (let loop ((node tail.next))
(p node.content)
(if (eq? node tail)
#u
(loop node.next)))
))
(define (queue/pop q)
(match q.tail with
(maybe:no) -> (maybe:no)
(maybe:yes tail)
-> (let ((head tail.next))
(set! q.length (- q.length 1))
(if (= q.length 0)
(set! q.tail (maybe:no))
(set! tail.next head.next))
(maybe:yes head.content))))