;; re-introducing datatype declarations for normal sum types
(datatype list
(:nil)
(:cons 'a (list 'a))
)
(datatype bool (:true) (:false))
(define (+ a b)
(%%cexp (int int -> int) "%0+%1" a b))
(define (- a b)
(%%cexp (int int -> int) "%0-%1" a b))
(define (zero? a)
(%%cexp (int -> bool) "%0==0" a))
(define (length l)
(let loop ((l l) (r 0))
(vcase list l
((:nil) r)
((:cons _ tl) (loop tl (+ r 1))))))
(define (range n)
(let loop ((n n) (r (list:nil)))
(if (zero? n)
r
(loop (- n 1) (list:cons n r)))))
(define (n-of n x)
(let loop ((n n) (r (list:nil)))
(if (zero? n)
r
(loop (- n 1) (list:cons x r)))))
(define (member x = l)
(let loop ((l l))
(vcase list l
((:nil) #f)
((:cons hd tl)
(if (= x hd)
#t
(loop tl))))))
(define (printn x)
(%%cexp ('a -> undefined) "dump_object (%0, 0); fprintf (stdout, \"\\n\")" x))
(define (= a b)
(%%cexp (int int -> bool) "%0==%1" a b))
(let ((l0 (range 5))
(l1 (list:nil))
(l2 (list:nil))
)
(printn l0)
(printn (length l0))
(printn l1)
(printn (length l1))
(set! l1 (list:cons #\C l1))
(printn l1)
(printn (length l1))
(set! l1 (list:cons #\B l1))
(printn l1)
(printn (length l1))
(set! l1 (list:cons #\A l1))
(printn l1)
(printn (length l1))
(set! l2 (n-of 10 "hello"))
(printn l2)
(printn (member 15 = l0))
(printn (member 3 = l0))
99
)