diff options
| author | Rose Hogenson <rhogenson@posteo.net> | 2022-03-03 13:51:41 -0800 |
|---|---|---|
| committer | Rose Hogenson <rhogenson@posteo.net> | 2022-03-03 13:51:41 -0800 |
| commit | 07221d401de8d633cc58fec8c313617b0716ef1d (patch) | |
| tree | 18573067f6dd5ccec9bbfaedde79fb0e2e2fe630 /csc/compiler.csc | |
| parent | Start the garbage collector. (diff) | |
| download | chromatopelma-07221d401de8d633cc58fec8c313617b0716ef1d.tar.zst | |
Write the compiler frontend.
Diffstat (limited to 'csc/compiler.csc')
| -rw-r--r-- | csc/compiler.csc | 89 |
1 files changed, 89 insertions, 0 deletions
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) + (string<? (symbol->string s1) (symbol->string s2))) + + + (define-record-type <syntax-error> + (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 <program> + (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) |
