From 07221d401de8d633cc58fec8c313617b0716ef1d Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Thu, 3 Mar 2022 13:51:41 -0800 Subject: Write the compiler frontend. --- csc/compiler.csc | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 csc/compiler.csc (limited to 'csc/compiler.csc') diff --git a/csc/compiler.csc b/csc/compiler.csc new file mode 100644 index 0000000..5486344 --- /dev/null +++ b/csc/compiler.csc @@ -0,0 +1,89 @@ +(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) -- cgit v1.3.1