Commit | Line | Data |
---|---|---|
51248e6e DK |
1 | ;;; Guile Emac Lisp |
2 | ||
3 | ;; Copyright (C) 2001 Free Software Foundation, Inc. | |
4 | ||
5 | ;; This program is free software; you can redistribute it and/or modify | |
6 | ;; it under the terms of the GNU General Public License as published by | |
7 | ;; the Free Software Foundation; either version 2, or (at your option) | |
8 | ;; any later version. | |
9 | ;; | |
10 | ;; This program is distributed in the hope that it will be useful, | |
11 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | ;; GNU General Public License for more details. | |
14 | ;; | |
15 | ;; You should have received a copy of the GNU General Public License | |
16 | ;; along with this program; see the file COPYING. If not, write to | |
17 | ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
18 | ;; Boston, MA 02111-1307, USA. | |
19 | ||
20 | ;;; Code: | |
21 | ||
22 | (define-module (language elisp compile-tree-il) | |
23 | #:use-module (language tree-il) | |
24 | #:use-module (system base pmatch) | |
25 | #:export (compile-tree-il)) | |
26 | ||
27 | ||
28 | ; Find the source properties of some parsed expression if there are any | |
29 | ; associated with it. | |
30 | ||
31 | (define (location x) | |
32 | (and (pair? x) | |
33 | (let ((props (source-properties x))) | |
34 | (and (not (null? props)) | |
35 | props)))) | |
36 | ||
37 | ||
4530432e DK |
38 | ; Value to use for Elisp's nil. |
39 | ||
a4316739 | 40 | (define (nil-value loc) (make-const loc #f)) |
4530432e DK |
41 | |
42 | ||
51248e6e DK |
43 | ; Compile a symbol expression. This is a variable reference or maybe some |
44 | ; special value like nil. | |
45 | ||
46 | (define (compile-symbol loc sym) | |
47 | (case sym | |
48 | ||
49 | ((nil) | |
4530432e | 50 | (nil-value loc)) |
51248e6e DK |
51 | |
52 | ((t) | |
53 | (make-const loc #t)) | |
54 | ||
55 | ; FIXME: Use fluids. | |
56 | (else | |
57 | (make-module-ref loc '(language elisp variables) sym #f)))) | |
58 | ||
59 | ||
60 | ; Compile a pair-expression (that is, any structure-like construct). | |
61 | ||
62 | (define (compile-pair loc expr) | |
63 | (pmatch expr | |
64 | ||
65 | ((progn . ,forms) | |
66 | (make-sequence loc (map compile-expr forms))) | |
67 | ||
68 | ((if ,condition ,ifclause) | |
69 | (make-conditional loc (compile-expr condition) | |
70 | (compile-expr ifclause) | |
4530432e | 71 | (nil-value loc))) |
51248e6e DK |
72 | ((if ,condition ,ifclause ,elseclause) |
73 | (make-conditional loc (compile-expr condition) | |
74 | (compile-expr ifclause) | |
75 | (compile-expr elseclause))) | |
76 | ((if ,condition ,ifclause . ,elses) | |
77 | (make-conditional loc (compile-expr condition) | |
78 | (compile-expr ifclause) | |
79 | (make-sequence loc (map compile-expr elses)))) | |
80 | ||
a4316739 DK |
81 | ; For (cond ...) forms, a special case is a (condition) clause without |
82 | ; body. In this case, the value of condition itself should be returned, | |
83 | ; and thus is saved in a local variable for testing and returning, if it | |
84 | ; is found true. | |
51248e6e DK |
85 | ((cond . ,clauses) (guard (and-map (lambda (el) |
86 | (and (list? el) (not (null? el)))) | |
87 | clauses)) | |
88 | (let iterate ((tail clauses)) | |
89 | (if (null? tail) | |
4530432e | 90 | (nil-value loc) |
51248e6e | 91 | (let ((cur (car tail))) |
a4316739 DK |
92 | (if (null? (cdr cur)) |
93 | (let ((var (gensym))) | |
94 | (make-let loc | |
95 | '(condition) `(,var) `(,(compile-expr (car cur))) | |
96 | (make-conditional loc | |
97 | (make-lexical-ref loc 'condition var) | |
98 | (make-lexical-ref loc 'condition var) | |
99 | (iterate (cdr tail))))) | |
100 | (make-conditional loc | |
101 | (compile-expr (car cur)) | |
102 | (make-sequence loc (map compile-expr (cdr cur))) | |
103 | (iterate (cdr tail)))))))) | |
51248e6e | 104 | |
4530432e | 105 | ((and) (nil-value loc)) |
51248e6e DK |
106 | ((and . ,expressions) |
107 | (let iterate ((tail expressions)) | |
108 | (if (null? (cdr tail)) | |
109 | (compile-expr (car tail)) | |
110 | (make-conditional loc | |
111 | (compile-expr (car tail)) | |
112 | (iterate (cdr tail)) | |
4530432e | 113 | (nil-value loc))))) |
51248e6e DK |
114 | |
115 | (('quote ,val) | |
116 | (make-const loc val)) | |
117 | ||
118 | (else | |
119 | (error "unrecognized elisp" expr)))) | |
120 | ||
121 | ||
122 | ; Compile a single expression to TreeIL. | |
123 | ||
124 | (define (compile-expr expr) | |
125 | (let ((loc (location expr))) | |
126 | (cond | |
127 | ((symbol? expr) | |
128 | (compile-symbol loc expr)) | |
129 | ((pair? expr) | |
130 | (compile-pair loc expr)) | |
131 | (else (make-const loc expr))))) | |
132 | ||
133 | ||
134 | ; Entry point for compilation to TreeIL. | |
135 | ||
136 | (define (compile-tree-il expr env opts) | |
137 | (values | |
138 | (compile-expr expr) | |
139 | env | |
140 | env)) |