3 ;;; Copyright (C) 2009 Free Software Foundation, Inc.
5 ;;; This library is free software; you can redistribute it and/or modify
6 ;;; it under the terms of the GNU Lesser General Public License as
7 ;;; published by the Free Software Foundation; either version 3 of the
8 ;;; License, or (at your option) any later version.
10 ;;; This library is distributed in the hope that it will be useful, but
11 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ;;; Lesser General Public License for more details.
15 ;;; You should have received a copy of the GNU Lesser General Public
16 ;;; License along with this library; if not, write to the Free Software
17 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 (define-module (language elisp runtime subrs)
23 #:use-module (language elisp runtime)
24 #:use-module (system base compile))
26 ;;; This module contains the function-slots of elisp symbols. Elisp
27 ;;; built-in functions are implemented as predefined function bindings
30 ;;; Equivalence and equalness predicates.
34 (elisp-bool (eq? a b))))
38 (elisp-bool (equal? a b))))
40 ;;; Number predicates.
44 (elisp-bool (and (real? num)
46 (prim not (integer? num)))))))
48 (built-in-func integerp
50 (elisp-bool (and (exact? num)
53 (built-in-func numberp
55 (elisp-bool (real? num))))
57 (built-in-func wholenump
59 (elisp-bool (and (exact? num)
65 (elisp-bool (prim = num 0))))
67 ;;; Number comparisons.
71 (elisp-bool (prim = num1 num2))))
75 (elisp-bool (prim not (prim = num1 num2)))))
79 (elisp-bool (prim < num1 num2))))
83 (elisp-bool (prim <= num1 num2))))
87 (elisp-bool (prim > num1 num2))))
91 (elisp-bool (prim >= num1 num2))))
95 (prim apply (@ (guile) max) nums)))
99 (prim apply (@ (guile) min) nums)))
104 ;;; Number conversion.
112 ;;; TODO: truncate, floor, ceiling, round.
114 ;;; Arithmetic functions.
116 (built-in-func 1+ (@ (guile) 1+))
118 (built-in-func 1- (@ (guile) 1-))
120 (built-in-func + (@ (guile) +))
122 (built-in-func - (@ (guile) -))
124 (built-in-func * (@ (guile) *))
126 (built-in-func % (@ (guile) modulo))
128 ;;; TODO: / with correct integer/real behaviour, mod (for floating-piont
131 ;;; Floating-point rounding operations.
133 (built-in-func ffloor (@ (guile) floor))
135 (built-in-func fceiling (@ (guile) ceiling))
137 (built-in-func ftruncate (@ (guile) truncate))
139 (built-in-func fround (@ (guile) round))
145 (elisp-bool (pair? el))))
149 (elisp-bool (prim not (pair? el)))))
153 (elisp-bool (or (pair? el) (null? el)))))
155 (built-in-func nlistp
157 (elisp-bool (and (prim not (pair? el))
158 (prim not (null? el))))))
162 (elisp-bool (null? el))))
164 ;;; Accessing list elements.
178 (built-in-func car-safe
184 (built-in-func cdr-safe
197 ((null? tail) nil-value)
198 ((zero? i) (prim car tail))
199 (else (iterate (prim 1- i) (prim cdr tail))))))))
201 (built-in-func nthcdr
208 ((null? tail) nil-value)
210 (else (iterate (prim 1- i) (prim cdr tail))))))))
212 (built-in-func length (@ (guile) length))
216 (built-in-func cons (@ (guile) cons))
218 (built-in-func list (@ (guile) list))
220 (built-in-func make-list
222 (prim make-list len obj)))
224 (built-in-func append (@ (guile) append))
226 (built-in-func reverse (@ (guile) reverse))
228 (built-in-func copy-tree (@ (guile) copy-tree))
230 (built-in-func number-sequence
231 (lambda (from . rest)
232 (if (prim > (prim length rest) 2)
233 (runtime-error "too many arguments for number-sequence"
237 (let ((to (prim car rest))
238 (sep (if (or (null? (prim cdr rest))
239 (eq? nil-value (prim cadr rest)))
243 ((or (eq? nil-value to) (prim = to from)) `(,from))
244 ((and (zero? sep) (prim not (prim = from to)))
245 (runtime-error "infinite list in number-sequence"))
246 ((prim < (prim * to sep) (prim * from sep)) '())
248 (let iterate ((i (prim +
261 (iterate (prim - i sep)
262 (prim cons i result)))))))))))
266 (built-in-func setcar
268 (if (and (null? cell) (null? val))
270 (prim set-car! cell val))
273 (built-in-func setcdr
275 (if (and (null? cell) (null? val))
277 (prim set-cdr! cell val))
280 ;;; Accessing symbol bindings for symbols known only at runtime.
282 (built-in-func symbol-value
284 (reference-variable-with-check value-slot-module sym)))
286 (built-in-func symbol-function
288 (reference-variable-with-check function-slot-module sym)))
292 (set-variable! value-slot-module sym value)))
296 (set-variable! function-slot-module sym value)))
298 (built-in-func makunbound
300 (set-variable! value-slot-module sym void)
303 (built-in-func fmakunbound
305 (set-variable! function-slot-module sym void)
308 (built-in-func boundp
310 (elisp-bool (prim not
312 (reference-variable value-slot-module
315 (built-in-func fboundp
317 (elisp-bool (prim not
319 (reference-variable function-slot-module
322 ;;; Function calls. These must take care of special cases, like using
323 ;;; symbols or raw lambda-lists as functions!
326 (lambda (func . args)
327 (let ((real-func (cond
329 (reference-variable-with-check
333 (if (and (prim not (null? func))
334 (eq? (prim car func) 'lambda))
335 (compile func #:from 'elisp #:to 'value)
336 (runtime-error "list is not a function"
339 (prim apply (@ (guile) apply) real-func args))))
341 (built-in-func funcall
342 (let ((myapply (fluid-ref apply)))
343 (lambda (func . args)
344 (myapply func args))))
346 ;;; Throw can be implemented as built-in function.
350 (prim throw 'elisp-exception tag value)))
356 (if x nil-value t-value)))
360 (compile form #:from 'elisp #:to 'value)))
364 (compile-file file #:from 'elisp #:to 'value)