-
Notifications
You must be signed in to change notification settings - Fork 2
/
scheme-r7rs-syntax.scm
66 lines (59 loc) · 2.75 KB
/
scheme-r7rs-syntax.scm
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
(define-library (scheme-r7rs-syntax)
(export check-library
check-library-declarations
library-has-declaration?
library-declarations)
(import (scheme base)
(lists)
(pattern-match)
(compilation-error))
(begin
(define (check-library exp)
(cond
((pattern-match? `(define-library (,?? ,??*) ,??*) exp)
(let ((identifiers (cadr exp)))
(if (pattern-match? `(scheme ,??*) identifiers)
(raise-compilation-error "scheme as first library name identifier is reserved" identifiers))
(let ((invalid-identifiers
(filter
(lambda (identifier)
(not
(or (symbol? identifier)
(and (number? identifier) (integer? identifier) (>= identifier 0)))))
identifiers)))
(if (not (null? invalid-identifiers))
(raise-compilation-error "Invalid library name identifiers" invalid-identifiers)))))
((pattern-match? `(define-library) exp)
(raise-compilation-error "Empty library definition" exp))
((pattern-match? `(define-library ,??) exp)
(raise-compilation-error "Expected list as library name" (cadr exp)))
(else
(raise-compilation-error "Invalid R7RS library definition" exp))))
(define (check-declaration decl)
(cond ((pattern-match? `(export ,?? ,??*) decl))
((pattern-match? '(export) decl)
(raise-compilation-error "Empty export library declaration" decl))
((pattern-match? `(import ,?? ,??*) decl))
((pattern-match? '(import) decl)
(raise-compilation-error "Empty import library declaration" decl))
((pattern-match? `(begin ,?? ,??*) decl))
((pattern-match? '(begin) decl)
(raise-compilation-error "Empty begin library declaration" decl))
((pattern-match? `(,?? ,??*) decl)
(raise-compilation-error "Unsupported R7RS library declaration" decl))
((not (pattern-match? `(,?? ,??*) decl))
(raise-compilation-error "Illegal R7RS library declaration" decl))))
(define (check-library-declarations library-def)
(for-each check-declaration (cddr library-def)))
(define (library-has-declaration? type library-def)
(and (assq type (cddr library-def)) #t))
(define (library-declarations type library-def)
(let collect ((decls (cddr library-def))
(decl '())
(result '()))
(cond ((null? decl)
(cond ((null? decls) (reverse result))
((eq? (caar decls) type) (collect (cdr decls) (cdar decls) result))
(else (collect (cdr decls) '() result))))
(else (collect decls (cdr decl) (cons (car decl) result))))))
))