rosella/libcompiler/reader.scm

50 lines
1.7 KiB
Scheme

#lang scheme/base
(require scheme/list)
(require scheme/match)
(require scheme/path)
(require scheme/pretty)
(provide read-module)
(define (read-module [port (current-input-port)])
`(lambda *argv*
,@(let iter ([forms (read-forms port)]
[bindings '()])
(match forms
['()
(if (null? bindings)
'()
`((letrec ,(reverse bindings))))]
[`((define (,(? symbol? var) . ,arglist) . ,body) . ,rst)
(iter rst (cons (list var `(lambda ,arglist ,@body)) bindings))]
[`((define ,(? symbol? var) ,expr) . ,rst)
(iter rst (cons (list var expr) bindings))]
[`((define . ,_) . ,_)
(error "Unrecognized define-form:" (first forms))]
[`((begin . ,body) . ,rst)
(iter (append body rst) bindings)]
[`(,form . ,rst)
(if (null? bindings)
(cons form (iter rst '()))
`((letrec ,(reverse bindings)
,@(cons form (iter rst '())))))]))))
(define (read-forms [port (current-input-port)])
(let iter ([form (read port)]
[forms '()])
(match form
[(? eof-object?)
(reverse forms)]
[`(load ,(? string? pathname))
(let ([loaded-forms (with-input-from-file pathname
(lambda ()
(parameterize ([current-directory (or (path-only pathname) ".")])
(read-forms))))])
(iter (read port) (cons `(begin ,@loaded-forms) forms)))]
[`(load . ,_)
(error "Unrecognized load-form:" (first forms))]
[_ (iter (read port) (cons form forms))])))
; vim:set sw=2 expandtab: