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
79
80
81
82
83
84
85
86
87
88
|
(in-package #:chains)
(defun get-var (env key)
(if-let ((slot (assoc key env)))
(cdr slot)
(error "var ~A not found~% ~A~%" key env)))
;; Built-in functions and variables used inside the interpreter use their own
;; package. This allows the language to have keywords like lambda which
;; otherwise would be reserved words from the cl package
(defmacro define-function (name (&rest args) &body body)
(let ((siblings (gensym)))
`(make-closure #'(lambda (environment ,siblings ,@args)
(declare (ignore ,siblings))
,@body)
',args
nil
(complement #'identity)
nil
:function)))
(defmacro define-function* (name (&rest args) (siblings group-predicate)
&body body)
`(make-closure #'(lambda (environment ,siblings ,@args)
,@body)
',args
nil
,group-predicate
nil
:function))
(defmacro define-syntax (name (&rest args) &body body)
`(make-closure #'(lambda (environment siblings ,@args)
,@body)
',args
t
(complement #'identity)
nil
:special))
(defmacro define-syntax* (name (&rest args) (siblings group-predicate)
&body body)
`(make-closure #'(lambda (environment ,siblings ,@args)
,@body)
',args
t
,group-predicate
nil
:special))
(defparameter *lambda*
(define-syntax lambda (arglist body)
(setf arglist (remove-if #'whitespace-text-p arglist))
(assert (every #'object-symbolp arglist))
(setf arglist (mapcar #'cdr arglist))
(let ((env environment))
(make-closure #'(lambda (environment siblings &rest args)
(tree-eval (append (pairlis arglist args)
env
environment)
body))
arglist nil (complement #'identity) env :function))))
;; Is this basically quasiquote?
(defparameter *syntax*
(define-syntax syntax (arglist body)
(setf arglist (remove-if #'whitespace-text-p arglist))
(assert (every #'object-symbolp arglist))
(setf arglist (mapcar #'cdr arglist))
(let ((env environment))
(make-closure #'(lambda (environment siblings &rest args)
(mapc #'(lambda (pair)
(setf body (nsubst (cdr pair)
`((symbol . ,(car pair)))
body
:test #'equal)))
(pairlis arglist args))
body)
arglist t (complement #'identity) env :syntax))))
(defparameter *define*
(define-syntax* define (name value) (siblings #'identity)
(assert (object-symbolp (first name)))
(setf name (cdr (first name)))
(setf value (first (tree-eval environment value)))
(tree-eval (acons name value environment)
siblings)))
|