Skip to content

Commit

Permalink
Added special type constructor forall.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralith committed Apr 20, 2012
1 parent 5f60ce3 commit ea90adc
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 13 deletions.
35 changes: 28 additions & 7 deletions src/specials.lisp
@@ -1,5 +1,25 @@
(in-package #:bitlisp) (in-package #:bitlisp)


(defmacro def-type-special (name self (&rest args) (env &rest resolver) constructor)
(with-gensyms (sym)
`(let* ((,sym (make-bl-symbol ,name))
(,self (make-special-tycon :name ,sym)))
(bind *primitives-env* :type ,sym ,self)
(setf (special-tycon-resolver ,self) (lambda (,env ,@args) ,@resolver)
(special-tycon-constructor ,self) (lambda ,args ,@constructor)))))

(def-type-special "forall" self (vars constraints type)
(env (let ((subenv (make-subenv env)))
(let ((tyvars (loop :repeat (length vars)
:collect (make-instance 'tyvar))))
(mapc (curry #'bind subenv :type) vars tyvars)
(list self tyvars
(mapcar (rcurry #'constraint-eval subenv)
constraints)
(infer-kinds (type-resolve type subenv))))))
((declare (ignore vars))
(values (type-construct type) constraints)))

(defmacro defspecial (name self (&rest args) (defmacro defspecial (name self (&rest args)
(env &body resolver) (env &body resolver)
(&body inferrer) (&body inferrer)
Expand Down Expand Up @@ -120,9 +140,9 @@
(defspecial "def-as" self (declared-type name value) (defspecial "def-as" self (declared-type name value)
(env (env
(let* ((subenv (make-subenv env)) (let* ((subenv (make-subenv env))
(scheme (let ((ty (type-construct (infer-kinds (type-resolve-free declared-type subenv))))) (scheme
;; TODO: Allow constraints to be specified (multiple-value-bind (ty preds) (type-eval declared-type env)
(quantify (free-vars ty) nil ty))) (quantify (free-vars ty) preds ty)))
(var (make-instance 'value (var (make-instance 'value
:name name :env env :name name :env env
:value-type scheme))) :value-type scheme)))
Expand Down Expand Up @@ -204,10 +224,11 @@
(llvm remote-binding) val)))))))) (llvm remote-binding) val))))))))


(defspecial "the" self (type value) (defspecial "the" self (type value)
(env (list self (type-eval type env) (resolve value env))) (env (list self (type-resolve type env) (resolve value env)))
((multiple-value-bind (form preds subst) (infer-expr value) ((multiple-value-bind (form val-preds subst) (infer-expr value)
(values form preds (multiple-value-bind (ty ty-preds) (type-construct type)
(subst-compose subst (unify (form-type form) type))))) (values form (nconc ty-preds val-preds)
(subst-compose subst (unify (form-type form) ty))))))
(m b ty (m b ty
(declare (ignore m b ty type value)) (declare (ignore m b ty type value))
(error "What's this doing here?"))) (error "What's this doing here?")))
Expand Down
19 changes: 13 additions & 6 deletions src/types.lisp
Expand Up @@ -182,7 +182,11 @@
(integer code) (integer code)
((or bl-symbol string) (or (lookup code :type env) ((or bl-symbol string) (or (lookup code :type env)
(error "~A names no type binding!" code))) (error "~A names no type binding!" code)))
(list (mapcar (rcurry #'type-resolve env) code)))) (list (let ((ctor (type-resolve (first code) env)))
(typecase ctor
(special-tycon (apply (special-tycon-resolver ctor)
env (rest code)))
(t (cons ctor (mapcar (rcurry #'type-resolve env) (rest code)))))))))


(defun type-resolve-free (code &optional (env *primitives-env*)) (defun type-resolve-free (code &optional (env *primitives-env*))
"Like type-resolve, but binds free variables. Kind inference must be done on the result." "Like type-resolve, but binds free variables. Kind inference must be done on the result."
Expand All @@ -193,15 +197,18 @@
(make-instance 'tyvar)))) (make-instance 'tyvar))))
(list (mapcar (rcurry #'type-resolve-free env) code)))) (list (mapcar (rcurry #'type-resolve-free env) code))))


(defun type-construct (resolved &optional (env *primitives-env*)) (defun type-construct (resolved)
(etypecase resolved (etypecase resolved
((or integer bl-type) resolved) ((or integer bl-type) resolved)
(list (destructuring-bind (constructor &rest args) (list (unless (null resolved)
(mapcar (rcurry #'type-construct env) resolved) (destructuring-bind (constructor &rest args) resolved
(apply #'tyapply constructor args))))) (typecase constructor
(special-tycon (apply (special-tycon-constructor constructor)
args))
(t (apply #'tyapply (mapcar #'type-construct resolved)))))))))


(defun type-eval (code &optional (env *primitives-env*)) (defun type-eval (code &optional (env *primitives-env*))
(type-construct (type-resolve code env) env)) (type-construct (type-resolve code env)))


(defun constraint-eval (code &optional (env *primitives-env*)) (defun constraint-eval (code &optional (env *primitives-env*))
(destructuring-bind (interface &rest args) code (destructuring-bind (interface &rest args) code
Expand Down
6 changes: 6 additions & 0 deletions src/values.lisp
Expand Up @@ -6,6 +6,12 @@
(print-unreadable-object (value stream :type t) (print-unreadable-object (value stream :type t)
(princ (special-op-name value) stream))) (princ (special-op-name value) stream)))


(defstruct special-tycon name resolver constructor)

(defmethod print-object ((value special-tycon) stream)
(print-unreadable-object (value stream :type t)
(princ (special-op-name value) stream)))

(defclass value () (defclass value ()
((name :initarg :name :reader name) ((name :initarg :name :reader name)
(env :initarg :env :reader env) (env :initarg :env :reader env)
Expand Down

0 comments on commit ea90adc

Please sign in to comment.