-
Notifications
You must be signed in to change notification settings - Fork 32
/
compile-larceny
executable file
·173 lines (161 loc) · 6.22 KB
/
compile-larceny
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/bin/env scheme-script
#!r7rs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Usage:
;;;
;;; compile-larceny [options...] [pathname]
;;;
;;; Compiles the R7RS top-level program contained within the
;;; file named by pathname. If no pathname is given, but one
;;; or more directories are specified by -I or -A options,
;;; attempts to compile any R7RS or R6RS libraries found in
;;; those directories.
;;;
;;; Options:
;;;
;;; -o outfile
;;; Specifies the name of the executable file to be
;;; generated. If this option is omitted, and the
;;; pathname is of the form pgm.scm or pgm.sps, then
;;; the executable file will be named pgm. If the
;;; pathname is of some other form, and no outfile
;;; is specified via this option, then the executable
;;; file will be named a.out.
;;;
;;; -I directory
;;; -A directory
;;; These options specify a directory to be searched
;;; when locating libraries imported by the program.
;;; The -I option specifies a directory to be searched
;;; before searching directories that contain standard
;;; libraries, while the -A option specifies a directory
;;; to be searched after.
;;;
;;; -D feature
;;; Declares a feature to be recognized by cond-expand
;;; when the program is compiled.
;;;
;;; The -I, -A, and -D options may be used more than once.
;;;
;;; When compiling a program, all libraries imported by the
;;; program, whether directly or indirectly, are assumed to
;;; have already been compiled, or don't need to be compiled,
;;; or are contained within the program file itself.
;;;
;;; If no program or output file is specified, then an attempt
;;; will be made to compile all libraries found within directories
;;; specified by -I or -A options, proceeding from left to right.
;;; That compilation process will respect import dependencies
;;; between libraries located within one of those directories
;;; and any of its subdirectories, but will not respect import
;;; dependencies between libraries located within two different
;;; directories specified by the -I or -A options. If a library
;;; found within the first directory specified imports a library
;;; located within the second directory specified, the compiled
;;; forms of those libraries will not be consistent, and any
;;; programs that import both of them will not run.
;;;
;;; See SRFI 138: http://srfi.schemers.org/srfi-138
;;;
;;; KNOWN BUGS:
;;;
;;; doesn't yet look at the COMPILE_R7RS environment variable.
;;; doesn't handle colon-separated directory lists
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(import (scheme base)
(scheme cxr)
(scheme process-context)
(scheme write)
(scheme list)
(srfi 138)
(larceny compiler)
(larceny parse-options))
(define (usage-message)
(let ((q (current-error-port)))
(for-each
(lambda (s) (display s q) (newline q))
'("Usage: compile-larceny [ OPTION ... ] [ PGM ]"
" compiles PGM as specified by SRFI 138"
"Options:"
" -o outfile"
" -I directory"
" -A directory"
" -D feature")))
(exit 1))
;;; cmds will resemble
;;; ("larceny" "compile-larceny" "-I" "dir1" ... "pgm.scm")
(define cmds (command-line))
;;; Returns 6 values:
;;; the name of the program to be compiled, or #f
;;; the name of the executable file to be generated, or #f
;;; the list of -D features, from left to right
;;; the list of -I directories, from left to right
;;; the list of -A directories, from left to right
;;; the list of all -I and -A directories, from left to right
(define (parse-commands)
(call-with-values
(lambda ()
(larceny:parse-options (cddr cmds)
'((seq "-o" _)
(seq "-D" _)
(seq (or "-I" "-A") _))))
(lambda (pgms opts-o opts-D opts-IA)
(cond ((or (> (length pgms) 1)
(> (length opts-o) 1))
(usage-message)
(values #f #f '() '() '() '()))
(else
(values (if (null? pgms) #f (car pgms))
(if (null? opts-o) #f (cadr (car opts-o)))
(map cadr opts-D)
(map cadr
(filter (lambda (x) (string=? (car x) "-I"))
opts-IA))
(map cadr
(filter (lambda (x) (string=? (car x) "-A"))
opts-IA))
(map cadr opts-IA)))))))
(define (process-commands)
(call-with-values
parse-commands
(lambda (pgm outfile features dirs1 dirs2 alldirs)
(cond (pgm
(compile-r7rs pgm outfile dirs1 dirs2 features))
(outfile
(usage-message))
((null? alldirs)
(usage-message))
(else
(display "Compiling libraries...\n"
(current-error-port))
(guard (exn (#t (report-error-and-exit exn)))
(for-each (lambda (dir)
(parameterize
((current-require-path
(append dirs1
(current-require-path)
dirs2))
(larceny:current-declared-features
(append (larceny:current-declared-features)
features))
(current-directory dir))
(compile-stale-libraries)))
alldirs)))))))
(define (report-error-and-exit exn)
(report-error exn)
(exit 1))
(define (report-error exn)
(display "ERROR: " (current-error-port))
(if (error-object? exn)
(begin (display (error-object-message exn)
(current-error-port))
(newline (current-error-port))
(for-each (lambda (x)
(write x (current-error-port))
(newline (current-error-port)))
(error-object-irritants exn)))
(display "abandoning compilation\n"
(current-error-port))))
(process-commands)