3 ;; Copyright (C) 2001 Free Software Foundation, Inc.
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)
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.
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.
22 (define-module (language elisp runtime macro-slot)
23 #:use-module (language elisp runtime))
25 ; This module contains the macro definitions of elisp symbols. In contrast to
26 ; the other runtime modules, those are used directly during compilation, of
27 ; course, so not really in runtime. But I think it fits well to the others
31 ; The prog1 and prog2 constructs can easily be defined as macros using progn
32 ; and some lexical-let's to save the intermediate value to return at the end.
35 (lambda (form1 . rest)
36 (let ((temp (gensym)))
37 `(without-void-checks (,temp)
38 (lexical-let ((,temp ,form1))
43 (lambda (form1 form2 . rest)
44 `(progn ,form1 (prog1 ,form2 ,@rest))))
47 ; Define the conditionals when and unless as macros.
50 (lambda (condition . thens)
51 `(if ,condition (progn ,@thens) nil)))
53 (built-in-macro unless
54 (lambda (condition . elses)
55 `(if ,condition nil (progn ,@elses))))
58 ; Impement the cond form as nested if's. A special case is a (condition)
59 ; subform, in which case we need to return the condition itself if it is true
60 ; and thus save it in a local variable before testing it.
64 (let iterate ((tail clauses))
67 (let ((cur (car tail))
68 (rest (iterate (cdr tail))))
70 ((prim or (not (list? cur)) (null? cur))
71 (macro-error "invalid clause in cond" cur))
74 `(without-void-checks (,var)
75 (lexical-let ((,var ,(car cur)))
85 ; The and and or forms can also be easily defined with macros.
91 (let iterate ((tail args))
92 (if (null? (cdr tail))
100 (let iterate ((tail args))
103 (let ((var (gensym)))
104 `(without-void-checks (,var)
105 (lexical-let ((,var ,(car tail)))
108 ,(iterate (cdr tail))))))))))
111 ; Define the dotimes and dolist iteration macros.
113 (built-in-macro dotimes
114 (lambda (args . body)
115 (if (prim or (not (list? args))
118 (macro-error "invalid dotimes arguments" args)
119 (let ((var (car args))
121 (if (not (symbol? var))
122 (macro-error "expected symbol as dotimes variable"))
124 (while (< ,var ,count)
126 (setq ,var (1+ ,var)))
127 ,@(if (= (length args) 3)
131 (built-in-macro dolist
132 (lambda (args . body)
133 (if (prim or (not (list? args))
136 (macro-error "invalid dolist arguments" args)
137 (let ((var (car args))
138 (iter-list (cadr args))
140 (if (not (symbol? var))
141 (macro-error "expected symbol as dolist variable")
143 (without-void-checks (,tailvar)
144 (lexical-let ((,tailvar ,iter-list))
145 (while (not (null ,tailvar))
146 (setq ,var (car ,tailvar))
148 (setq ,tailvar (cdr ,tailvar)))
149 ,@(if (= (length args) 3)
154 ; Pop off the first element from a list or push one to it.
158 `(prog1 (car ,list-name)
159 (setq ,list-name (cdr ,list-name)))))
162 (lambda (new-el list-name)
163 `(setq ,list-name (cons ,new-el ,list-name))))