Skip to content

Commit d96f2a8

Browse files
committed
Split compiler pass into libraries
(it builds, but not runs yet)
1 parent 519bda5 commit d96f2a8

15 files changed

+6108
-5457
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ sagittarius-package
8484
/src/lib_kernel.c
8585
/src/lib_atomic.c
8686
/src/lib_iform.c
87+
/src/lib_pass1.c
88+
/src/lib_pass2.c
89+
/src/lib_pass3.c
90+
/src/lib_pass4.c
91+
/src/lib_pass5.c
8792
/src/compiler.c
8893
/src/compiler-aux.c
8994
/src/builtin-symbols.c

boot/aux-incl.scm

+141
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,144 @@
194194
((_ obj val)
195195
(vector-set! obj ,i val))))
196196
r))))))))))))
197+
198+
(define-syntax generate-dispatch-table
199+
(er-macro-transformer
200+
(lambda (form rename compare)
201+
(smatch form
202+
((_ prefix)
203+
`(vector ,@(imap (lambda (p)
204+
(string->symbol (string-append
205+
(symbol->string prefix) "/"
206+
(symbol->string (car p)))))
207+
.intermediate-tags.)))))))
208+
209+
;; used both pass1 and pass2
210+
(define (id->bound-gloc id)
211+
(let ((gloc (find-binding (id-library id) (id-name id) #f)))
212+
(and gloc (gloc-bound? gloc) gloc)))
213+
214+
;; to avoid unneccessary stack trace, we use guard.
215+
;; this is not the same as the one in exceptions.scm
216+
;; this does not use call/cc
217+
(define-syntax guard
218+
(syntax-rules ()
219+
((_ (var . clauses) . body)
220+
(with-error-handler
221+
(lambda (e)
222+
(let ((var e))
223+
(%guard-rec var e . clauses)))
224+
(lambda () . body) #t))))
225+
226+
(define-syntax %guard-rec
227+
(syntax-rules (else =>)
228+
((%guard-rec var exc)
229+
(raise exc))
230+
((%guard-rec var exc (else . exprs))
231+
(begin . exprs))
232+
((%guard-rec var exc (test => proc) . more)
233+
(let ((tmp test))
234+
(if tmp
235+
(proc tmp)
236+
(%guard-rec var exc . more))))
237+
((%guard-rec var exc (test . exprs) . more)
238+
(if test
239+
(begin . exprs)
240+
(%guard-rec var exc . more)))
241+
((%guard-rec var exc other . more)
242+
(syntax-error "malformed guard clause" other))))
243+
244+
(define (add-backtrace c src) (make-trace-condition (truncate-program src)))
245+
246+
(define (format-source-info info)
247+
(if info
248+
(format "~s:~d" (car info) (cdr info))
249+
#f))
250+
251+
(define (truncate-program program)
252+
(if (circular-list? program)
253+
program
254+
(unwrap-syntax program)))
255+
256+
;; IFORM must be a $LAMBDA node. This expands the application of IFORM
257+
;; on IARGS (list of IForm) into a mere $LET node.
258+
;; used both pass1 and pass2
259+
(define (expand-inlined-procedure src iform iargs)
260+
(let ((lvars ($lambda-lvars iform))
261+
(args (adjust-arglist src
262+
($lambda-args iform)
263+
($lambda-option iform)
264+
iargs ($lambda-name iform))))
265+
(ifor-each2 (lambda (lv a) (lvar-initval-set! lv a)) lvars args)
266+
($let src 'let lvars args ($lambda-body iform))))
267+
268+
;; Adjust argmuent list according to reqargs and optarg count.
269+
;; Used in procedure inlining and local call optimization.
270+
;; used both pass1 and pass2
271+
(define (adjust-arglist src reqargs optarg iargs name)
272+
(unless (argcount-ok? iargs reqargs (> optarg 0))
273+
(raise (condition (make-compile-error
274+
(format-source-info (source-info src))
275+
(truncate-program src))
276+
(make-who-condition name)
277+
(make-message-condition
278+
(format
279+
"wrong number of arguments: ~s requires ~a, but got ~a"
280+
name reqargs (length iargs))))))
281+
(if (zero? optarg)
282+
iargs
283+
(receive (reqs opts) (split-at iargs reqargs)
284+
(append! reqs (list ($list #f opts))))))
285+
286+
;; used both pass1 and pass2
287+
(define (argcount-ok? args reqargs optarg?)
288+
(let ((nargs (length args)))
289+
(or (and (not optarg?) (= nargs reqargs))
290+
(and optarg? (>= nargs reqargs)))))
291+
292+
;; see if the given iform is referentially transparent. That is the iform is
293+
;; side effect free, and alto the value of iform won't change even if we move
294+
;; iform to a differnet place in the subtree.
295+
(define (everyc proc lis c) ;avoid closure allocation
296+
(or (null? lis)
297+
(let loop ((lis lis))
298+
(smatch lis
299+
((x) (proc x c))
300+
((x . xs) (and (proc x c) (loop xs)))))))
301+
;; used both pass2 and pass3
302+
(define (transparent? iform) (transparent?/rec iform (make-label-dic #f)))
303+
(define (transparent?/rec iform labels)
304+
(case/unquote (iform-tag iform)
305+
(($LREF ) (zero? (lvar-set-count ($lref-lvar iform))))
306+
(($GREF ) (inlinable-binding? ($gref-id iform) #t))
307+
(($CONST $LAMBDA $IT $UNDEF) #t)
308+
(($IF ) (and (transparent?/rec ($if-test iform) labels)
309+
(transparent?/rec ($if-then iform) labels)
310+
(transparent?/rec ($if-else iform) labels)))
311+
(($LET ) (and (everyc transparent?/rec ($let-inits iform) labels)
312+
(transparent?/rec ($let-body iform) labels)))
313+
(($LABEL ) (or (label-seen? labels iform)
314+
(begin (label-push! labels iform)
315+
(transparent?/rec ($label-body iform) labels))))
316+
(($SEQ ) (everyc transparent?/rec ($seq-body iform) labels))
317+
(($CALL ) (and (no-side-effect-call? ($call-proc iform) ($call-args iform))
318+
(everyc transparent?/rec ($call-args iform) labels)))
319+
(($ASM ) (and (no-side-effect-insn? ($asm-insn iform) ($asm-args iform))
320+
(everyc transparent?/rec ($asm-args iform) labels)))
321+
(($LIST ) (everyc transparent?/rec ($list-args iform) labels))
322+
(($RECEIVE) (and (transparent?/rec ($receive-expr iform) labels)
323+
(transparent?/rec ($receive-body iform) labels)))
324+
(else #f)))
325+
326+
;; label dictionary
327+
(define (make-label-dic init) (list init))
328+
(define (copy-label-dic label) (cons (car label) (cdr label)))
329+
(define (label-seen? label-dic label-node)
330+
(memq label-node (cdr label-dic)))
331+
(define (label-push! label-dic label-node)
332+
(set-cdr! label-dic (cons label-node (cdr label-dic))))
333+
(define (label-dic-info label-dic) (car label-dic))
334+
(define (label-dic-info-set! label-dic val) (set-car! label-dic val))
335+
(define (label-dic-info-push! label-dic val)
336+
(set-car! label-dic (cons val (car label-dic))))
337+

0 commit comments

Comments
 (0)