;;;; Copyright 2002, Jonathan Bachrach.  See file TERMS.

(use goo/boot)
(use goo/fun)
(use goo/class)
(use goo/macros)
(use goo/functional)
(use goo/types)
(use goo/any)
(use goo/log)
(use goo/chr)
(use goo/mag)
(use goo/math)
(use goo/cols/col)
(use goo/cols/seq)

;; 3.7.6 RANGES

;;;;!! Interface
(exported
 ;;  represents series of numbers
 (dc <range> (<seq>))
 (dg range (from|<num> done?|<fun> lim|<num> => <range>))
 (dg range-by (from|<num> done?|<fun> lim|<num> nxt|<fun> => <range>))
 (dg from (from|<num> => <range>))
 (dg below (from|<num> => <range>))
)

;; TODO: FEWER PROPS
(dp range-from (<range> =>  <num>)     0)
(dp range-in?  (<range> =>  <fun>)     <) 
(dp range-lim  (<range> => (t? <num>)) #f) 
(dp range-nxt  (<range> => <fun>)      1+) 

(dm fab ((c (t= <range>)) s|<int> => <range>)
  (range 0 < s 1+))

(dm range (from|<num> in?|<fun> lim|<num> => <range>)
  (new <range> range-from from range-in? in? range-lim lim))

(dm range-by (from|<num> in?|<fun> lim|<num> nxt|<fun> => <range>)
  (new <range> range-from from range-in? in? range-lim lim range-nxt nxt))

(dm from (from|<num> => <range>)
  (new <range> range-from from range-in? (always #t)))

(dm below (lim|<num> => <range>)
  (new <range> range-lim lim))

(dm col-res-type (x|<range> => <type>)
  <lst>)

(dc <range-enum> (<enum>))
(dp %dat (<range-enum> => <range>))
(dp! %val (<range-enum> => <num>))
(dp! %key (<range-enum> => <int>))

(dm enum (x|<range> => <range-enum>) 
  (new <range-enum> %dat x %val (range-from x) %key 0))

(dm fin? (e|<range-enum> => <log>)       
  (def c (%dat e))
  (not ((range-in? c) (%val e) (range-lim c))))

(dm nxt (e|<range-enum> => <range-enum>)  
  (renew e %val ((range-nxt (%dat e)) (%val e)) %key (+ (%key e) 1) 
         ))
(dm now (e|<range-enum> => <num>)         
  (%val e))

(dm now-key (e|<range-enum> => <int>)         
  (%key e))
