-
Notifications
You must be signed in to change notification settings - Fork 4
/
lambda-list-from-parameter-groups.lisp
78 lines (61 loc) · 3.05 KB
/
lambda-list-from-parameter-groups.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
72
73
74
75
76
77
78
(cl:in-package #:cleavir-cst-to-ast)
(defun var-to-lexical (var-cst)
(let* ((raw (cst:raw var-cst))
(name (make-symbol (string-downcase raw))))
(ast:make-lexical-variable name :origin var-cst)))
(defun init-var-to-lexicals (var-cst supplied-p-cst)
(list (var-to-lexical var-cst)
(if (null supplied-p-cst)
(ast:make-lexical-variable (gensym) :origin var-cst)
(var-to-lexical supplied-p-cst))))
(defgeneric entries-from-parameter-group (parameter-group))
(defmethod entries-from-parameter-group
((parameter-group cst:multi-parameter-group-mixin))
(mapcar #'entry-from-parameter (cst:parameters parameter-group)))
(defmethod entries-from-parameter-group
((parameter-group cst:ordinary-rest-parameter-group))
(list (entry-from-parameter (cst:parameter parameter-group))))
(defmethod entries-from-parameter-group
((parameter-group cst:aux-parameter-group))
;; Don't need any.
nil)
(defgeneric entry-from-parameter (parameter))
(defmethod entry-from-parameter ((parameter cst:simple-variable))
(var-to-lexical (cst:name parameter)))
(defmethod entry-from-parameter ((parameter cst:ordinary-optional-parameter))
(init-var-to-lexicals (cst:name parameter) (cst:supplied-p parameter)))
(defmethod entry-from-parameter ((parameter cst:ordinary-key-parameter))
(init-var-to-lexicals (cst:name parameter) (cst:supplied-p parameter)))
(defgeneric lambda-list-from-parameter-group (parameter-group entries))
(defmethod lambda-list-from-parameter-group
((parameter-group cst:ordinary-required-parameter-group) entries)
(values entries entries))
(defmethod lambda-list-from-parameter-group
((parameter-group cst:optional-parameter-group) entries)
(values (cons '&optional entries) entries))
(defmethod lambda-list-from-parameter-group
((parameter-group cst:ordinary-rest-parameter-group) entries)
(values (cons '&rest entries) entries))
(defmethod lambda-list-from-parameter-group
((parameter-group cst:key-parameter-group) entries)
(values (append '(&key)
(mapcar (lambda (entry parameter)
(cons (cst:raw (cst:keyword parameter)) entry))
entries (cst:parameters parameter-group))
(if (cst:allow-other-keys parameter-group)
'(&allow-other-keys)
'()))
entries))
(defmethod lambda-list-from-parameter-group
((parameter-group cst:aux-parameter-group) entries)
;; &aux doesn't contribute to the function-ast's lambda-list.
(values '() entries))
;;; Given a list of parameter groups, return a lambda list suitable
;;; for the FUNCTION-AST, as well as a list of lists of lexical variables.
(defun lambda-list-from-parameter-groups (parameter-groups)
(loop for group in parameter-groups
for entries = (entries-from-parameter-group group)
for lambda-list-part = (lambda-list-from-parameter-group group entries)
appending lambda-list-part into lambda-list
collecting entries into components
finally (return (values lambda-list components))))