1 ;;; Guile VM specific syntaxes and utilities
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 (system base syntax)
23 :use-module (ice-9 match)
24 :use-module (ice-9 receive)
25 :use-module (ice-9 and-let-star)
26 :export (stack-catch match syntax-error receive and-let*))
30 ;;; Keywords by `:KEYWORD
33 (read-set! keywords 'prefix)
40 ;; FOO.BAR -> (slot FOO 'BAR)
42 (define (expand-dot! x)
43 (cond ((symbol? x) (expand-symbol x))
45 (cond ((eq? (car x) 'quote) x)
46 (else (set-car! x (expand-dot! (car x)))
47 (set-cdr! x (expand-dot! (cdr x)))
51 (define (expand-symbol x)
52 (let loop ((s (symbol->string x)))
53 (let ((i (string-rindex s #\.)))
55 `(slot ,(loop (substring s 0 i))
56 (quote ,(string->symbol (substring s (1+ i)))))
57 (string->symbol s)))))
59 (export-syntax syntax)
60 (define syntax expand-dot!)
67 (export-syntax define-type)
68 (define-macro (define-type name sig) sig)
74 (export-syntax define-record)
75 (define-macro (define-record def)
76 (let ((name (car def)) (slots (cdr def)))
78 (define (,name . args)
79 (vector ',name (%make-struct
81 (list ,@(map (lambda (slot)
83 `(cons ',(car slot) ,(cadr slot))
86 (define (,(symbol-append name '?) x)
87 (and (vector? x) (eq? (vector-ref x 0) ',name)))
89 (slots (cdr def) (cdr slots))
90 (ls '() (cons (let* ((slot (car slots))
91 (slot (if (pair? slot) (car slot) slot)))
92 `(define ,(string->symbol
93 (format #f "~A-~A" name n))
94 (lambda (x) (slot x ',slot))))
96 ((null? slots) (reverse! ls))))))
98 (define *unbound* "#<unbound>")
100 (define-public (%make-struct args slots)
102 (let* ((key (if (pair? slot) (car slot) slot))
103 (def (if (pair? slot) (cdr slot) *unbound*))
104 (val (get-key args (symbol->keyword key) def)))
105 (if (eq? val *unbound*)
106 (error "Slot unbound:" key)
110 (define (get-key klist key def)
111 (do ((ls klist (cddr ls)))
112 ((or (null? ls) (eq? (car ls) key))
113 (if (null? ls) def (cadr ls)))))
116 (make-procedure-with-setter
117 (lambda (struct name)
118 (let ((data (assq name (vector-ref struct 1))))
120 (error "Unknown slot:" name))
122 (lambda (struct name val)
123 (let ((data (assq name (vector-ref struct 1))))
125 (error "Unknown slot:" name))
126 (else (set-cdr! data val)))))))
133 (define-macro (| . rest)
134 `(begin ,@(map %make-variant-type rest)))
136 (define (%make-variant-type def)
137 (let ((name (car def)) (slots (cdr def)))
139 (define ,def (vector ',name ,@slots))
140 (define (,(symbol-append name '?) x)
141 (and (vector? x) (eq? (vector-ref x 0) ',name)))
143 (slots slots (cdr slots))
144 (ls '() (cons `(define ,(string->symbol
145 (format #f "~A-~A" name n))
146 ,(string->symbol (format #f "%slot-~A" n)))
148 ((null? slots) (reverse! ls))))))
150 (define-public (%slot-1 x) (vector-ref x 1))
151 (define-public (%slot-2 x) (vector-ref x 2))
152 (define-public (%slot-3 x) (vector-ref x 3))
153 (define-public (%slot-4 x) (vector-ref x 4))
154 (define-public (%slot-5 x) (vector-ref x 5))
155 (define-public (%slot-6 x) (vector-ref x 6))
156 (define-public (%slot-7 x) (vector-ref x 7))
157 (define-public (%slot-8 x) (vector-ref x 8))
158 (define-public (%slot-9 x) (vector-ref x 9))
165 (define-public (list-fold f d l)
168 (list-fold f (f (car l) d) (cdr l))))