Skip to content

Commit

Permalink
Add .coal versions of library files
Browse files Browse the repository at this point in the history
  • Loading branch information
jbouwman committed Sep 11, 2024
1 parent 8f80992 commit 39d5404
Show file tree
Hide file tree
Showing 16 changed files with 2,398 additions and 7 deletions.
14 changes: 7 additions & 7 deletions coalton.asd
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@
:serial t
:components ((:file "set-float-traps")
(:file "utils")
(:file "types")
(:coalton-file "types")
(:file "primitive-types")
(:file "classes")
(:file "hash")
(:file "builtin")
(:file "functions")
(:file "boolean")
(:file "bits")
(:coalton-file "functions")
(:coalton-file "boolean")
(:coalton-file "bits")
(:module "math"
:serial t
:components ((:file "arith")
Expand All @@ -65,15 +65,15 @@
(:file "dyadic")
(:file "dual")))
(:file "randomaccess")
(:file "cell")
(:coalton-file "cell")
(:file "tuple")
(:file "iterator")
(:file "optional")
(:file "result")
(:file "lisparray")
(:file "list")
(:file "vector")
(:file "char")
(:coalton-file "vector")
(:coalton-file "char")
(:file "string")
(:file "slice")
(:file "hashtable")
Expand Down
25 changes: 25 additions & 0 deletions library/bits.coal
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
(package coalton-library/bits
(shadow
and
or
xor
not)
(import-from
coalton-library/classes
Num)
(export
Bits
and
or
xor
not
shift))

(define-class (Num :int => Bits :int)
"Operations on the bits of twos-complement integers"
(and (:int -> :int -> :int))
(or (:int -> :int -> :int))
(xor (:int -> :int -> :int))
(not (:int -> :int))
(shift (Integer -> :int -> :int)))

33 changes: 33 additions & 0 deletions library/boolean.coal
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
(package coalton-library/boolean
(import
coalton-library/classes
coalton-library/hash))

;;
;; Boolean instances
;;

(define-instance (Hash Boolean)
(define (hash item)
(lisp Hash (item)
(cl:sxhash item))))

(define-instance (Eq Boolean)
(define (== x y)
(lisp Boolean (x y)
(cl:eq x y))))

(define-instance (Ord Boolean)
(define (<=> x y)
(match x
((True)
(match y
((True) EQ)
((False) GT)))
((False)
(match y
((True) LT)
((False) EQ))))))

(define-instance (Default Boolean)
(define (default) False))
60 changes: 60 additions & 0 deletions library/builtin.coal
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
(package coalton-library/builtin
(import
coalton-library/classes)
(export
unreachable
undefined
error ; re-export from classes
not
xor
boolean-not
boolean-or
boolean-and
boolean-xor))

(lisp-toplevel ()
(cl:eval-when (:compile-toplevel)
(cl:defmacro unreachable (cl:&optional (datum "Unreachable") cl:&rest arguments)
"Signal an error with CL format string DATUM and optional format arguments ARGUMENTS."
`(lisp :a ()
(cl:error ,datum ,@arguments)))))

(define (undefined _)
"A function which can be used in place of any value, throwing an error at runtime."
(error "Undefined"))

(define not
"Synonym for `boolean-not`."
boolean-not)

(define xor
"Synonym for `boolean-xor`."
boolean-xor)

(declare boolean-not (Boolean -> Boolean))
(define (boolean-not x)
"The logical negation of `x`. Is `x` false?"
(match x
((True) False)
((False) True)))

(declare boolean-or (Boolean -> Boolean -> Boolean))
(define (boolean-or x y)
"Is either `x` or `y` true? Note that this is a *function* which means both `x` and `y` will be evaluated. Use the `or` macro for short-circuiting behavior."
(match x
((True) True)
((False) y)))

(declare boolean-and (Boolean -> Boolean -> Boolean))
(define (boolean-and x y)
"Are both `x` and `y` true? Note that this is a *function* which means both `x` and `y` will be evaluated. Use the `and` macro for short-circuiting behavior."
(match x
((True) y)
((False) False)))

(declare boolean-xor (Boolean -> Boolean -> Boolean))
(define (boolean-xor x y)
"Are `x` or `y` true, but not both?"
(match x
((True) (boolean-not y))
((False) y)))
141 changes: 141 additions & 0 deletions library/cell.coal
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
(package coalton-library/cell
(import
coalton-library/builtin
coalton-library/classes)
(export
Cell
new
read
swap!
write!
update!
update-swap!
push!
pop!
increment!
decrement!))

(lisp-toplevel ()
(cl:eval-when (:compile-toplevel :load-toplevel)

(cl:declaim (cl:inline make-cell-internal))

(cl:defstruct cell-internal
(inner (cl:error "") :type cl:t))

(cl:defmethod cl:print-object ((self cell-internal) stream)
(cl:format stream "#.(CELL ~A)" (cell-internal-inner self))
self)

#+sbcl
(cl:declaim (sb-ext:freeze-type cell-internal))))

(repr :native cell-internal)
(define-type (Cell :a)
"Internally mutable cell")

(declare new (:a -> Cell :a))
(define (new data)
"Create a new mutable cell"
(lisp (Cell :a) (data)
(make-cell-internal :inner data)))

(declare read (Cell :a -> :a))
(define (read cel)
"Read the value of a mutable cell"
(lisp :a (cel)
(cell-internal-inner cel)))

(declare swap! (Cell :a -> :a -> :a))
(define (swap! cel data)
"Replace the value of a mutable cell with a new value, then return the old value"
(lisp :a (data cel)
(cl:let* ((old (cell-internal-inner cel)))
(cl:setf (cell-internal-inner cel) data)
old)))

(declare write! (Cell :a -> :a -> :a))
(define (write! cel data)
"Set the value of a mutable cell, returning the new value"
(lisp :a (data cel)
(cl:setf (cell-internal-inner cel) data)))

(declare update! ((:a -> :a) -> Cell :a -> :a))
(define (update! f cel)
"Apply F to the contents of CEL, storing and returning the result"
(write! cel (f (read cel))))

(declare update-swap! ((:a -> :a) -> Cell :a -> :a))
(define (update-swap! f cel)
"Apply F to the contents of CEL, swapping the result for the old value"
(swap! cel (f (read cel))))

;;; operators on cells of lists
(declare push! (Cell (List :elt) -> :elt -> List :elt))
(define (push! cel new-elt)
"Push NEW-ELT onto the start of the list in CEL."
(update! (Cons new-elt) cel))

(declare pop! (Cell (List :elt) -> Optional :elt))
(define (pop! cel)
"Remove and return the first element of the list in CEL."
(match (read cel)
((Cons fst rst)
(write! cel rst)
(Some fst))
((Nil) None)))

;;; operators on cells of numbers
(declare increment! (Num :counter => Cell :counter -> :counter))
(define (increment! cel)
"Add one to the contents of CEL, storing and returning the new value"
(update! (+ 1) cel))

(declare decrement! (Num :counter => (Cell :counter) -> :counter))
(define (decrement! cel)
"Subtract one from the contents of CEL, storing and returning the new value"
(update! (+ -1) cel))

;; i am very skeptical of these instances
(define-instance (Eq :a => Eq (Cell :a))
(define (== c1 c2)
(== (read c1) (read c2))))

(define-instance (Ord :a => Ord (Cell :a))
(define (<=> c1 c2)
(match (<=> (read c1) (read c2))
((LT) LT)
((GT) GT)
((EQ) EQ))))

(define-instance (Num :a => Num (Cell :a))
(define (+ c1 c2)
(new (+ (read c1) (read c2))))
(define (- c1 c2)
(new (- (read c1) (read c2))))
(define (* c1 c2)
(new (* (read c1) (read c2))))
(define (fromInt i)
(new (fromInt i))))

(define-instance (Semigroup :a => Semigroup (Cell :a))
(define (<> a b)
(new (<> (read a) (read b)))))

(define-instance (Functor Cell)
(define (map f c)
(new (f (read c)))))

(define-instance (Applicative Cell)
(define pure new)
(define (liftA2 f c1 c2)
(new (f (read c1) (read c2)))))

(define-instance (Into :a (Cell :a))
(define into new))

(define-instance (Into (Cell :a) :a)
(define into read))

(define-instance (Default :a => Default (Cell :a))
(define (default) (new (default))))
Loading

0 comments on commit 39d5404

Please sign in to comment.