(define-library (csc compiler) (import (scheme base) (only (csc hash-map) hash-bytevector insert key-not-found-error? lookup make-map map-for-each merge) (only (csc ir1) toplevel-define?) (only (csc loop) loop return) (only (csc macros) builtins-environment expand) (only (csc match) match)) (begin (define (hash-symbol s) (hash-bytevector (string->utf8 (symbol->string s)))) (define (cmp-symbol s1 s2) (stringstring s1) (symbol->string s2))) (define-record-type (make-syntax-error msg irritants) syntax-error?) (define (raise-syntax-error msg . irritants) (raise (make-syntax-error msg irritants))) (define (parse-import-set expr) (match expr (((! 'only) import-set . idents) (loop with bindings = (parse-import-set import-set) and new-bindings = (make-map hash-symbol cmp-symbol) for ident in idents do (set! new-bindings (insert new-bindings ident (guard (e ((key-not-found-error? e) (raise-syntax-error "unknown symbol in `only' form" ident))) (lookup bindings ident)))) finally (return new-bindings))) ((! '(csc builtins)) builtins-environment) (_ (raise-syntax-error "unknown or unsupported import set form" expr)))) (define (parse-import expr) (match expr (((! 'import) . import-sets) (loop with bindings = (make-map hash-symbol cmp-symbol) for import-set in import-sets do (set! bindings (merge bindings (parse-import-set import-set))) finally (return bindings))) (_ (raise-syntax-error "expected import form" expr)))) (define-record-type (make-program imports body) program? (imports program-imports) (body program-body)) ; A Scheme program consists of one or more import declarations ; followed by a sequence of expressions and definitions. ; -- R7RS (define (program->ir1 program) (loop with bindings = (make-map hash-symbol cmp-symbol) for body on program for expr = (car body) do (match expr (((! 'import) . import-sets) (set! bindings (merge bindings (parse-import expr)))) (_ (loop for expr in body for expanded-expr = (expand expr bindings) if (toplevel-define? expanded-expr)