You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
br-parser-tools/collects/mrspidey/Sba/ldexpand.ss

372 lines
14 KiB
Scheme

; ldexpand.ss - loads and macro expands source files
; ----------------------------------------------------------------------
; Copyright (C) 1995-97 Cormac Flanagan
;
; This program is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; version 2 as published by the Free Software Foundation.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
; ----------------------------------------------------------------------
(define (open-code-file filename)
(let ([filename (normalize-path filename)]
[cd (current-directory)])
(dynamic-let
([current-directory (path-only filename)])
(unless (file-exists? filename)
(mrspidey:error (format "Can't open file ~s, current directory ~s"
filename (current-directory))))
(let* ( [p (open-input-file filename 'text)]
[p (system-expand-if-necy p)])
p))))
(define (zodiac:read* port filename)
(let* ( [default-loc (zodiac:make-location 1 1 0 filename)]
[reader (if (st:fake-reader)
(fake-zodiac-reader port default-loc)
(zodiac:read port default-loc))]
[sexps
(recur loop ()
(let* ([expr (reader)])
(if (or (zodiac:eof? expr) (eof-object? expr))
'()
(begin
(when (zodiac:zodiac? expr)
(mrspidey:zprogress "Reading"
(zodiac:zodiac-start expr)))
(cons expr (loop))))))])
(unless (null? sexps)
(mrspidey:zprogress "Reading" (zodiac:zodiac-finish (rac sexps))))
(close-input-port port)
(when debugging-front
(printf "~n--Loaded file---------------------~n")
(for-each (lambda (sexp) (pretty-print (zodiac:stripper sexp))) sexps)
(printf "----------------------------------~n"))
sexps))
(define mrspidey:zprogress
(let ( [cur-phase '()]
[cur-line -100]
[cur-file ""])
(lambda (phase loc)
(let ( [file (zodiac:location-file loc)]
[line (zodiac:location-line loc)])
(unless (and
(equal? file cur-file)
(eq? phase cur-phase)
;;(>= line cur-line)
(< line (+ cur-line 10)))
(set! cur-phase phase)
(set! cur-line line)
(set! cur-file file)
(mrspidey:progress
(format "~a ~a: "
(padr phase 10)
(file-name-from-path file))
line))))))
; ----------------------------------------------------------------------
(define fake-zodiac-reader
(case-lambda
[(p) (fake-zodiac-reader p (zodiac:make-location 1 1 0 "filename"))]
[(p loc)
(lambda ()
(let ([x (read p)])
(recur loop ([x x])
(match x
[(? string?) (zodiac:make-string loc loc loc x)]
[(? boolean?) (zodiac:make-boolean loc loc loc x)]
[(? number?) (zodiac:make-number loc loc loc x)]
[(? symbol?) (zodiac:make-symbol loc loc loc x x x)]
[(? char?) (zodiac:make-char loc loc loc x)]
[(? vector?) (zodiac:make-vector loc loc loc
(map loop (vector->list x))
(vector-length x))]
[(? list?) (zodiac:make-list loc loc loc
(map loop x)
(length x)
'marks)]
[(? pair?) (zodiac:make-improper-list
loc loc loc
(recur loop2 ([x x])
(match x
[(a . d) (cons (loop a) (loop2 d))]
[r (list (loop r))]))
0
'period 'marks)]
[_ (if (eof-object? x)
(zodiac:make-eof loc)
(mrspidey:internal-error
'fake-zodiac-reader
"Bad object ~s" x))]))))]))
; ----------------------------------------------------------------------
(define (expand-zexp->port exp)
(let* ( [exp (zodiac:stripper exp)]
[s (format "~s" exp)]
[p (open-input-string s)]
[p (system-expand-if-necy p)])
p))
; ----------------------------------------------------------------------
(define (system-expand-if-necy p)
(if (st:system-expand)
(system-expand-port p)
p))
(define system-macros
'(;; --- r4rs
case cond do recur rec let* letrec let and or define
;; --- Chez things
parameterize fluid-let case-lambda let-values #%let-values
;; --- Rice things
match match-lambda match-lambda* match-let match-let*
;; --- My things
define-module global assert for
;; --- Misc
defmacro
;; Units w/ signatures
define-signature
unit-with-signature unit/sig
compound-unit/sig compound-unit-with-signature
invoke-unit/sig invoke-unit-with-signature
unit->unit/sig
))
(define (expander-eval e)
(parameterize ([current-namespace expander-namespace])
(eval e)))
(when (st:system-expand)
(expander-eval '(load "/home/cormac/Spidey/Code/Sba/expander-boot.ss")))
(define (my-expand e) (expander-eval `(expand-defmacro ',e)))
(define (my-expand-once e) (expander-eval `(expand-defmacro-once ',e)))
(define unchanged-list
'( define-constructor
define-type
primitive:
type:))
(define system-expanded-exp (void))
(define (system-expand-exp exp)
(set! system-expanded-exp exp)
(match exp
[((? (lambda (x) (memq x unchanged-list))) . _)
exp]
[_ (match (my-expand exp)
[(and e ((or '#%define-expansion-time '#%define-macro) . _))
(expander-eval e)
'(void)]
[e e])]))
(define (remove-signature-stuff e)
(recur loop ([e e])
(match e
[('#%make-unit-with-signature x _ _) (loop x)]
[('#%verify-signed-compound-sub-units . _) '(void)]
[('#%verify-linkage-signature-match . _) '(void)]
[('#%unit-with-signature-unit x) x]
[('#%invoke-open-unit expr name-specifier . imports)
`(#%invoke-unit ,(loop expr) ,@imports)]
[('#%invoke-open-unit expr)
`(#%invoke-unit ,(loop expr))]
[(('#%global-defined-value ('#%quote match:error)) . args)
'(error 'match "Match error")]
[(a . d) (cons (loop a) (loop d))]
[x x])))
(define (system-expand-port p)
(pretty-debug `(system-expand-port ,p ,(current-directory)))
(let* ([o (open-output-string)])
(parameterize
([pretty-print-depth #f])
(recur loop ([p p])
(let ([e (read p)])
(printf ".") (flush-output)
(unless (eof-object? e)
(recur process ([e e])
(match (system-expand-exp e)
[('#%begin . e*)
(for-each process e*)]
[e
(let* ([e (remove-signature-stuff e)])
(match e
[((or 'load '#%load '#%load/cd 'load/cd) exp)
(let ([filename (normalize-path (expander-eval exp))])
(unless (file-exists? filename)
(mrspidey:error (format "Can't load ~s" filename)))
(dynamic-let
([current-directory
(if (memq (car e) '(load/cd #%load/cd))
(path-only filename)
(current-directory))])
(let* ([p (open-input-file filename 'text)])
(printf "[File:~s " (file-name-from-path filename))
(loop p)
(printf "done]")
(close-input-port p))))]
[('load-recent s)
(process `(load ,(string-append s ".ss")))]
[(or '(void) (? void?)) (void)]
[e (pretty-print (strip-hash-percent e) o)]))]))
(loop p)))))
(begin0
(open-input-string (get-output-string o))
(close-output-port o)
(close-input-port p))))
(define (strip-hash-percent expr)
(recur loop ([expr expr])
(match expr
[('|#primitive| prim) prim]
[(a . d) (cons (loop a) (loop d))]
[(? symbol? x)
(let* ([s (symbol->string x)]
[l (string-length s)])
(if (and (> l 2)
(string=? (substring s 0 2) "#%"))
(string->symbol (substring s 2 l))
x))]
[x x])))
; ----------------------------------------------------------------------
(define expand-file
(case-lambda
[(infile)
(let ([infile (normalize-path infile)])
(let ([outfile (regexp-replace ".ss$" infile ".expanded")])
(when (eq? outfile infile)
(error 'expand-file "Bad suffix on ~s" infile))
(expand-file infile outfile)))]
[(infile outfile)
(when (file-exists? outfile) (delete-file outfile))
(dynamic-let ( [st:system-expand #t]
[current-directory (path-only (normalize-path infile))])
(let* ( [p (open-input-file infile 'text)]
[p2 (system-expand-if-necy p)]
[p3 (open-output-file outfile 'text)])
(printf "~nCopying:")
(recur loop ()
(let ([e (read p2)])
(unless (eof-object? e)
(pretty-print e p3)
(printf ".") (flush-output)
(loop))))
(newline)
(close-input-port p2)
(close-output-port p3)
outfile))]))
; ----------------------------------------------------------------------
(define file-time-cache '())
(define (clear-file-time-cache!)
(set! file-time-cache '()))
(define (extend-file-time-cache! file n)
(set! file-time-cache (cons (cons file n) file-time-cache)))
(define (file-time file)
(or (lookup-or-#f file-time-cache file)
(let* ([n (file-modify-seconds file)])
(unless (number? n)
(error 'file-time "file-modify-seconds failed on ~a" file))
(extend-file-time-cache! file n)
n)))
(define (zodiac-time x)
(let* ([start (zodiac:zodiac-start x)]
[file (zodiac:location-file start)])
(file-time file)))
(define (zodiac-time* x)
;; ## should be either current time, or file time of any imported file
;; is in right directory
(let* ([t (zodiac-time x)]
[fn (lambda (exp cl-fn)
(match exp
[($ zodiac:reference-unit-form _ _ _ _ file cd)
(let*-vals
( [_ (unless (zodiac:string? file)
(mrspidey:error
(format "reference-unit requires a string argument, given ~s" file)))]
[file (zodiac:read-object file)]
[file (if (relative-path? file)
(build-path cd file)
file)])
(when (file-exists? file)
(pretty-debug `(zodiac:time* includes ,file))
(set! t (max t (file-time file))))
#f)]
[_ #f]))])
((zodiac:compat fn) x)
t))
;; ======================================================================
(define attributes #f)
(define expander-namespace #f)
(define (init-expand!)
(set! attributes (zodiac:make-attributes))
(set! expander-namespace (make-expander-namespace)))
;; ----------------------------------------------------------------------
(define g:prog #f)
(define (my-scheme-expand-program defs)
;;(printf "my-scheme-expand-program cd=~s~n" (cd))
(let* ( [p (make-parameterization)]
[_ (with-parameterization p
(lambda ()
(current-namespace
expander-namespace
;(make-expander-namespace)
)
(reference-library "core.ss")
(reference-library "macro.ss")
'(reference
(begin-elaboration-time
(build-path
mred:plt-home-directory "mred" "system" "sig.ss")))
'(eval '(unit/sig () (import mred^) 1))
;;(printf "np=~s~n" normalize-path)
))]
; [defs2 (zodiac:expand-program
; defs attributes zodiac:mrspidey-vocabulary p)]
[defs2 (call/nal
zodiac:expand-program/nal
zodiac:expand-program
(expressions: defs)
(attributes: attributes)
(vocabulary: zodiac:mrspidey-vocabulary))]
; (parameterization: p))]
[defs2 (zodiac:inline-begins defs2)]
[_ (zodiac:initialize-mutated defs2)]
[free (zodiac:free-vars-defs defs2)])
(set! g:prog defs2)
;;(pretty-print defs2)
'(when debugging
(pretty-print (map zodiac:stripper defs2)))
(values defs2 free)))
;; ----------------------------------------------------------------------