forked from coalton-lang/coalton
-
Notifications
You must be signed in to change notification settings - Fork 0
/
toplevel-define-instance.lisp
71 lines (58 loc) · 3.08 KB
/
toplevel-define-instance.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
(in-package #:coalton-impl)
;;; Handling of toplevel COALTON:DEFINE-INSTANCE.
(defun process-toplevel-instance-definitions (definstance-forms package env)
(declare (values instance-definition-list))
(mapcar
(lambda (form)
(parse-instance-definition form package env))
definstance-forms))
(defun predeclare-toplevel-instance-definitions (definstance-forms package env)
"Predeclare all instance definitions in the environment so values can be typechecked"
(declare (type list definstance-forms)
(type package package)
(type environment env)
(values environment))
(loop :for form :in definstance-forms
:do (multiple-value-bind (predicate context methods)
(coalton-impl/typechecker::parse-instance-decleration form env)
(declare (ignore methods))
(let* ((class-name (ty-predicate-class predicate))
(instance-codegen-sym
(alexandria:format-symbol
package "INSTANCE/~A"
(with-output-to-string (s)
(with-pprint-variable-context ()
(pprint-predicate s predicate)))))
(method-names (mapcar
#'car
(coalton-impl/typechecker::ty-class-unqualified-methods
(coalton-impl/typechecker::lookup-class env class-name))))
(method-codegen-syms
(let ((table (make-hash-table)))
(loop :for method-name :in method-names
:do (setf (gethash method-name table)
(alexandria:format-symbol
package
"~A-~A"
instance-codegen-sym
method-name)))
table))
(instance
(ty-class-instance
:constraints context
:predicate predicate
:codegen-sym instance-codegen-sym
:method-codegen-syms method-codegen-syms)))
(loop :for key :being :the :hash-keys :of method-codegen-syms
:for value :being :the :hash-values :of method-codegen-syms
:for codegen-sym := (coalton-impl/typechecker::ty-class-instance-codegen-sym instance)
:do (setf env (coalton-impl/typechecker::set-method-inline env key codegen-sym value)))
(when context
(setf env (set-function
env
instance-codegen-sym
(coalton-impl/typechecker::make-function-env-entry
:name instance-codegen-sym
:arity (length context)))))
(setf env (add-instance env class-name instance)))))
env)