rosella/libcompiler/reader.scm

50 lines
1.8 KiB
Scheme

#lang scheme/base
(require scheme/list)
(require scheme/path)
(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 ,var ,expr) . ,rst)
(iter rst (cons (list var expr) bindings))]
[`((define (,var . ,arglist) . ,body) . ,rst)
(iter rst (cons (list var `(lambda ,arglist ,@body)) bindings))]
[`((define . ,_) . ,_)
(error "Unrecognized define-form:" (first forms))]
[`((begin . ,body) . ,rst)
(iter (append body rst) bindings)]
[`((load ,(? string? pathname)) . ,rst)
(let ([complete-path (path->complete-path pathname)]
[directory (path-only complete-path)])
(iter (append (with-input-from-file complete-path
(lambda ()
(parameterize ([current-directory directory])
(read-forms))))
rst)
bindings))]
[`((load . ,_) . ,rst)
(error "Unrecognized load-form:" (first forms))]
[(,form . ,rst)
(if (null? bindings)
(cons form (iter rst '()))
`((letrec ,(reverse bindings)
,@(cons form (iter rst '())))))]))))
(define (read-forms [port (current-input-port)])
(reverse (let iter ([form (read port)]
[forms '()])
(if (eof-object? form)
forms
(iter (read port) (cons form forms))))))
; vim:set sw=2 expandtab: