This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
((begin | |
(define-syntax | |
case-lambda | |
(syntax-rules | |
() | |
((_ (frm code ...)) (lambda frm code ...)) | |
((_ clauses ...) (%%gen-case-lambda-dispatch () () () clauses ...)))) | |
(define-syntax | |
%%emit-case-lambda-body | |
(syntax-rules | |
() | |
((_ () () () count x) (error "case-lambda: unmatched" count)) | |
((_ (n ...) (#t ...) ((frm body ...)) count x) (let ((frm x)) body ...)) | |
((_ (n nn ...) (pred pp ...) ((frm body ...) next ...) count x) | |
(if (pred count n) | |
(apply (lambda frm body ...) x) | |
(%%emit-case-lambda-body (nn ...) (pp ...) (next ...) count x))))) | |
(define-syntax | |
%gen-case-lambda-dotted-reverse-quote | |
(syntax-rules | |
() | |
((_ acc (frm a . d)) | |
(%gen-case-lambda-dotted-reverse-quote (frm . acc) (a . d))) | |
((_ acc (frm . rest)) '(frm . acc)))) | |
(define-syntax | |
%%gen-case-lambda-dispatch | |
(syntax-rules | |
() | |
((_ n pred clauses) | |
(lambda x | |
(let ((count (length x))) | |
(%%emit-case-lambda-body n pred clauses count x)))) | |
((_ (n ...) (pred ...) (clauses ...) ((frms ...) . code) next ...) | |
(let ((nn (length '(frms ...)))) | |
(%%gen-case-lambda-dispatch | |
(n ... nn) | |
(pred ... =) | |
(clauses ... ((frms ...) . code)) | |
next | |
...))) | |
((_ (n ...) (pred ...) (clauses ...) ((frms . rest) . code) next ...) | |
(let ((nn (length (%gen-case-lambda-dotted-reverse-quote | |
() | |
(frms . rest))))) | |
(%%gen-case-lambda-dispatch | |
(n ... nn) | |
(pred ... >=) | |
(clauses ... ((frms . rest) . code)) | |
next | |
...))) | |
((_ (n ...) (pred ...) (clauses ...) (frms . code) next ...) | |
(%%gen-case-lambda-dispatch | |
(n ... #t) | |
(pred ... #t) | |
(clauses ... (frms . code)) | |
next | |
...))))) | |
(begin | |
(define %%my-eof-object (let ((p (open-input-string ""))) (read p))) | |
(define (eof-object) %%my-eof-object) | |
(define (flush-output-port p) 'do-nothing) | |
(define bytevector? u8vector?) | |
(define bytevector u8vector) | |
(define bytevector-append u8vector-append) | |
(define bytevector-copy u8vector-copy) | |
(define bytevector-length u8vector-length) | |
(define bytevector-u8-ref u8vector-ref) | |
(define bytevector-u8-set! u8vector-set!) | |
(define make-bytevector make-u8vector) | |
(define bytevector-copy! | |
(case-lambda | |
((to at from) (bytevector-copy! to at from 0)) | |
((to at from start) | |
(let ((flen (bytevector-length from)) (tlen (bytevector-length to))) | |
(let ((fmaxcopysize (- flen start)) (tmaxcopysize (- tlen at))) | |
(bytevector-copy! | |
to | |
at | |
from | |
start | |
(+ start (min fmaxcopysize tmaxcopysize)))))) | |
((to at from start end) (subu8vector-move! from start end to at)))) | |
(define (%utf8->string u8) | |
(define len (u8vector-length u8)) | |
(define (complain) (error "Illegal utf8 sequence" u8)) | |
(call-with-output-string | |
'() | |
(lambda (p) | |
(let loop ((idx 0)) | |
(define rest (- len idx)) | |
(cond ((= idx len) p) | |
(else | |
(let ((c0 (u8vector-ref u8 idx))) | |
(cond ((< c0 128) | |
(write-char (integer->char c0) p) | |
(loop (+ 1 idx))) | |
((< c0 224) | |
(if (< rest 1) (complain)) | |
(let* ((c1 (u8vector-ref u8 (+ 1 idx))) | |
(i (bitwise-ior | |
(arithmetic-shift (bitwise-and 31 c0) 6) | |
(bitwise-and 63 c1)))) | |
(write-char (integer->char i) p)) | |
(loop (+ 2 idx))) | |
((< c0 240) | |
(if (< rest 2) (complain)) | |
(let* ((c1 (u8vector-ref u8 (+ 1 idx))) | |
(c2 (u8vector-ref u8 (+ 2 idx))) | |
(i (bitwise-ior | |
(arithmetic-shift (bitwise-and 15 c0) 12) | |
(arithmetic-shift (bitwise-and 63 c1) 6) | |
(bitwise-and 63 c2)))) | |
(write-char (integer->char i) p)) | |
(loop (+ 3 idx))) | |
((< c0 245) | |
(if (< rest 3) (complain)) | |
(let* ((c1 (u8vector-ref u8 (+ 1 idx))) | |
(c2 (u8vector-ref u8 (+ 2 idx))) | |
(c3 (u8vector-ref u8 (+ 3 idx))) | |
(i (bitwise-ior | |
(arithmetic-shift (bitwise-and 7 c0) 18) | |
(arithmetic-shift (bitwise-and 63 c1) 12) | |
(arithmetic-shift (bitwise-and 63 c2) 6) | |
c3))) | |
(write-char (integer->char i) p)) | |
(loop (+ 4 idx))) | |
(else (complain)))))))))) | |
(define utf8->string | |
(case-lambda | |
((u8) (%utf8->string u8)) | |
((u8 start) (%utf8->string (subu8vector u8 start (u8vector-length u8)))) | |
((u8 start end) (%utf8->string (subu8vector u8 start end))))) | |
(define (%string->utf8 str) | |
(define len (string-length str)) | |
(call-with-output-u8vector | |
'() | |
(lambda (p) | |
(let loop ((idx 0)) | |
(cond ((= idx len) p) | |
(else | |
(let ((i (char->integer (string-ref str idx)))) | |
(cond ((< i 128) (write-u8 i p)) | |
((< i 2048) | |
(let ((c0 (bitwise-ior | |
192 | |
(bitwise-and 31 (arithmetic-shift i -6)))) | |
(c1 (bitwise-ior 128 (bitwise-and 63 i)))) | |
(write-u8 c0 p) | |
(write-u8 c1 p))) | |
((< i 65536) | |
(let ((c0 (bitwise-ior | |
224 | |
(bitwise-and | |
15 | |
(arithmetic-shift i -12)))) | |
(c1 (bitwise-ior | |
128 | |
(bitwise-and 63 (arithmetic-shift i -6)))) | |
(c2 (bitwise-ior 128 (bitwise-and 63 i)))) | |
(write-u8 c0 p) | |
(write-u8 c1 p) | |
(write-u8 c2 p))) | |
((< i 1114112) | |
(let ((c0 (bitwise-ior | |
240 | |
(bitwise-and 7 (arithmetic-shift i -18)))) | |
(c1 (bitwise-ior | |
128 | |
(bitwise-and | |
63 | |
(arithmetic-shift i -12)))) | |
(c2 (bitwise-ior | |
128 | |
(bitwise-and 63 (arithmetic-shift i -6)))) | |
(c3 (bitwise-ior 128 (bitwise-and 63 i)))) | |
(write-u8 c0 p) | |
(write-u8 c1 p) | |
(write-u8 c2 p) | |
(write-u8 c3 p))) | |
(else (error "Invalid character" i str)))) | |
(loop (+ 1 idx)))))))) | |
(define string->utf8 | |
(case-lambda | |
((str) (%string->utf8 str)) | |
((str start) (%string->utf8 (substring str start (string-length str)))) | |
((str start end) (%string->utf8 (substring str start end))))) | |
(define-syntax | |
define-record-type | |
(syntax-rules | |
() | |
((_ name (ctr ctr-name ...) pred? flds ...) | |
(begin | |
(define name (list 'table-type)) | |
(define (ctr ctr-name ...) | |
(define theRecord (make-table)) | |
(table-set! theRecord '%%yunifake-record-type name) | |
(table-set! theRecord 'ctr-name ctr-name) | |
... | |
theRecord) | |
(define (pred? obj) | |
(and (table? obj) | |
(eq? name (table-ref obj '%%yunifake-record-type)))) | |
(%define-record-type-fields pred? flds) | |
...)))) | |
(define-syntax | |
%define-record-type-fields | |
(syntax-rules | |
() | |
((_ pred? (field-name accessor)) | |
(begin | |
(define (accessor obj) | |
(cond ((pred? obj) (table-ref obj 'field-name)) | |
(else (error "Unexpected object" pred? obj)))))) | |
((_ pred? (field-name accessor setter)) | |
(begin | |
(define (setter obj val) | |
(cond ((pred? obj) (table-set! obj 'field-name val)) | |
(else (error "Unexpected object" pred? obj)))) | |
(%define-record-type-fields pred? (field-name accessor)))))) | |
(define-syntax | |
when | |
(syntax-rules () ((_ pred code ...) (cond (pred code ...))))) | |
(define-syntax | |
unless | |
(syntax-rules () ((_ pred code ...) (cond ((not pred) code ...)))))) | |
(begin | |
(define %%%export-testeval~24 #f) | |
(define %%%export-failure?~25 #f) | |
(define %%%export-failure->string~26 #f) | |
(let () | |
(define failure-header (list "Yuni testing failure")) | |
(define (failure? x) (not (eq? #t x))) | |
(define (failure->string f) | |
(let ((p (open-output-string))) (write f p) (get-output-string p))) | |
(define (testeval form lib*) | |
(define (libname lib) | |
(if (pair? lib) | |
(case (car lib) | |
((rename except only) (libname (cadr lib))) | |
(else lib)))) | |
(define (assert-for-library lib) | |
(guard (c (#t c)) (begin (eval 123 (environment lib)) #f))) | |
(define (assert-for-libraries libs*) | |
(and (pair? libs*) | |
(or (assert-for-library (libname (car libs*))) | |
(assert-for-libraries (cdr libs*))))) | |
(let ((libresult (assert-for-libraries lib*))) | |
(if libresult | |
(values #f libresult) | |
(guard (c (#t (values #f c))) | |
(let ((ret (eval form (apply environment lib*)))) | |
(values ret #t)))))) | |
(set! %%%export-testeval~24 testeval) | |
(set! %%%export-failure?~25 failure?) | |
(set! %%%export-failure->string~26 failure->string))) | |
(begin | |
(begin | |
(define-syntax | |
seq | |
(syntax-rules | |
(=>) | |
((_ clauses ... => error-handler) (seq => error-handler clauses ...)) | |
((_ => error-handler clauses ...) | |
(let ((err error-handler)) (%seq/clauses err clauses ...))) | |
((_ otherwise ...) (seq => (lambda x (if #f #f)) otherwise ...)))) | |
(define-syntax | |
%seq/clauses | |
(syntax-rules | |
(=>) | |
((_ err (=> something ...) anything ...) | |
(%seq/splitL | |
() | |
() | |
(something ...) | |
(err (%seq/clauses err anything ...)))) | |
((_ err normal-form next-form ...) | |
(begin normal-form (%seq/clauses err next-form ...))) | |
((_ err) (begin)))) | |
(define-syntax | |
%seq/splitL | |
(syntax-rules | |
(=>) | |
((_ cur (acc ...) (item => something ...) n) | |
(%seq/splitR cur (acc ... item) () (something ...) n)) | |
((_ cur (acc ...) (s0 s1 ...) n) | |
(%seq/splitL cur (acc ... s0) (s1 ...) n)))) | |
(define-syntax | |
%seq/splitR | |
(syntax-rules | |
(=>) | |
((_ (cur ...) L R () (err next)) (%seq/emit err (cur ... (L R)) next)) | |
((_ (cur ...) L (acc ...) (item => something ...) n) | |
(%seq/splitL (cur ... (L (acc ... item))) () (something ...) n)) | |
((_ cur L (acc ...) (something anything ...) n) | |
(%seq/splitR cur L (acc ... something) (anything ...) n)))) | |
(define-syntax | |
%seq/emit | |
(syntax-rules | |
() | |
((_ err () next) next) | |
((_ err ((q0 c0) qc1 ...) next) | |
(%seq/gen err q0 c0 (%seq/emit err (qc1 ...) next))))) | |
(define-syntax | |
%seq/gen | |
(syntax-rules | |
'unquote | |
((_ err ('something q0 ...) c0 next) | |
(%seq/call 'err something (q0 ...) c0 next)) | |
((_ err (,something q0 ...) c0 next) | |
(%seq/call err something (q0 ...) c0 next)) | |
((_ err (anything ...) c0 next) | |
(%seq/call err #f (anything ...) c0 next)))) | |
(define-syntax | |
%seq/call | |
(syntax-rules | |
() | |
((_ err id (call ...) recv next) | |
(call ... (%seq/gencallback err id () () recv next))))) | |
(define-syntax | |
%seq/gencallback | |
(syntax-rules | |
() | |
((_ err id (names ...) (checks ...) () next) | |
(lambda (names ...) (if (and checks ...) next (err id names ...)))) | |
((_ err id (names ...) (checks ...) ((checker name) obj ...) next) | |
(%seq/gencallback | |
err | |
id | |
(names ... name) | |
(checks ... (checker name)) | |
(obj ...) | |
next)) | |
((_ err id (names ...) (checks ...) ((name) obj ...) next) | |
(%seq/gencallback | |
err | |
id | |
(names ... name) | |
(checks ... name) | |
(obj ...) | |
next)) | |
((_ err id (names ...) checks (name obj ...) next) | |
(%seq/gencallback err id (names ... name) checks (obj ...) next)))) | |
(define (apply/async limit proc param callback) | |
(define len (length param)) | |
(define input (list->vector param)) | |
(define v (make-vector len #f)) | |
(define count 0) | |
(define jobs 0) | |
(define count-finish 0) | |
(define abort? #f) | |
(define (job-finish) (set! jobs (- jobs 1))) | |
(define (last-job?) | |
(set! count-finish (+ 1 count-finish)) | |
(= count-finish len)) | |
(define (enqueue) | |
(if abort? | |
(if (last-job?) (callback (vector->list v)) (next)) | |
(let* ((par (vector-ref input count)) | |
(idx count) | |
(cb (lambda x | |
(vector-set! v idx x) | |
(job-finish) | |
(if (last-job?) | |
(callback (vector->list v)) | |
(next))))) | |
(set! jobs (+ jobs 1)) | |
(let ((r (if (list? par) | |
(apply proc (append par (list cb))) | |
(proc par cb)))) | |
(unless r (set! jobs 0) (set! abort? #t)))))) | |
(define (next) | |
(unless (or (= count len) (and limit (= jobs limit))) | |
(enqueue) | |
(set! count (+ count 1)) | |
(next)) | |
(not abort?)) | |
(next)))) | |
(begin | |
(define %%%export-miniobj-rnrs-ref-error~28 #f) | |
(define %%%export-miniobj-rnrs-set!-error~29 #f) | |
(let () | |
(define (miniobj-rnrs-ref-error obj slot) | |
(error "miniobj: unsupported object" (list obj slot))) | |
(define (miniobj-rnrs-set!-error obj slot value) | |
(error "miniobj: unsupported object" (list obj slot value))) | |
(set! %%%export-miniobj-rnrs-ref-error~28 miniobj-rnrs-ref-error) | |
(set! %%%export-miniobj-rnrs-set!-error~29 miniobj-rnrs-set!-error))) | |
(begin | |
(define %%%export-make-simple-struct~30 #f) | |
(define %%%export-simple-struct-name~31 #f) | |
(define %%%export-simple-struct-ref~32 #f) | |
(define %%%export-simple-struct-set!~33 #f) | |
(define %%%export-simple-struct?~34 #f) | |
(let () | |
(define-record-type | |
<yuni-simple-struct> | |
(%make-simple-struct0 name object) | |
simple-struct? | |
(name simple-struct-name) | |
(object %simple-struct-obj)) | |
(define (simple-struct-ref obj idx) | |
(vector-ref (%simple-struct-obj obj) idx)) | |
(define (simple-struct-set! obj idx v) | |
(vector-set! (%simple-struct-obj obj) idx v)) | |
(define (make-simple-struct name len lis) | |
(%make-simple-struct0 name (list->vector lis))) | |
(set! %%%export-make-simple-struct~30 make-simple-struct) | |
(set! %%%export-simple-struct-name~31 simple-struct-name) | |
(set! %%%export-simple-struct-ref~32 simple-struct-ref) | |
(set! %%%export-simple-struct-set!~33 simple-struct-set!) | |
(set! %%%export-simple-struct?~34 simple-struct?))) | |
(begin | |
(define make-simple-struct %%%export-make-simple-struct~30) | |
(define simple-struct-name %%%export-simple-struct-name~31) | |
(define simple-struct-ref %%%export-simple-struct-ref~32) | |
(define simple-struct-set! %%%export-simple-struct-set!~33) | |
(define simple-struct? %%%export-simple-struct?~34) | |
(define (check? obj sym) | |
(and (simple-struct? obj) (eq? sym (simple-struct-name obj)))) | |
(define (minitype? obj) (check? obj '*yuni-minitype*)) | |
(define (minitype-obj? obj) (check? obj '*yuni-minitype-obj*)) | |
(define (check-minitype obj) | |
(or (minitype? obj) (error "minitype needed" obj))) | |
(define (check-minitype-obj obj) | |
(or (minitype-obj? obj) (error "minitype-obj needed" obj))) | |
(define (minitype-slot obj) (check-minitype obj) (simple-struct-ref obj 1)) | |
(define (minitype-obj-slot obj) | |
(check-minitype-obj obj) | |
(simple-struct-ref obj 1)) | |
(define (minitype-obj-type obj) | |
(check-minitype-obj obj) | |
(simple-struct-ref obj 0)) | |
(define (make-minitype name slots) | |
(make-simple-struct '*yuni-minitype* 2 (list name slots))) | |
(define (make-minitype-obj minitype) | |
(check-minitype minitype) | |
(lambda () | |
(make-simple-struct | |
'*yuni-minitype-obj* | |
2 | |
(list minitype (make-vector (length (minitype-slot minitype))))))) | |
(define (minitype-predicate obj minitype) | |
(check-minitype minitype) | |
(and (minitype-obj? obj) (eq? minitype (minitype-obj-type obj)))) | |
(define (minitype-typeof obj) | |
(and (minitype-obj? obj) (minitype-obj-type obj))) | |
(define (scan-slot minitype slot) | |
(define (number cur rest) | |
(if (pair? rest) | |
(if (eq? (car rest) slot) cur (number (+ 1 cur) (cdr rest))) | |
#f)) | |
(let ((slots (minitype-slot minitype))) (number 0 slots))) | |
(define (miniobj-minitype-typeof obj k) | |
(if (minitype-obj? obj) (minitype-obj-type obj) (k obj))) | |
(define (miniobj-minitype-typeof-error obj) | |
(error "unsupported object" obj)) | |
(define (miniobj-minitype-ref obj slot k) | |
(if (minitype-obj? obj) | |
(vector-ref | |
(minitype-obj-slot obj) | |
(scan-slot (minitype-obj-type obj) slot)) | |
(k obj slot))) | |
(define (miniobj-minitype-set! obj slot value k) | |
(if (minitype-obj? obj) | |
(vector-set! | |
(minitype-obj-slot obj) | |
(scan-slot (minitype-obj-type obj) slot) | |
value) | |
(k obj slot value))) | |
(define-syntax | |
define-minitype | |
(syntax-rules | |
() | |
((_ name spec) (define name (make-minitype 'name 'spec)))))) | |
(begin | |
(define-minitype <minidispatch> (name func)) | |
(define-minitype <minidispatch-obj> (minitype obj)) | |
(define (baseref obj slot) | |
(define (complain obj slot) (error "Fatal error" obj slot)) | |
(miniobj-minitype-ref obj slot complain)) | |
(define (baseset! obj slot v) | |
(define (complain obj slot v) (error "Fatal error" obj slot)) | |
(miniobj-minitype-set! obj slot v complain)) | |
(define (minidispatch-obj? obj) (minitype-predicate obj <minidispatch-obj>)) | |
(define (minidispatch-class? obj) (minitype-predicate obj <minidispatch>)) | |
(define-syntax | |
define-minidispatch-class | |
(syntax-rules | |
() | |
((_ nam fun) | |
(define nam | |
(let ((obj ((make-minitype-obj <minidispatch>)))) | |
(baseset! obj 'name 'nam) | |
(baseset! obj 'func fun) | |
obj))))) | |
(define (make-minidispatch-obj class param) | |
(unless (minidispatch-class? class) | |
(error "minidispatch class required" class)) | |
(let ((obj ((make-minitype-obj <minidispatch-obj>)))) | |
(baseset! obj 'minitype class) | |
(baseset! obj 'obj param) | |
obj)) | |
(define (do-ref obj slot) | |
(let* ((typ (baseref obj 'minitype)) | |
(func (baseref typ 'func)) | |
(o (baseref obj 'obj))) | |
(func 'ref slot o))) | |
(define (do-set! obj slot value) | |
(let* ((typ (baseref obj 'minitype)) | |
(func (baseref typ 'func)) | |
(o (baseref obj 'obj))) | |
(func 'set! slot o value))) | |
(define (do-typeof obj) (define typ (baseref obj 'minitype)) typ) | |
(define (miniobj-minidispatch-aux obj) | |
(let* ((typ (baseref obj 'minitype)) (func (baseref typ 'func))) func)) | |
(define (miniobj-minidispatch-ref obj slot k) | |
(if (minidispatch-obj? obj) (do-ref obj slot) (k obj slot))) | |
(define (miniobj-minidispatch-set! obj slot value k) | |
(if (minidispatch-obj? obj) (do-set! obj slot value) (k obj slot value))) | |
(define (miniobj-minidispatch-typeof obj k) | |
(if (minidispatch-obj? obj) (do-typeof obj) (k obj)))) | |
(begin | |
(define-syntax | |
define-miniobj-typeof | |
(syntax-rules | |
() | |
((_ name ref0 ref1 ... refnext term) | |
(define-miniobj-typeof | |
name | |
ref0 | |
ref1 | |
... | |
(lambda (obj) (refnext obj term)))) | |
((_ name ref0 term) (define (name obj) (ref0 obj term))))) | |
(define-syntax | |
define-miniobj-ref | |
(syntax-rules | |
() | |
((_ name ref0 ref1 ... refnext term) | |
(define-miniobj-ref | |
name | |
ref0 | |
ref1 | |
... | |
(lambda (obj slot) (refnext obj slot term)))) | |
((_ name ref0 term) (define (name obj slot) (ref0 obj slot term))))) | |
(define-syntax | |
define-miniobj-set! | |
(syntax-rules | |
() | |
((_ name set0 set1 ... setnext term) | |
(define-miniobj-set! | |
name | |
set0 | |
set1 | |
... | |
(lambda (obj slot value) (setnext obj slot value term)))) | |
((_ name set0 term) | |
(define (name obj slot value) (set0 obj slot value term)))))) | |
(begin | |
(define %%%export-miniobj-ref~48 #f) | |
(define %%%export-miniobj-set!~49 #f) | |
(define %%%export-miniobj-typeof~50 #f) | |
(let ((miniobj-rnrs-set!-error %%%export-miniobj-rnrs-set!-error~29) | |
(miniobj-rnrs-ref-error %%%export-miniobj-rnrs-ref-error~28)) | |
(define-miniobj-typeof | |
miniobj-typeof | |
miniobj-minidispatch-typeof | |
miniobj-minitype-typeof | |
(lambda (_) #f)) | |
(define-miniobj-ref | |
miniobj-ref | |
miniobj-minidispatch-ref | |
miniobj-minitype-ref | |
miniobj-rnrs-ref-error) | |
(define-miniobj-set! | |
miniobj-set! | |
miniobj-minidispatch-set! | |
miniobj-minitype-set! | |
miniobj-rnrs-set!-error) | |
(set! %%%export-miniobj-ref~48 miniobj-ref) | |
(set! %%%export-miniobj-set!~49 miniobj-set!) | |
(set! %%%export-miniobj-typeof~50 miniobj-typeof))) | |
(begin | |
(define-syntax | |
define-invalid-form | |
(syntax-rules | |
() | |
((_ sym) | |
(define-syntax | |
sym | |
(syntax-rules | |
() | |
((_) (syntax-error "Invalid form (for aux keyword)"))))))) | |
(define-syntax | |
define-invalid-forms | |
(syntax-rules | |
() | |
((_ sym) (define-invalid-form sym)) | |
((_ sym0 sym1 ...) | |
(begin (define-invalid-form sym0) (define-invalid-forms sym1 ...)))))) | |
(begin | |
(define-syntax | |
define-syntax-rules/keywords | |
(syntax-rules | |
() | |
((_ nam (symlit ...) (keylit ...) clauses ...) | |
(define-syntax nam (syntax-rules (symlit ... keylit ...) clauses ...))))) | |
(define-syntax | |
define-keywords | |
(syntax-rules () ((_ key ...) (define-invalid-forms key ...))))) | |
(begin | |
(define miniobj-typeof %%%export-miniobj-typeof~50) | |
(define miniobj-set! %%%export-miniobj-set!~49) | |
(define miniobj-ref %%%export-miniobj-ref~48) | |
(define-syntax | |
ref | |
(syntax-rules () ((_ target slot) (miniobj-ref target slot)))) | |
(define-syntax | |
refset! | |
(syntax-rules () ((_ target slot value) (miniobj-set! target slot value)))) | |
(define-syntax-rules/keywords | |
~ | |
() | |
(:=) | |
((_ target slot := obj) (refset! target slot obj)) | |
((_ target slot) (ref target slot)) | |
((_ target slot next-slot ...) (~ (ref target slot) next-slot ...))) | |
(define-syntax | |
define-composite | |
(syntax-rules () ((_ typename slots) (define-minitype typename slots)))) | |
(define-syntax | |
~new | |
(syntax-rules () ((_ typename) (make-minitype-obj typename)))) | |
(define-syntax | |
let-with | |
(syntax-rules | |
() | |
((_ OBJ (specs0) body ...) (let-with-binder OBJ specs0 body ...)) | |
((_ OBJ (specs0 specs1 ...) body ...) | |
(let ((myobj OBJ)) | |
(let-with-binder | |
myobj | |
specs0 | |
(let-with myobj (specs1 ...) body ...)))))) | |
(define-syntax | |
let-with* | |
(syntax-rules | |
() | |
((_ (specs0 specs1 ...) body ...) | |
(let-with specs0 (let-with* (specs1 ...) body ...))) | |
((_ (specs0) body ...) (let-with specs0 body ...)))) | |
(define-syntax | |
let-with-binder | |
(syntax-rules | |
() | |
((_ OBJ (bindname name) body ...) | |
(let ((bindname (~ OBJ 'name))) body ...)) | |
((_ OBJ name body ...) (let ((name (~ OBJ 'name))) body ...)))) | |
(define-syntax typeof (syntax-rules () ((_ obj) (miniobj-typeof obj)))) | |
(define-syntax | |
is-a? | |
(syntax-rules | |
() | |
((_ obj type) (and type (eq? type (miniobj-typeof obj)))))) | |
(define-syntax | |
make-apply-rule1! | |
(syntax-rules | |
() | |
((_ NAME (slot body)) (let ((result body)) (~ NAME 'slot := result))))) | |
(define-syntax | |
make | |
(syntax-rules | |
() | |
((_ TYPE rule0 ...) | |
(let ((new-object ((~new TYPE)))) | |
(make-apply-rule1! new-object rule0) | |
... | |
new-object)))) | |
(define-syntax | |
touch!-bind-spec1 | |
(syntax-rules | |
() | |
((_ OBJ (slot) body ...) (begin body ...)) | |
((_ OBJ (#f slot) body ...) (begin body ...)) | |
((_ OBJ (bind slot) body ...) (let-with OBJ ((bind slot)) body ...)) | |
((_ OBJ slot body ...) (touch!-bind-spec1 OBJ (slot slot) body ...)))) | |
(define-syntax | |
touch!-bind-spec | |
(syntax-rules | |
() | |
((_ OBJ (spec0) body ...) (touch!-bind-spec1 OBJ spec0 body ...)) | |
((_ OBJ (spec0 spec1 ...) body ...) | |
(touch!-bind-spec1 | |
OBJ | |
spec0 | |
(touch!-bind-spec OBJ (spec1 ...) body ...))))) | |
(define-syntax | |
touch!-apply-spec1! | |
(syntax-rules | |
() | |
((_ OBJ (slot) body ...) (~ OBJ 'slot := body ...)) | |
((_ OBJ (#f slot) body ...) (~ OBJ 'slot := body ...)) | |
((_ OBJ (bind slot) body ...) (~ OBJ 'slot := body ...)) | |
((_ OBJ slot body ...) (~ OBJ 'slot := body ...)))) | |
(define-syntax | |
touch! | |
(syntax-rules | |
() | |
((_ OBJ (bind-spec0 body-spec0) ...) | |
(let ((myobj OBJ)) | |
(touch!-bind-spec | |
myobj | |
(bind-spec0 ...) | |
(touch!-apply-spec1! myobj bind-spec0 body-spec0) | |
... | |
myobj))))) | |
(define (type-check sym id-name type-name id type) | |
(if (is-a? id type) | |
'ok | |
(begin (error "yuni: type violation" id-name type-name)))) | |
(define-syntax | |
annotate-check | |
(syntax-rules | |
() | |
((_ sym (id type)) (type-check sym 'id 'type id type)) | |
((_ sym id) 'ok))) | |
(define-syntax raw-name (syntax-rules () ((_ id) id) ((_ (id type)) id))) | |
(define-syntax | |
lambda*0-itr | |
(syntax-rules | |
() | |
((_ sym (cur ...) (spec ...) ((id bogus) rest0 ...) last body ...) | |
(lambda*0-itr | |
sym | |
(cur ... id) | |
((id bogus) spec ...) | |
(rest0 ...) | |
last | |
body | |
...)) | |
((_ sym (cur ...) (spec ...) ((id) rest0 ...) last body ...) | |
(let ((lambda*0-proxy id)) | |
(lambda*0-itr | |
sym | |
(cur ...) | |
(spec ...) | |
((id lambda*0-proxy) rest0 ...) | |
last | |
body | |
...))) | |
((_ sym (cur ...) (spec ...) (id rest0 ...) last body ...) | |
(lambda*0-itr sym (cur ... id) (spec ...) (rest0 ...) last body ...)) | |
((_ sym (cur ...) (spec ...) () () body ...) | |
(lambda (cur ...) (annotate-check sym spec) ... (let () body ...))) | |
((_ sym (cur ...) (spec ...) () (last-id last-type) body ...) | |
(lambda (cur ... . last-id) | |
(for-each (lambda (e) (annotate-check e last-type)) last-id) | |
(annotate-check sym spec) | |
... | |
(let () body ...))) | |
((_ sym (cur ...) (spec ...) () last body ...) | |
(lambda (cur ... . last) | |
(annotate-check sym spec) | |
... | |
(let () body ...))))) | |
(define-syntax | |
lambda*0 | |
(syntax-rules | |
() | |
((_ sym (spec0 ...) last body ...) | |
(lambda*0-itr sym () () (spec0 ...) last body ...)))) | |
(define (lookup-property form sym def) | |
(define (fail) (values def form)) | |
(define (itr ret top next rest) | |
(if (eq? sym top) | |
(values next (append (reverse ret) rest)) | |
(if (pair? rest) | |
(itr (cons top ret) next (car rest) (cdr rest)) | |
(fail)))) | |
(if (and (pair? form) (pair? (cdr form))) | |
(itr '() (car form) (cadr form) (cddr form)) | |
(fail))) | |
(define-syntax | |
let-property | |
(syntax-rules | |
() | |
((_ form out #() proc) (let ((out form)) proc)) | |
((_ form out #(sym) proc) (let-property form out #(sym #f) proc)) | |
((_ form out #(sym def) proc) | |
(let-values (((sym out) (lookup-property form 'sym def))) proc)))) | |
(define-syntax | |
let-properties | |
(syntax-rules | |
() | |
((_ form () proc) (apply proc form)) | |
((_ form (props0 props1 ...) proc) | |
(let-property form out props0 (let-properties out (props1 ...) proc))))) | |
(define-syntax | |
flatten-properties-itr | |
(syntax-rules | |
() | |
((_ form (out ...) (#((obj ...) rest ...) next ...) proc) | |
(flatten-properties-itr | |
form | |
(out ... #(obj ...)) | |
(#(rest ...) next ...) | |
proc)) | |
((_ form (out ...) (next0 next1 ...) proc) | |
(flatten-properties-itr form (out ... next0) (next1 ...) proc)) | |
((_ form (out ...) () proc) (let-properties form (out ...) proc)))) | |
(define-syntax | |
flatten-properties | |
(syntax-rules | |
() | |
((_ form (obj ...) proc) | |
(flatten-properties-itr form () (obj ...) proc)))) | |
(define-syntax | |
lambda*1-itr | |
(syntax-rules | |
() | |
((_ sym (prop ...) (out ...) (#(propx ...) spec0 ...) last body ...) | |
(lambda*1-itr | |
sym | |
(#(propx ...) prop ...) | |
(out ...) | |
(spec0 ...) | |
last | |
body | |
...)) | |
((_ sym (prop ...) (out ...) (spec0 spec1 ...) last body ...) | |
(lambda*1-itr sym (prop ...) (out ... spec0) (spec1 ...) last body ...)) | |
((_ sym () (out ...) () last body ...) | |
(lambda*0 sym (out ...) last body ...)) | |
((_ sym (prop0 ...) (out ...) () last body ...) | |
(lambda property-input | |
(flatten-properties | |
property-input | |
(prop0 ...) | |
(lambda*0 sym (out ...) last body ...)))))) | |
(define-syntax | |
lambda*1 | |
(syntax-rules | |
() | |
((_ sym (spec0 ...) body ...) | |
(lambda*1-itr sym () () (spec0 ...) () body ...)))) | |
(define-syntax | |
lambda* | |
(syntax-rules () ((_ spec body ...) (lambda*1 'lambda spec body ...)))) | |
(define-syntax | |
define* | |
(syntax-rules | |
() | |
((_ (name . spec) body ...) (define name (lambda*1 'name spec body ...))) | |
((_ name spec) (define-composite name spec)))) | |
(define-keywords :=)) | |
(begin | |
(define-syntax | |
match-syntax-error | |
(syntax-rules | |
() | |
((_) (match-syntax-error "invalid match-syntax-error usage")))) | |
(define-syntax | |
match | |
(syntax-rules | |
() | |
((match) (match-syntax-error "missing match expression")) | |
((match atom) (match-syntax-error "missing match clause")) | |
((match (app ...) (pat . body) ...) | |
(let ((v (app ...))) | |
(match-next v (app ...) (set! (app ...)) (pat . body) ...))) | |
((match #(vec ...) (pat . body) ...) | |
(let ((v #(vec ...))) (match-next v v (set! v) (pat . body) ...))) | |
((match atom (pat . body) ...) | |
(match-next atom atom (set! atom) (pat . body) ...)))) | |
(define-syntax | |
match-next | |
(syntax-rules | |
(=>) | |
((match-next v g s) (error "no matching pattern")) | |
((match-next v g s (pat (=> failure) . body) . rest) | |
(let ((failure (lambda () (match-next v g s . rest)))) | |
(match-one v pat g s (match-drop-ids (begin . body)) (failure) ()))) | |
((match-next v g s (pat . body) . rest) | |
(match-next v g s (pat (=> failure) . body) . rest)))) | |
(define-syntax | |
match-one | |
(syntax-rules | |
() | |
((match-one v (p q . r) g s sk fk i) | |
(match-check-ellipse | |
q | |
(match-extract-vars p (match-gen-ellipses v p r g s sk fk i) i ()) | |
(match-two v (p q . r) g s sk fk i))) | |
((match-one . x) (match-two . x)))) | |
(define-syntax | |
match-two | |
(syntax-rules | |
(___ quote quasiquote ? $ = and or not set! get!) | |
((match-two v () g s (sk ...) fk i) (if (null? v) (sk ... i) fk)) | |
((match-two v 'p g s (sk ...) fk i) (if (equal? v 'p) (sk ... i) fk)) | |
((match-two v `p g s sk fk i) (match-quasiquote v p g s sk fk i)) | |
((match-two v (and) g s (sk ...) fk i) (sk ... i)) | |
((match-two v (and p q ...) g s sk fk i) | |
(match-one v p g s (match-one v (and q ...) g s sk fk) fk i)) | |
((match-two v (or) g s sk fk i) fk) | |
((match-two v (or p) g s sk fk i) (match-one v p g s sk fk i)) | |
((match-two v (or p ...) g s sk fk i) | |
(match-extract-vars | |
(or p ...) | |
(match-gen-or v (p ...) g s sk fk i) | |
i | |
())) | |
((match-two v (not p) g s (sk ...) fk i) | |
(match-one v p g s (match-drop-ids fk) (sk ... i) i)) | |
((match-two v (get! getter) g s (sk ...) fk i) | |
(let ((getter (lambda () g))) (sk ... i))) | |
((match-two v (set! setter) g (s ...) (sk ...) fk i) | |
(let ((setter (lambda (x) (s ... x)))) (sk ... i))) | |
((match-two v (? pred p ...) g s sk fk i) | |
(if (pred v) (match-one v (and p ...) g s sk fk i) fk)) | |
((match-two v (= proc p) g s sk fk i) | |
(let ((w (proc v))) (match-one w p g s sk fk i))) | |
((match-two v (p ___ . r) g s sk fk i) | |
(match-extract-vars p (match-gen-ellipses v p r g s sk fk i) i ())) | |
((match-two v (p) g s sk fk i) | |
(if (and (pair? v) (null? (cdr v))) | |
(let ((w (car v))) (match-one w p (car v) (set-car! v) sk fk i)) | |
fk)) | |
((match-two v (p . q) g s sk fk i) | |
(if (pair? v) | |
(let ((w (car v)) (x (cdr v))) | |
(match-one | |
w | |
p | |
(car v) | |
(set-car! v) | |
(match-one x q (cdr v) (set-cdr! v) sk fk) | |
fk | |
i)) | |
fk)) | |
((match-two v #(p ...) g s sk fk i) (match-vector v 0 () (p ...) sk fk i)) | |
((match-two v x g s (sk ...) fk (id ...)) | |
(let-syntax | |
((new-sym? | |
(syntax-rules | |
(id ...) | |
((new-sym? x sk2 fk2) sk2) | |
((new-sym? y sk2 fk2) fk2)))) | |
(new-sym? | |
random-sym-to-match | |
(let ((x v)) (sk ... (id ... x))) | |
(if (equal? v x) (sk ... (id ...)) fk)))))) | |
(define-syntax | |
match-quasiquote | |
(syntax-rules | |
(unquote unquote-splicing quasiquote) | |
((_ v ,p g s sk fk i) (match-one v p g s sk fk i)) | |
((_ v (,@p . rest) g s sk fk i) | |
(if (pair? v) | |
(match-one v (p . tmp) (match-quasiquote tmp rest g s sk fk) fk i) | |
fk)) | |
((_ v `p g s sk fk i . depth) | |
(match-quasiquote v p g s sk fk i #f . depth)) | |
((_ v ,p g s sk fk i x . depth) | |
(match-quasiquote v p g s sk fk i . depth)) | |
((_ v ,@p g s sk fk i x . depth) | |
(match-quasiquote v p g s sk fk i . depth)) | |
((_ v (p . q) g s sk fk i . depth) | |
(if (pair? v) | |
(let ((w (car v)) (x (cdr v))) | |
(match-quasiquote | |
w | |
p | |
g | |
s | |
(match-quasiquote-step x q g s sk fk depth) | |
fk | |
i | |
. | |
depth)) | |
fk)) | |
((_ v #(elt ...) g s sk fk i . depth) | |
(if (vector? v) | |
(let ((ls (vector->list v))) | |
(match-quasiquote ls (elt ...) g s sk fk i . depth)) | |
fk)) | |
((_ v x g s sk fk i . depth) (match-one v 'x g s sk fk i)))) | |
(define-syntax | |
match-quasiquote-step | |
(syntax-rules | |
() | |
((match-quasiquote-step x q g s sk fk depth i) | |
(match-quasiquote x q g s sk fk i . depth)))) | |
(define-syntax match-drop-ids (syntax-rules () ((_ expr ids ...) expr))) | |
(define-syntax | |
match-gen-or | |
(syntax-rules | |
() | |
((_ v p g s (sk ...) fk (i ...) ((id id-ls) ...)) | |
(let ((sk2 (lambda (id ...) (sk ... (i ... id ...))))) | |
(match-gen-or-step | |
v | |
p | |
g | |
s | |
(match-drop-ids (sk2 id ...)) | |
fk | |
(i ...)))))) | |
(define-syntax | |
match-gen-or-step | |
(syntax-rules | |
() | |
((_ v () g s sk fk i) fk) | |
((_ v (p) g s sk fk i) (match-one v p g s sk fk i)) | |
((_ v (p . q) g s sk fk i) | |
(match-one v p g s sk (match-gen-or-step v q g s sk fk i) i)))) | |
(define-syntax | |
match-gen-ellipses | |
(syntax-rules | |
() | |
((_ v p () g s (sk ...) fk i ((id id-ls) ...)) | |
(match-check-identifier | |
p | |
(let ((p v)) (if (list? p) (sk ... i) fk)) | |
(let loop ((ls v) (id-ls '()) ...) | |
(cond ((null? ls) (let ((id (reverse id-ls)) ...) (sk ... i))) | |
((pair? ls) | |
(let ((w (car ls))) | |
(match-one | |
w | |
p | |
(car ls) | |
(set-car! ls) | |
(match-drop-ids (loop (cdr ls) (cons id id-ls) ...)) | |
fk | |
i))) | |
(else fk))))) | |
((_ v p (r ...) g s (sk ...) fk i ((id id-ls) ...)) | |
(match-verify-no-ellipses | |
(r ...) | |
(let* ((tail-len (length '(r ...))) (ls v) (len (length ls))) | |
(if (< len tail-len) | |
fk | |
(let loop ((ls ls) (n len) (id-ls '()) ...) | |
(cond ((= n tail-len) | |
(let ((id (reverse id-ls)) ...) | |
(match-one ls (r ...) #f #f (sk ... i) fk i))) | |
((pair? ls) | |
(let ((w (car ls))) | |
(match-one | |
w | |
p | |
(car ls) | |
(set-car! ls) | |
(match-drop-ids | |
(loop (cdr ls) (- n 1) (cons id id-ls) ...)) | |
fk | |
i))) | |
(else fk))))))))) | |
(define-syntax | |
match-verify-no-ellipses | |
(syntax-rules | |
() | |
((_ (x . y) sk) | |
(match-check-ellipse | |
x | |
(match-syntax-error | |
"multiple ellipse patterns not allowed at same level") | |
(match-verify-no-ellipses y sk))) | |
((_ x sk) sk))) | |
(define-syntax | |
match-vector | |
(syntax-rules | |
(___) | |
((_ v n pats (p q) sk fk i) | |
(match-check-ellipse | |
q | |
(match-vector-ellipses v n pats p sk fk i) | |
(match-vector-two v n pats (p q) sk fk i))) | |
((_ v n pats (p ___) sk fk i) (match-vector-ellipses v n pats p sk fk i)) | |
((_ . x) (match-vector-two . x)))) | |
(define-syntax | |
match-vector-two | |
(syntax-rules | |
() | |
((_ v n ((pat index) ...) () sk fk i) | |
(if (vector? v) | |
(let ((len (vector-length v))) | |
(if (= len n) (match-vector-step v ((pat index) ...) sk fk i) fk)) | |
fk)) | |
((_ v n (pats ...) (p . q) sk fk i) | |
(match-vector v (+ n 1) (pats ... (p n)) q sk fk i)))) | |
(define-syntax | |
match-vector-step | |
(syntax-rules | |
() | |
((_ v () (sk ...) fk i) (sk ... i)) | |
((_ v ((pat index) . rest) sk fk i) | |
(let ((w (vector-ref v index))) | |
(match-one | |
w | |
pat | |
(vector-ref v index) | |
(vector-set! v index) | |
(match-vector-step v rest sk fk) | |
fk | |
i))))) | |
(define-syntax | |
match-vector-ellipses | |
(syntax-rules | |
() | |
((_ v n ((pat index) ...) p sk fk i) | |
(if (vector? v) | |
(let ((len (vector-length v))) | |
(if (>= len n) | |
(match-vector-step | |
v | |
((pat index) ...) | |
(match-vector-tail v p n len sk fk) | |
fk | |
i) | |
fk)) | |
fk)))) | |
(define-syntax | |
match-vector-tail | |
(syntax-rules | |
() | |
((_ v p n len sk fk i) | |
(match-extract-vars p (match-vector-tail-two v p n len sk fk i) i ())))) | |
(define-syntax | |
match-vector-tail-two | |
(syntax-rules | |
() | |
((_ v p n len (sk ...) fk i ((id id-ls) ...)) | |
(let loop ((j n) (id-ls '()) ...) | |
(if (>= j len) | |
(let ((id (reverse id-ls)) ...) (sk ... i)) | |
(let ((w (vector-ref v j))) | |
(match-one | |
w | |
p | |
(vector-ref v j) | |
(vetor-set! v j) | |
(match-drop-ids (loop (+ j 1) (cons id id-ls) ...)) | |
fk | |
i))))))) | |
(define-syntax | |
match-extract-vars | |
(syntax-rules | |
(___ ? $ = quote quasiquote and or not get! set!) | |
((match-extract-vars (? pred . p) k i v) (match-extract-vars p k i v)) | |
((match-extract-vars ($ rec . p) k i v) (match-extract-vars p k i v)) | |
((match-extract-vars (= proc p) k i v) (match-extract-vars p k i v)) | |
((match-extract-vars 'x (k ...) i v) (k ... v)) | |
((match-extract-vars `x k i v) | |
(match-extract-quasiquote-vars x k i v (#t))) | |
((match-extract-vars (and . p) k i v) (match-extract-vars p k i v)) | |
((match-extract-vars (or . p) k i v) (match-extract-vars p k i v)) | |
((match-extract-vars (not . p) k i v) (match-extract-vars p k i v)) | |
((match-extract-vars (p q . r) k i v) | |
(match-check-ellipse | |
q | |
(match-extract-vars (p . r) k i v) | |
(match-extract-vars p (match-extract-vars-step (q . r) k i v) i ()))) | |
((match-extract-vars (p . q) k i v) | |
(match-extract-vars p (match-extract-vars-step q k i v) i ())) | |
((match-extract-vars #(p ...) k i v) (match-extract-vars (p ...) k i v)) | |
((match-extract-vars ___ (k ...) i v) (k ... v)) | |
((match-extract-vars p (k ...) (i ...) v) | |
(let-syntax | |
((new-sym? | |
(syntax-rules | |
(i ...) | |
((new-sym? p sk fk) sk) | |
((new-sym? x sk fk) fk)))) | |
(new-sym? random-sym-to-match (k ... ((p p-ls) . v)) (k ... v)))))) | |
(define-syntax | |
match-extract-vars-step | |
(syntax-rules | |
() | |
((_ p k i v ((v2 v2-ls) ...)) | |
(match-extract-vars p k (v2 ... . i) ((v2 v2-ls) ... . v))))) | |
(define-syntax | |
match-extract-quasiquote-vars | |
(syntax-rules | |
(quasiquote unquote unquote-splicing) | |
((match-extract-quasiquote-vars `x k i v d) | |
(match-extract-quasiquote-vars x k i v (#t . d))) | |
((match-extract-quasiquote-vars ,@x k i v d) | |
(match-extract-quasiquote-vars ,x k i v d)) | |
((match-extract-quasiquote-vars ,x k i v (#t)) | |
(match-extract-vars x k i v)) | |
((match-extract-quasiquote-vars ,x k i v (#t . d)) | |
(match-extract-quasiquote-vars x k i v d)) | |
((match-extract-quasiquote-vars (x . y) k i v (#t . d)) | |
(match-extract-quasiquote-vars | |
x | |
(match-extract-quasiquote-vars-step y k i v d) | |
i | |
())) | |
((match-extract-quasiquote-vars #(x ...) k i v (#t . d)) | |
(match-extract-quasiquote-vars (x ...) k i v d)) | |
((match-extract-quasiquote-vars x (k ...) i v (#t . d)) (k ... v)))) | |
(define-syntax | |
match-extract-quasiquote-vars-step | |
(syntax-rules | |
() | |
((_ x k i v d ((v2 v2-ls) ...)) | |
(match-extract-quasiquote-vars | |
x | |
k | |
(v2 ... . i) | |
((v2 v2-ls) ... . v) | |
d)))) | |
(define-syntax | |
match-lambda | |
(syntax-rules () ((_ clause ...) (lambda (expr) (match expr clause ...))))) | |
(define-syntax | |
match-lambda* | |
(syntax-rules () ((_ clause ...) (lambda expr (match expr clause ...))))) | |
(define-syntax | |
match-let | |
(syntax-rules | |
() | |
((_ (vars ...) . body) (match-let/helper let () () (vars ...) . body)) | |
((_ loop . rest) (match-named-let loop () . rest)))) | |
(define-syntax | |
match-letrec | |
(syntax-rules | |
() | |
((_ vars . body) (match-let/helper letrec () () vars . body)))) | |
(define-syntax | |
match-let/helper | |
(syntax-rules | |
() | |
((_ let ((var expr) ...) () () . body) (let ((var expr) ...) . body)) | |
((_ let ((var expr) ...) ((pat tmp) ...) () . body) | |
(let ((var expr) ...) (match-let* ((pat tmp) ...) . body))) | |
((_ let (v ...) (p ...) (((a . b) expr) . rest) . body) | |
(match-let/helper | |
let | |
(v ... (tmp expr)) | |
(p ... ((a . b) tmp)) | |
rest | |
. | |
body)) | |
((_ let (v ...) (p ...) ((#(a ...) expr) . rest) . body) | |
(match-let/helper | |
let | |
(v ... (tmp expr)) | |
(p ... (#(a ...) tmp)) | |
rest | |
. | |
body)) | |
((_ let (v ...) (p ...) ((a expr) . rest) . body) | |
(match-let/helper let (v ... (a expr)) (p ...) rest . body)))) | |
(define-syntax | |
match-named-let | |
(syntax-rules | |
() | |
((_ loop ((pat expr var) ...) () . body) | |
(let loop ((var expr) ...) (match-let ((pat var) ...) . body))) | |
((_ loop (v ...) ((pat expr) . rest) . body) | |
(match-named-let loop (v ... (pat expr tmp)) rest . body)))) | |
(define-syntax | |
match-let* | |
(syntax-rules | |
() | |
((_ () . body) (begin . body)) | |
((_ ((pat expr) . rest) . body) | |
(match expr (pat (match-let* rest . body)))))) | |
(define-syntax | |
match-check-ellipse | |
(syntax-rules | |
() | |
((match-check-ellipse (a . b) success-k failure-k) failure-k) | |
((match-check-ellipse #(a ...) success-k failure-k) failure-k) | |
((match-check-ellipse id success-k failure-k) | |
(let-syntax | |
((ellipse? | |
(syntax-rules | |
() | |
((ellipse? (foo id) sk fk) sk) | |
((ellipse? other sk fk) fk)))) | |
(ellipse? (a b c) success-k failure-k))))) | |
(define-syntax | |
match-check-identifier | |
(syntax-rules | |
() | |
((_ (x . y) success-k failure-k) failure-k) | |
((_ #(x ...) success-k failure-k) failure-k) | |
((_ x success-k failure-k) | |
(let-syntax | |
((sym? (syntax-rules () ((sym? x sk fk) sk) ((sym? y sk fk) fk)))) | |
(sym? abracadabra success-k failure-k)))))) | |
(begin | |
(define-syntax | |
%let-terms | |
(syntax-rules | |
() | |
((_ (var . varrest) (nam . namrest) body) | |
(let ((nam var)) (%let-terms varrest namrest body))) | |
((_ () () body) body) | |
((_ var nam body) (let ((nam var)) body)))) | |
(define-syntax | |
%gen-dispatch+case-lambda | |
(syntax-rules | |
() | |
((_ (first . rest) (((withsymtop . withsymrest) body) ...) ()) | |
(case first | |
((withsymtop) (%let-terms rest withsymrest body)) | |
... | |
(else (error "unknown command" first (list 'withsymtop ...))))) | |
((_ f () ((f2 body))) (%let-terms f f2 body)) | |
((_ (first . rest) (((withsymtop . withsymrest) body) ...) ((f elsebody))) | |
(case first | |
((withsymtop) (%let-terms rest withsymrest body)) | |
... | |
(else (%let-terms (first . rest) f elsebody)))))) | |
(define-syntax | |
%sort-dispatch-clauses | |
(syntax-rules | |
(quote) | |
((_ with without f ()) (%gen-dispatch+case-lambda f with without)) | |
((_ with without f ((('sym . rest) body) . next)) | |
(%sort-dispatch-clauses (((sym . rest) body) . with) without f next)) | |
((_ with without f (cur . next)) | |
(%sort-dispatch-clauses with (cur . without) f next)))) | |
(define-syntax | |
%output-case-lambda | |
(syntax-rules | |
() | |
((_ cur (f ()) next ...) (%output-case-lambda cur next ...)) | |
((_ cur valid-entry next ...) | |
(%output-case-lambda (valid-entry . cur) next ...)) | |
((_ ((f clauses) ...)) | |
(case-lambda (f (%sort-dispatch-clauses () () f clauses)) ...)))) | |
(define-syntax | |
%gen-case-lambda | |
(syntax-rules | |
() | |
((_ $0 $0+ $1 $1+ $2 $2+ $3 $3+ $4 $4+ $5 $5+ $6 $6+ $7 $7+ $8 $8+ $9 $9+) | |
(%output-case-lambda | |
() | |
(() $0) | |
((x1) $1) | |
((x1 x2) $2) | |
((x1 x2 x3) $3) | |
((x1 x2 x3 x4) $4) | |
((x1 x2 x3 x4 x5) $5) | |
((x1 x2 x3 x4 x5 x6) $6) | |
((x1 x2 x3 x4 x5 x6 x7) $7) | |
((x1 x2 x3 x4 x5 x6 x7 x8) $8) | |
((x1 x2 x3 x4 x5 x6 x7 x8 x9) $9) | |
((x1 x2 x3 x4 x5 x6 x7 x8 x9 . x) $9+) | |
((x1 x2 x3 x4 x5 x6 x7 x8 . x) $8+) | |
((x1 x2 x3 x4 x5 x6 x7 . x) $7+) | |
((x1 x2 x3 x4 x5 x6 . x) $6+) | |
((x1 x2 x3 x4 x5 . x) $5+) | |
((x1 x2 x3 x4 . x) $4+) | |
((x1 x2 x3 . x) $3+) | |
((x1 x2 . x) $2+) | |
((x1 . x) $1+) | |
(wam $0+))))) | |
(define-syntax | |
%sort-clauses | |
(syntax-rules | |
() | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 ...) body ...) . bogus)) | |
(syntax-error "Too many arguments")) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
()) | |
(%gen-case-lambda | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
((() body ...) . next)) | |
(%sort-clauses | |
((() (begin body ...)) . $0) | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
(((x1) (begin body ...)) . $1) | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
(((x1 x2) (begin body ...)) . $2) | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
(((x1 x2 x3) (begin body ...)) . $3) | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 x4) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
(((x1 x2 x3 x4) (begin body ...)) . $4) | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 x4 x5) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
(((x1 x2 x3 x4 x5) (begin body ...)) . $5) | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 x4 x5 x6) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
(((x1 x2 x3 x4 x5 x6) (begin body ...)) . $6) | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 x4 x5 x6 x7) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
(((x1 x2 x3 x4 x5 x6 x7) (begin body ...)) . $7) | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 x4 x5 x6 x7 x8) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
(((x1 x2 x3 x4 x5 x6 x7 x8) (begin body ...)) . $8) | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 x4 x5 x6 x7 x8 x9) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
(((x1 x2 x3 x4 x5 x6 x7 x8 x9) (begin body ...)) . $9) | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 x4 x5 x6 x7 x8 x9 . x) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
(((x1 x2 x3 x4 x5 x6 x7 x8 x9 . x) (begin body ...)) . $9+) | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 x4 x5 x6 x7 x8 . x) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
(((x1 x2 x3 x4 x5 x6 x7 x8 . x) (begin body ...)) . $8+) | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 x4 x5 x6 x7 . x) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
(((x1 x2 x3 x4 x5 x6 x7 . x) (begin body ...)) . $7+) | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 x4 x5 x6 . x) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
(((x1 x2 x3 x4 x5 x6 . x) (begin body ...)) . $6+) | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 x4 x5 . x) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
(((x1 x2 x3 x4 x5 . x) (begin body ...)) . $5+) | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 x4 . x) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
(((x1 x2 x3 x4 . x) (begin body ...)) . $4+) | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 x3 . x) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
(((x1 x2 x3 . x) (begin body ...)) . $3+) | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 x2 . x) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
(((x1 x2 . x) (begin body ...)) . $2+) | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
(((x1 . x) body ...) . next)) | |
(%sort-clauses | |
$0 | |
$0+ | |
$1 | |
(((x1 . x) (begin body ...)) . $1+) | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)) | |
((_ $0 | |
$0+ | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
((x body ...) . next)) | |
(%sort-clauses | |
$0 | |
((x (begin body ...)) . $0+) | |
$1 | |
$1+ | |
$2 | |
$2+ | |
$3 | |
$3+ | |
$4 | |
$4+ | |
$5 | |
$5+ | |
$6 | |
$6+ | |
$7 | |
$7+ | |
$8 | |
$8+ | |
$9 | |
$9+ | |
next)))) | |
(define-syntax | |
dispatch-lambda | |
(syntax-rules | |
() | |
((_ clauses ...) | |
(%sort-clauses | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
() | |
(clauses ...)))))) | |
(begin | |
(define %%%export-ssplit-byte-delimiter?~51 #f) | |
(define %%%export-ssplit-byte-whitespace?~52 #f) | |
(define %%%export-ssplit-byte-class~53 #f) | |
(let () | |
(define-syntax | |
%bcdef | |
(syntax-rules | |
() | |
((_ (char sym) ...) | |
(let ((sym char) ...) | |
(lambda (b) (cond ((= sym b) 'sym) ... (else #f))))))) | |
(define (ssplit-byte-whitespace? byte) | |
(case (ssplit-byte-class byte) ((SPACE TAB CR LF) #t) (else #f))) | |
(define (ssplit-byte-delimiter? byte) | |
(or (ssplit-byte-whitespace? byte) | |
(case (ssplit-byte-class byte) | |
((PAREN_L PAREN_R SQ_L SQ_R SEMICOLON SHARP DQUOTE) #t) | |
(else #f)))) | |
(define ssplit-byte-class | |
(%bcdef (32 SPACE) | |
(9 TAB) | |
(13 CR) | |
(10 LF) | |
(40 PAREN_L) | |
(41 PAREN_R) | |
(91 SQ_L) | |
(93 SQ_R) | |
(59 SEMICOLON) | |
(35 SHARP) | |
(34 DQUOTE) | |
(92 BACKSLASH) | |
(39 QUOTE) | |
(64 AT) | |
(44 COMMA) | |
(124 PIPE) | |
(96 BQUOTE) | |
(116 SMALL-T) | |
(102 SMALL-F) | |
(84 LARGE-T) | |
(70 LARGE-F))) | |
(set! %%%export-ssplit-byte-delimiter?~51 ssplit-byte-delimiter?) | |
(set! %%%export-ssplit-byte-whitespace?~52 ssplit-byte-whitespace?) | |
(set! %%%export-ssplit-byte-class~53 ssplit-byte-class))) | |
(begin | |
(define %%%export-ssplit-parse-byte0~54 #f) | |
(define %%%export-ssplit-parse-byte1~55 #f) | |
(define %%%export-ssplit-parse-byte2~56 #f) | |
(define %%%export-ssplit-instring-parse-byte0~57 #f) | |
(define %%%export-ssplit-instring-parse-byte1~58 #f) | |
(define %%%export-ssplit-incomment-parse-byte0~59 #f) | |
(define %%%export-ssplit-incomment-parse-byte1~60 #f) | |
(define %%%export-ssplit-inblockcomment-parse-byte0~61 #f) | |
(define %%%export-ssplit-inblockcomment-parse-byte1~62 #f) | |
(let ((ssplit-byte-class %%%export-ssplit-byte-class~53) | |
(ssplit-byte-whitespace? %%%export-ssplit-byte-whitespace?~52) | |
(ssplit-byte-delimiter? %%%export-ssplit-byte-delimiter?~51)) | |
(define-syntax | |
%expand-clause | |
(syntax-rules | |
() | |
((_ single) (values 'single #f)) | |
((_ has-next #t) (values 'has-next #t)))) | |
(define-syntax | |
%dispatch0 | |
(syntax-rules | |
(=>) | |
((_ byte (sym => clause ...) ...) | |
(let ((cls (ssplit-byte-class byte))) | |
(case cls | |
((sym) (%expand-clause clause ...)) | |
... | |
(else (values 'OTHERS #f))))))) | |
(define-syntax | |
%dispatch | |
(syntax-rules | |
(=>) | |
((_ prev-sym byte (from to => clause ...) ...) | |
(let ((cls (ssplit-byte-class byte))) | |
(cond ((and (eq? prev-sym 'from) (eq? cls 'to)) | |
(%expand-clause clause ...)) | |
... | |
(else (values 'OTHERS #f))))))) | |
(define (ssplit-parse-byte0 byte) | |
(%dispatch0 | |
byte | |
(PAREN_L => LIST_BEGIN_PAREN) | |
(PAREN_R => LIST_END_PAREN) | |
(SQ_L => LIST_BEGIN_SQ) | |
(SQ_R => LIST_END_SQ) | |
(QUOTE => NEXT_QUOTE) | |
(BQUOTE => NEXT_QUASIQUOTE) | |
(COMMA => NEXT_UNQUOTE #t) | |
(SPACE => SPACE) | |
(CR => CR #t) | |
(LF => LF) | |
(SHARP => SHARP #t) | |
(SEMICOLON => SEMICOLON) | |
(DQUOTE => DQUOTE))) | |
(define (ssplit-parse-byte1 byte prev-sym) | |
(%dispatch | |
prev-sym | |
byte | |
(SHARP QUOTE => NEXT_SYNTAX_QUOTE) | |
(SHARP BQUOTE => NEXT_SYNTAX_QUASIQUOTE) | |
(SHARP COMMA => NEXT_SYNTAX_UNQUOTE #t) | |
(NEXT_UNQUOTE AT => NEXT_UNQUOTE_SPLICING) | |
(SHARP BACKSLASH => NEXT_CHAR_LITERAL) | |
(SHARP PIPE => BLOCK_COMMENT_BEGIN) | |
(SHARP SEMICOLON => NEXT_DATUM_COMMENT) | |
(CR LF => CRLF) | |
(SHARP SMALL-T => TRUE) | |
(SHARP SMALL-F => FALSE) | |
(SHARP LARGE-T => TRUE) | |
(SHARP LARGE-F => FALSE))) | |
(define (ssplit-parse-byte2 byte prev-sym) | |
(%dispatch | |
prev-sym | |
byte | |
(NEXT_SYNTAX_UNQUOTE AT => NEXT_SYNTAX_UNQUOTE_SPLICING))) | |
(define (ssplit-instring-parse-byte0 byte) | |
(%dispatch0 | |
byte | |
(BACKSLASH => BACKSLASH #t) | |
(DQUOTE => DQUOTE) | |
(CR => CR #t) | |
(LF => LF))) | |
(define (ssplit-instring-parse-byte1 byte prev-sym) | |
(%dispatch | |
prev-sym | |
byte | |
(CR LF => CRLF) | |
(BACKSLASH DQUOTE => ESCAPE_DQUOTE))) | |
(define (ssplit-incomment-parse-byte0 byte) | |
(%dispatch0 byte (CR => CR #t) (LF => LF) (SEMICOLON => SEMICOLON))) | |
(define (ssplit-incomment-parse-byte1 byte prev-sym) | |
(%dispatch prev-sym byte (CR LF => CRLF))) | |
(define (ssplit-inblockcomment-parse-byte0 byte) | |
(%dispatch0 | |
byte | |
(PIPE => PIPE #t) | |
(SHARP => SHARP #t) | |
(CR => CR #t) | |
(LF => LF))) | |
(define (ssplit-inblockcomment-parse-byte1 byte prev-sym) | |
(%dispatch | |
prev-sym | |
byte | |
(PIPE SHARP => BLOCK_COMMENT_END) | |
(SHARP PIPE => BLOCK_COMMENT_BEGIN) | |
(CR LF => CRLF))) | |
(set! %%%export-ssplit-parse-byte0~54 ssplit-parse-byte0) | |
(set! %%%export-ssplit-parse-byte1~55 ssplit-parse-byte1) | |
(set! %%%export-ssplit-parse-byte2~56 ssplit-parse-byte2) | |
(set! %%%export-ssplit-instring-parse-byte0~57 | |
ssplit-instring-parse-byte0) | |
(set! %%%export-ssplit-instring-parse-byte1~58 | |
ssplit-instring-parse-byte1) | |
(set! %%%export-ssplit-incomment-parse-byte0~59 | |
ssplit-incomment-parse-byte0) | |
(set! %%%export-ssplit-incomment-parse-byte1~60 | |
ssplit-incomment-parse-byte1) | |
(set! %%%export-ssplit-inblockcomment-parse-byte0~61 | |
ssplit-inblockcomment-parse-byte0) | |
(set! %%%export-ssplit-inblockcomment-parse-byte1~62 | |
ssplit-inblockcomment-parse-byte1))) | |
(begin | |
(define %%%export-make-miniread~63 #f) | |
(define %%%export-make-tkn~64 #f) | |
(define %%%export-tkn-start-stream~65 #f) | |
(define %%%export-tkn-start-index~66 #f) | |
(define %%%export-tkn-start-lineno~67 #f) | |
(define %%%export-tkn-start-column~68 #f) | |
(define %%%export-tkn-end-stream~69 #f) | |
(define %%%export-tkn-end-index~70 #f) | |
(define %%%export-tkn-end-lineno~71 #f) | |
(define %%%export-tkn-end-column~72 #f) | |
(define %%%export-tkn-type~73 #f) | |
(define %%%export-miniread-main~74 #f) | |
(let ((ssplit-inblockcomment-parse-byte1 | |
%%%export-ssplit-inblockcomment-parse-byte1~62) | |
(ssplit-inblockcomment-parse-byte0 | |
%%%export-ssplit-inblockcomment-parse-byte0~61) | |
(ssplit-incomment-parse-byte1 | |
%%%export-ssplit-incomment-parse-byte1~60) | |
(ssplit-incomment-parse-byte0 | |
%%%export-ssplit-incomment-parse-byte0~59) | |
(ssplit-instring-parse-byte1 %%%export-ssplit-instring-parse-byte1~58) | |
(ssplit-instring-parse-byte0 %%%export-ssplit-instring-parse-byte0~57) | |
(ssplit-parse-byte2 %%%export-ssplit-parse-byte2~56) | |
(ssplit-parse-byte1 %%%export-ssplit-parse-byte1~55) | |
(ssplit-parse-byte0 %%%export-ssplit-parse-byte0~54) | |
(ssplit-byte-class %%%export-ssplit-byte-class~53) | |
(ssplit-byte-whitespace? %%%export-ssplit-byte-whitespace?~52) | |
(ssplit-byte-delimiter? %%%export-ssplit-byte-delimiter?~51)) | |
(define* miniread | |
(state reg | |
hold | |
hold-stream | |
hold-index | |
lineno | |
column | |
blockcomment-depth | |
start-stream | |
start-index | |
start-lineno | |
start-column | |
prev-type | |
prev-stream | |
prev-index | |
prev-lineno | |
prev-column)) | |
(define* tokenvec-entry | |
(start-stream | |
start-index | |
start-lineno | |
start-column | |
end-stream | |
end-index | |
end-lineno | |
end-column | |
type)) | |
(define (make-tkn num) | |
(list->vector | |
(map (lambda (e) (make tokenvec-entry)) | |
(vector->list (make-vector num))))) | |
(define (%tref vec idx sym) (~ (vector-ref vec idx) sym)) | |
(define (tkn-start-stream vec idx) (%tref vec idx 'start-stream)) | |
(define (tkn-start-index vec idx) (%tref vec idx 'start-index)) | |
(define (tkn-start-lineno vec idx) (%tref vec idx 'start-lineno)) | |
(define (tkn-start-column vec idx) (%tref vec idx 'start-column)) | |
(define (tkn-end-stream vec idx) (%tref vec idx 'end-stream)) | |
(define (tkn-end-index vec idx) (%tref vec idx 'end-index)) | |
(define (tkn-end-lineno vec idx) (%tref vec idx 'end-lineno)) | |
(define (tkn-end-column vec idx) (%tref vec idx 'end-column)) | |
(define (tkn-type vec idx) (%tref vec idx 'type)) | |
(define (make-miniread) | |
(make miniread (blockcomment-depth 0) (hold #f) (state #f))) | |
(define (miniread-main mr vec vecidx vecend cb) | |
(define terminate? #f) | |
(define curidx vecidx) | |
(define retidx #f) | |
(define (state) (~ mr 'state)) | |
(define (set-state! st) (~ mr 'state := st)) | |
(define (blockcomment-depth-zero?) (zero? (~ mr 'blockcomment-depth))) | |
(define (%blockcomment-depth-add! x) | |
(let ((d (~ mr 'blockcomment-depth))) | |
(~ mr 'blockcomment-depth := (+ x d)))) | |
(define (blockcomment-depth++) (%blockcomment-depth-add! 1)) | |
(define (blockcomment-depth--) (%blockcomment-depth-add! -1)) | |
(define (callstep next b stream index) | |
(define (step type has-next?) | |
(define prev-type (~ mr 'reg)) | |
(~ mr 'reg := type) | |
(next b (state) prev-type type has-next? stream index)) | |
(define (dostep0 p) (call-with-values (lambda () (p b)) step)) | |
(define (dostep p) | |
(call-with-values (lambda () (p b (~ mr 'reg))) step)) | |
(case (state) | |
((CHARLIT) (next b 'CHARLIT #f 'CHARLIT #f stream index)) | |
((#f OBJ0 OBJ0/SHARP) (dostep0 ssplit-parse-byte0)) | |
((OBJ1 OBJ1/SHARP) (dostep ssplit-parse-byte1)) | |
((OBJ2) (dostep ssplit-parse-byte2)) | |
((STRING0) (dostep0 ssplit-instring-parse-byte0)) | |
((STRING1) (dostep ssplit-instring-parse-byte1)) | |
((LINECOMMENT0) (dostep0 ssplit-incomment-parse-byte0)) | |
((LINECOMMENT1) (dostep ssplit-incomment-parse-byte1)) | |
((BLOCKCOMMENT0) (dostep0 ssplit-inblockcomment-parse-byte0)) | |
((BLOCKCOMMENT1) (dostep ssplit-inblockcomment-parse-byte1)) | |
(else (error "unexpected state" (state))))) | |
(define (char b st prev-type type has-next? stream index) | |
(define (whitespace?) (ssplit-byte-whitespace? b)) | |
(define (delimiter?) (ssplit-byte-delimiter? b)) | |
(define (paren-l?) (eq? 'PAREN_L (ssplit-byte-class b))) | |
(define (hold) | |
(~ mr 'hold := b) | |
(~ mr 'hold-index := index) | |
(~ mr 'hold-stream := stream)) | |
(define (set-prev-here type) | |
(~ mr 'prev-type := type) | |
(~ mr 'prev-stream := stream) | |
(~ mr 'prev-index := index) | |
(~ mr 'prev-lineno := (~ mr 'lineno)) | |
(~ mr 'prev-column := (~ mr 'column))) | |
(define (begin-here next-state) | |
(let ((st (state))) | |
(when (and st (not (eq? st 'CHARLIT))) | |
(error "Invalid state at begin-here" st))) | |
(~ mr 'state := next-state) | |
(~ mr 'start-stream := stream) | |
(~ mr 'start-index := index) | |
(~ mr 'start-lineno := (~ mr 'lineno)) | |
(~ mr 'start-column := (~ mr 'column))) | |
(define (%tkn-set-start! tkn type) | |
(~ tkn 'type := type) | |
(~ tkn 'start-stream := (~ mr 'start-stream)) | |
(~ tkn 'start-index := (~ mr 'start-index)) | |
(~ tkn 'start-lineno := (~ mr 'start-lineno)) | |
(~ tkn 'start-column := (~ mr 'start-column))) | |
(define (%emit-tkn!) | |
(~ mr 'state := #f) | |
(set! retidx curidx) | |
(set! curidx (+ 1 curidx))) | |
(define (end-here tkn-type) | |
(let ((tkn (vector-ref vec curidx))) | |
(%tkn-set-start! tkn tkn-type) | |
(~ tkn 'end-stream := stream) | |
(~ tkn 'end-index := index) | |
(~ tkn 'end-lineno := (~ mr 'lineno)) | |
(~ tkn 'end-column := (~ mr 'column))) | |
(%emit-tkn!)) | |
(define (end-prev) | |
(let ((tkn (vector-ref vec curidx))) | |
(%tkn-set-start! tkn (~ mr 'prev-type)) | |
(~ tkn 'end-stream := (~ mr 'prev-stream)) | |
(~ tkn 'end-index := (~ mr 'prev-index)) | |
(~ tkn 'end-lineno := (~ mr 'prev-lineno)) | |
(~ tkn 'end-column := (~ mr 'prev-column))) | |
(%emit-tkn!)) | |
(define (tkn-single tkn-type) (begin-here #f) (end-here tkn-type)) | |
(case st | |
((CHARLIT) (set-prev-here 'OBJ) (set-state! 'OBJ0)) | |
((#f) | |
(case type | |
((LIST_BEGIN_PAREN | |
LIST_END_PAREN | |
LIST_BEGIN_SQ | |
LIST_END_SQ | |
NEXT_QUOTE | |
NEXT_QUASIQUOTE) | |
(tkn-single type)) | |
((SEMICOLON) (begin-here 'LINECOMMENT0)) | |
((DQUOTE) (begin-here 'STRING0)) | |
((NEXT_UNQUOTE) (set-prev-here 'NEXT_UNQUOTE) (begin-here 'OBJ1)) | |
((SPACE CR LF) 'do-nothing) | |
((SHARP) (set-prev-here 'OBJ) (begin-here 'OBJ1/SHARP)) | |
(else | |
(set-prev-here 'OBJ) | |
(if has-next? (begin-here 'OBJ1) (begin-here 'OBJ0))))) | |
((OBJ0 OBJ0/SHARP) | |
(case type | |
((LIST_BEGIN_PAREN) | |
(cond ((eq? st 'OBJ0/SHARP) (end-here 'OBJ)) | |
(else (end-prev) (hold) (set-state! #f)))) | |
(else | |
(cond ((or (whitespace?) (delimiter?)) | |
(end-prev) | |
(hold) | |
(set-state! #f)) | |
(else | |
(set-prev-here 'OBJ) | |
(when has-next? (set-state! 'OBJ1))))))) | |
((OBJ1 OBJ1/SHARP) | |
(case type | |
((NEXT_CHAR_LITERAL) (set-prev-here 'OBJ) (set-state! 'CHARLIT)) | |
((NEXT_SYNTAX_QUOTE | |
NEXT_SYNTAX_QUASIQUOTE | |
NEXT_UNQUOTE_SPLICING | |
NEXT_DATUM_COMMENT | |
TRUE | |
FALSE) | |
(end-here type)) | |
((BLOCK_COMMENT_BEGIN) | |
(blockcomment-depth++) | |
(set-state! 'BLOCKCOMMENT0)) | |
(else | |
(case prev-type | |
((NEXT_UNQUOTE) (end-prev) (hold) (set-state! #f)) | |
(else | |
(cond ((and (eq? st 'OBJ1/SHARP) (paren-l?)) (end-here 'OBJ)) | |
((delimiter?) (end-prev) (hold) (set-state! #f)) | |
(else | |
(hold) | |
(if (eq? st 'OBJ1/SHARP) | |
(set-state! 'OBJ0/SHARP) | |
(set-state! 'OBJ0))))))))) | |
((OBJ2) | |
(case type | |
((NEXT_SYNTAX_UNQUOTE_SPLICING) (end-here type)) | |
(else | |
(case prev-type | |
((NEXT_SYNTAX_UNQUOTE) (end-prev) (hold) (set-state! #f)) | |
(else (error "???")))))) | |
((STRING0) | |
(case type | |
((BACKSLASH) (set-state! 'STRING1)) | |
((DQUOTE) (end-here 'STRING)) | |
(else 'do-nothing))) | |
((STRING1) (set-state! 'STRING0)) | |
((LINECOMMENT0) | |
(case type | |
((LF) (end-here 'COMMENT)) | |
((CR) (set-prev-here 'COMMENT) (set-state! 'LINECOMMENT1)))) | |
((LINECOMMENT1) | |
(case type | |
((CRLF) (end-here 'COMMENT)) | |
(else (end-prev) (hold) (set-state! #f)))) | |
((BLOCKCOMMENT0) | |
(case type | |
((PIPE SHARP) (set-state! 'BLOCKCOMMENT1)) | |
(else 'do-nothing))) | |
((BLOCKCOMMENT1) | |
(case type | |
((BLOCK_COMMENT_BEGIN) (blockcomment-depth++)) | |
((BLOCK_COMMENT_END) | |
(blockcomment-depth--) | |
(cond ((blockcomment-depth-zero?) | |
(end-here 'COMMENT) | |
(set-state! #f)) | |
(else (set-state! 'BLOCKCOMMENT0)))) | |
(else (set-state! 'BLOCKCOMMENT0)))) | |
(else (error "?????")))) | |
(define (stream-end stream index) | |
(callstep char 32 #f #f) | |
(set! terminate? #t)) | |
(define (byte b stream index) | |
(cond ((eof-object? b) (stream-end stream index)) | |
(else | |
(unless (integer? b) (error "Invalid value" b)) | |
(callstep char b stream index)))) | |
(define (itr) | |
(unless (or terminate? (= curidx vecend)) | |
(let ((hold (~ mr 'hold))) | |
(if hold | |
(let ((stream (~ mr 'hold-stream)) | |
(index (~ mr 'hold-index))) | |
(~ mr 'hold := #f) | |
(byte hold stream index)) | |
(call-with-values cb byte))) | |
(itr))) | |
(itr) | |
retidx) | |
(set! %%%export-make-miniread~63 make-miniread) | |
(set! %%%export-make-tkn~64 make-tkn) | |
(set! %%%export-tkn-start-stream~65 tkn-start-stream) | |
(set! %%%export-tkn-start-index~66 tkn-start-index) | |
(set! %%%export-tkn-start-lineno~67 tkn-start-lineno) | |
(set! %%%export-tkn-start-column~68 tkn-start-column) | |
(set! %%%export-tkn-end-stream~69 tkn-end-stream) | |
(set! %%%export-tkn-end-index~70 tkn-end-index) | |
(set! %%%export-tkn-end-lineno~71 tkn-end-lineno) | |
(set! %%%export-tkn-end-column~72 tkn-end-column) | |
(set! %%%export-tkn-type~73 tkn-type) | |
(set! %%%export-miniread-main~74 miniread-main))) | |
(begin | |
(define %%%export-utf8-read~75 #f) | |
(let ((miniread-main %%%export-miniread-main~74) | |
(tkn-type %%%export-tkn-type~73) | |
(tkn-end-column %%%export-tkn-end-column~72) | |
(tkn-end-lineno %%%export-tkn-end-lineno~71) | |
(tkn-end-index %%%export-tkn-end-index~70) | |
(tkn-end-stream %%%export-tkn-end-stream~69) | |
(tkn-start-column %%%export-tkn-start-column~68) | |
(tkn-start-lineno %%%export-tkn-start-lineno~67) | |
(tkn-start-index %%%export-tkn-start-index~66) | |
(tkn-start-stream %%%export-tkn-start-stream~65) | |
(make-tkn %%%export-make-tkn~64) | |
(make-miniread %%%export-make-miniread~63)) | |
(define (%u8-list->bytevector lis) | |
(define (itr bv cur rest) | |
(when (pair? rest) | |
(bytevector-u8-set! bv cur (car rest)) | |
(itr bv (+ cur 1) (cdr rest)))) | |
(let ((bv (make-bytevector (length lis)))) (itr bv 0 lis) bv)) | |
(define (%realize-string-raw bv start end) | |
(utf8->string bv start (+ 1 end))) | |
(define (%realize-PLACEHOLDER bv start end) | |
(let ((s (%realize-string-raw bv start end))) | |
(read (open-input-string s)))) | |
(define (%realize-string bv start end) | |
(%realize-PLACEHOLDER bv start end)) | |
(define (%realize-charlit bv start end) | |
(%realize-PLACEHOLDER bv start end)) | |
(define (%realize-number bv start end) | |
(string->number (%realize-string-raw bv start end))) | |
(define (%realize-object bv start end) | |
(string->symbol (%realize-string-raw bv start end))) | |
(define (%check-special-token bv start end) | |
(define s (%realize-string-raw bv start end)) | |
(cond ((or (string=? "#vu8(" s) (string=? "#u8(" s)) 'BYTEVECTOR_BEGIN) | |
((string=? "#(" s) 'VECTOR_BEGIN) | |
(else | |
(let ((head (and (<= 2 (string-length s)) (substring s 0 2)))) | |
(cond ((and head (string=? head "#!")) 'IGNORE) | |
((and head (string=? head "#\\")) 'CHARLIT) | |
(else (and (string->number s) 'NUMBER))))))) | |
(define (%realize bv lst) | |
(define (elem-type e) (vector-ref e 0)) | |
(define (elem-start e) (vector-ref e 1)) | |
(define (elem-end e) (vector-ref e 2)) | |
(define (itr mode dump cur rest) | |
(if (pair? rest) | |
(let ((a (car rest)) (d (cdr rest))) | |
(let ((type (elem-type a)) | |
(start (elem-start a)) | |
(end (elem-end a))) | |
(define (go-next mode obj cur dump) | |
(define (next/pop take? obj) | |
(let* ((x (car dump)) | |
(prev-cur (car x)) | |
(prev-mode (cdr x)) | |
(next-dump (cdr dump))) | |
(itr prev-mode | |
next-dump | |
(if take? (cons obj prev-cur) prev-cur) | |
d))) | |
(define (nextnext x) (itr mode dump (cons x cur) d)) | |
(define (nextnext/pop obj) (next/pop #t obj)) | |
(define (nextdrop/pop) (next/pop #f #f)) | |
(define (nextchar/pop obj) | |
(define c (string-ref obj 0)) | |
(nextnext/pop c)) | |
(case mode | |
((NEXT_QUOTE) (nextnext/pop (list 'quote obj))) | |
((NEXT_QUASIQUOTE) (nextnext/pop (list 'quasiquote obj))) | |
((NEXT_UNQUOTE) (nextnext/pop (list 'unquote obj))) | |
((NEXT_UNQUOTE_SPLICING) | |
(nextnext/pop (list 'unquote-splicing obj))) | |
((NEXT_SYNTAX_QUOTE) (nextnext/pop (list 'syntax obj))) | |
((NEXT_SYNTAX_UNQUOTE) | |
(nextnext/pop (list 'unsyntax obj))) | |
((NEXT_SYTNAX_UNQUOTE_SPLICING) | |
(nextnext/pop (list 'unsyntax-splicing obj))) | |
((NEXT_SYNTAX_QUASIQUOTE) | |
(nextnext/pop (list 'quasisyntax obj))) | |
((NEXT_DATUM_COMMENT) (nextdrop/pop)) | |
((NEXT_CHAR_LITERAL) (nextchar/pop obj)) | |
(else (nextnext obj)))) | |
(define (single obj) (go-next mode obj cur dump)) | |
(define (single/pop obj) | |
(let* ((x (car dump)) | |
(next-dump (cdr dump)) | |
(prev-cur (car x)) | |
(prev-mode (cdr x))) | |
(go-next prev-mode obj prev-cur next-dump))) | |
(define (push-to-dump next-mode) | |
(itr next-mode (cons (cons cur mode) dump) '() d)) | |
(case type | |
((COMMENT BLOCK_COMMENT) (itr mode dump cur d)) | |
((TRUE) (single #t)) | |
((FALSE) (single #f)) | |
((STRING) (single (%realize-string bv start end))) | |
((OBJ) | |
(let ((t (%check-special-token bv start end))) | |
(case t | |
((VECTOR_BEGIN) (push-to-dump 'VECTOR)) | |
((BYTEVECTOR_BEGIN) (push-to-dump 'BYTEVECTOR)) | |
((IGNORE) (itr mode dump cur d)) | |
((NUMBER) (single (%realize-number bv start end))) | |
((CHARLIT) (single (%realize-charlit bv start end))) | |
(else (single (%realize-object bv start end)))))) | |
((LIST_BEGIN_PAREN LIST_BEGIN_SQ) (push-to-dump 'LIST)) | |
((LIST_END_PAREN LIST_END_SQ) | |
(let ((obj (case mode | |
((LIST) (reverse cur)) | |
((VECTOR) (list->vector (reverse cur))) | |
((BYTEVECTOR) | |
(%u8-list->bytevector (reverse cur))) | |
(else (error "unknown mode??" mode))))) | |
(single/pop obj))) | |
((NEXT_QUOTE | |
NEXT_QUASIQUOTE | |
NEXT_UNQUOTE | |
NEXT_UNQUOTE_SPLICING | |
NEXT_SYNTAX_QUOTE | |
NEXT_SYNTAX_QUASIQUOTE | |
NEXT_SYNTAX_UNQUOTE_SPLICING | |
NEXT_DATUM_COMMENT | |
NEXT_CHAR_LITERAL) | |
(push-to-dump type)) | |
(else (error "unknown token type??" type))))) | |
(case mode | |
((FIRST) (reverse cur)) | |
(else (error "unknown mode?" mode))))) | |
(itr 'FIRST '() '() lst)) | |
(define (%utf8-in bv) | |
(define cur 0) | |
(define len (bytevector-length bv)) | |
(lambda () | |
(cond ((= cur len) (values (eof-object) bv cur)) | |
(else | |
(let ((c cur) (b (bytevector-u8-ref bv cur))) | |
(set! cur (+ 1 cur)) | |
(values b bv c)))))) | |
(define (utf8-read bv) | |
(define tkn (make-tkn 1)) | |
(define cb (%utf8-in bv)) | |
(define mr (make-miniread)) | |
(define (capture tkn idx) | |
(let ((start-index (tkn-start-index tkn idx)) | |
(end-index (tkn-end-index tkn idx)) | |
(type (tkn-type tkn idx))) | |
(vector type start-index end-index))) | |
(define (itr cur) | |
(let ((r (miniread-main mr tkn 0 1 cb))) | |
(cond ((eq? r #f) (%realize bv (reverse cur))) | |
((and (number? r) (= r 0)) (itr (cons (capture tkn 0) cur))) | |
(else (error "something wrong" r))))) | |
(itr '())) | |
(set! %%%export-utf8-read~75 utf8-read))) | |
(begin | |
(define %%%export-id?~76 #f) | |
(define %%%export-id-new-variable~77 #f) | |
(define %%%export-id-new-macro~78 #f) | |
(define %%%export-id-new-library-variable~79 #f) | |
(define %%%export-id-new-library-macro~80 #f) | |
(define %%%export-id-new-primitive~81 #f) | |
(define %%%export-id-new-aux-syntax~82 #f) | |
(define %%%export-id-set-global-name!~83 #f) | |
(define %%%export-id-set-gensym-ident!~84 #f) | |
(define %%%export-id-set-library!~85 #f) | |
(define %%%export-id-source-name~86 #f) | |
(define %%%export-id-global-name~87 #f) | |
(define %%%export-id-gensym-ident~88 #f) | |
(define %%%export-id-library~89 #f) | |
(define %%%export-id-variable?~90 #f) | |
(define %%%export-id-macro?~91 #f) | |
(define %%%export-id-aux-syntax?~92 #f) | |
(define %%%export-id-primitive?~93 #f) | |
(let () | |
(define id-ident (cons 'id '())) | |
(define (id? obj) | |
(and (vector? obj) | |
(>= (vector-length obj) 1) | |
(eq? id-ident (vector-ref obj 0)))) | |
(define (id-source-name id) (vector-ref id 1)) | |
(define (id-global-name id) (vector-ref id 2)) | |
(define (id-gensym-ident id) (vector-ref id 3)) | |
(define (id-library id) (vector-ref id 4)) | |
(define (%id-type id) (vector-ref id 5)) | |
(define (id-variable? id) (eq? (%id-type id) 'variable)) | |
(define (id-macro? id) (eq? (%id-type id) 'macro)) | |
(define (id-aux-syntax? id) (eq? (%id-type id) 'aux-syntax)) | |
(define (id-primitive? id) (vector-ref id 6)) | |
(define (id-set-global-name! id name) (vector-set! id 2 name)) | |
(define (id-set-gensym-ident! id ident) (vector-set! id 3 ident)) | |
(define (id-set-library! id lib) (vector-set! id 4 lib)) | |
(define (id-new-variable sym) (vector id-ident sym sym 0 #t 'variable #f)) | |
(define (id-new-macro sym) (vector id-ident sym sym 0 #t 'macro #f)) | |
(define (id-new-library-variable sym global lib) | |
(vector id-ident sym global 0 lib 'variable #f)) | |
(define (id-new-library-macro sym global lib) | |
(vector id-ident sym global 0 lib 'macro #f)) | |
(define (id-new-primitive sym global lib) | |
(vector id-ident sym global 0 lib 'variable #t)) | |
(define (id-new-aux-syntax sym lib) | |
(vector id-ident sym sym 0 lib 'aux-syntax #f)) | |
(set! %%%export-id?~76 id?) | |
(set! %%%export-id-new-variable~77 id-new-variable) | |
(set! %%%export-id-new-macro~78 id-new-macro) | |
(set! %%%export-id-new-library-variable~79 id-new-library-variable) | |
(set! %%%export-id-new-library-macro~80 id-new-library-macro) | |
(set! %%%export-id-new-primitive~81 id-new-primitive) | |
(set! %%%export-id-new-aux-syntax~82 id-new-aux-syntax) | |
(set! %%%export-id-set-global-name!~83 id-set-global-name!) | |
(set! %%%export-id-set-gensym-ident!~84 id-set-gensym-ident!) | |
(set! %%%export-id-set-library!~85 id-set-library!) | |
(set! %%%export-id-source-name~86 id-source-name) | |
(set! %%%export-id-global-name~87 id-global-name) | |
(set! %%%export-id-gensym-ident~88 id-gensym-ident) | |
(set! %%%export-id-library~89 id-library) | |
(set! %%%export-id-variable?~90 id-variable?) | |
(set! %%%export-id-macro?~91 id-macro?) | |
(set! %%%export-id-aux-syntax?~92 id-aux-syntax?) | |
(set! %%%export-id-primitive?~93 id-primitive?))) | |
(begin | |
(define %%%export-envframe-decl-binding!~94 #f) | |
(define %%%export-envframe-def-binding!~95 #f) | |
(define %%%export-envframe-add-binding!~96 #f) | |
(define %%%export-envframe-only-bindings!~97 #f) | |
(define %%%export-envframe-except-bindings!~98 #f) | |
(define %%%export-envframe-prefix-bindings!~99 #f) | |
(define %%%export-envframe-rename-bindings!~100 #f) | |
(define %%%export-envframe-lookup~101 #f) | |
(define %%%export-envframe-lookup-decl~102 #f) | |
(define %%%export-envframe-lookup-def~103 #f) | |
(define %%%export-envframe-import!~104 #f) | |
(define %%%export-envframe-new~105 #f) | |
(define %%%export-env-lookup~106 #f) | |
(define %%%export-env-current-frame~107 #f) | |
(define %%%export-env-current-add-unknown!~108 #f) | |
(define %%%export-env-up/merge!~109 #f) | |
(define %%%export-env-new-envframe!~110 #f) | |
(define %%%export-env-new~111 #f) | |
(let ((id-primitive? %%%export-id-primitive?~93) | |
(id-aux-syntax? %%%export-id-aux-syntax?~92) | |
(id-macro? %%%export-id-macro?~91) | |
(id-variable? %%%export-id-variable?~90) | |
(id-library %%%export-id-library~89) | |
(id-gensym-ident %%%export-id-gensym-ident~88) | |
(id-global-name %%%export-id-global-name~87) | |
(id-source-name %%%export-id-source-name~86) | |
(id-set-library! %%%export-id-set-library!~85) | |
(id-set-gensym-ident! %%%export-id-set-gensym-ident!~84) | |
(id-set-global-name! %%%export-id-set-global-name!~83) | |
(id-new-aux-syntax %%%export-id-new-aux-syntax~82) | |
(id-new-primitive %%%export-id-new-primitive~81) | |
(id-new-library-macro %%%export-id-new-library-macro~80) | |
(id-new-library-variable %%%export-id-new-library-variable~79) | |
(id-new-macro %%%export-id-new-macro~78) | |
(id-new-variable %%%export-id-new-variable~77) | |
(id? %%%export-id?~76)) | |
(define (%envframe-for-each proc envframe) | |
(for-each (lambda (sym+id) (proc sym+id)) (car envframe))) | |
(define (%envframe-filter-sym! envframe proc) | |
(define out '()) | |
(let ((c (car envframe))) | |
(for-each | |
(lambda (sym+id) | |
(let ((sym (car sym+id)) (id (cdr sym+id))) | |
(let ((x (proc sym))) | |
(when x | |
(set! out (cons (cons (if (eq? x #t) sym x) id) out)))))) | |
c) | |
(set-car! envframe (reverse out)))) | |
(define (envframe-only-bindings! envframe . sym) | |
(define (filt s) (and (memv s sym) #t)) | |
(%envframe-filter-sym! envframe filt)) | |
(define (envframe-except-bindings! envframe . sym) | |
(define (filt s) (not (memv s sym))) | |
(%envframe-filter-sym! envframe filt)) | |
(define (envframe-prefix-bindings! envframe pref) | |
(define name (symbol->string pref)) | |
(define (filt s) | |
(string->symbol (string-append name (symbol->string s)))) | |
(%envframe-filter-sym! envframe filt)) | |
(define (envframe-rename-bindings! envframe . ren) | |
(define (filt s) | |
(define (itr rest) | |
(and (pair? rest) | |
(let ((from (car (car rest))) (to (cadr (car rest)))) | |
(or (and (eq? from s) to) (itr (cdr rest)))))) | |
(or (itr ren) s)) | |
(%envframe-filter-sym! envframe filt)) | |
(define (envframe-decl-binding! envframe sym id) | |
(let ((c (car envframe))) | |
(set-car! envframe (cons (cons (cons 'decl sym) id) c)))) | |
(define (envframe-def-binding! envframe sym id) | |
(let ((c (car envframe))) | |
(set-car! envframe (cons (cons (cons 'def sym) id) c)))) | |
(define (envframe-add-binding! envframe sym id) | |
(let ((c (car envframe))) (set-car! envframe (cons (cons sym id) c)))) | |
(define (%envframe-lookup-tagged envframe tag sym) | |
(define (search rest) | |
(and (pair? rest) | |
(let ((p (caar rest))) | |
(or (and (pair? p) | |
(eq? (car p) tag) | |
(eq? (cdr p) sym) | |
(cdar rest)) | |
(search (cdr rest)))))) | |
(let ((l (car envframe))) (search l))) | |
(define (envframe-lookup-decl envframe sym) | |
(%envframe-lookup-tagged envframe 'decl sym)) | |
(define (envframe-lookup-def envframe sym) | |
(%envframe-lookup-tagged envframe 'def sym)) | |
(define (envframe-lookup envframe sym) | |
(define (search rest) | |
(and (pair? rest) | |
(or (and (eq? (caar rest) sym) (cdar rest)) | |
(search (cdr rest))))) | |
(let ((l (car envframe))) (search l))) | |
(define (envframe-import! envframe libframe) | |
(define (importone e) | |
(let ((sym (car e)) (id (cdr e))) | |
(let ((origid (envframe-lookup envframe sym))) | |
(cond (origid | |
(unless (and (eq? (id-source-name origid) | |
(id-source-name id)) | |
(eq? (id-global-name origid) | |
(id-global-name id)) | |
(equal? (id-library origid) (id-library id))) | |
(error "Unmatched import" origid id))) | |
(else (envframe-add-binding! envframe sym id)))))) | |
(let ((l (car libframe))) (for-each importone l))) | |
(define (envframe-new) (cons '() #f)) | |
(define (%env-content env) (car env)) | |
(define (%env-content-set! env e) (set-car! env e)) | |
(define (%env-capsule l) (cons l #f)) | |
(define (env-lookup env sym) | |
(define (search rest) | |
(and (pair? rest) | |
(or (envframe-lookup (env-current-frame (%env-capsule rest)) sym) | |
(search (cdr rest))))) | |
(search (%env-content env))) | |
(define (env-current-frame env) (caar (%env-content env))) | |
(define (env-current-add-unknown! env pair) | |
(let ((p (car (%env-content env)))) | |
(let ((current-unknown (cdr p))) | |
(set-cdr! p (cons pair current-unknown))))) | |
(define (%env-current-unknown-reset! env) | |
(let ((p (car (%env-content env)))) (set-cdr! p '()))) | |
(define (env-up/merge! env) | |
(let ((unknowns (cdar (cdr (%env-content env)))) | |
(cf (env-current-frame env)) | |
(next (cdr (%env-content env)))) | |
(let ((next-env (%env-capsule next))) | |
(%envframe-for-each | |
(lambda (x+id) | |
(let ((x (car x+id)) (id (cdr x+id))) | |
(when (pair? x) | |
(let ((disp (car x)) (sym (cdr x))) | |
(when (eq? disp 'def) | |
(envframe-add-binding! | |
(env-current-frame next-env) | |
sym | |
id)))))) | |
cf) | |
(%env-current-unknown-reset! next-env) | |
(for-each | |
(lambda (e) | |
(let ((id (env-lookup next-env (car e)))) | |
(cond (id | |
(unless (id-variable? id) (error "Invalid def match" e)) | |
(set-car! e (id-global-name id))) | |
(else (env-current-add-unknown! next-env e))))) | |
unknowns)) | |
(%env-content-set! env next))) | |
(define (env-new-envframe! env) | |
(let ((c (%env-content env))) | |
(%env-content-set! env (cons (cons (envframe-new) '()) c)))) | |
(define (env-new) (%env-capsule (list (cons (envframe-new) '())))) | |
(set! %%%export-envframe-decl-binding!~94 envframe-decl-binding!) | |
(set! %%%export-envframe-def-binding!~95 envframe-def-binding!) | |
(set! %%%export-envframe-add-binding!~96 envframe-add-binding!) | |
(set! %%%export-envframe-only-bindings!~97 envframe-only-bindings!) | |
(set! %%%export-envframe-except-bindings!~98 envframe-except-bindings!) | |
(set! %%%export-envframe-prefix-bindings!~99 envframe-prefix-bindings!) | |
(set! %%%export-envframe-rename-bindings!~100 envframe-rename-bindings!) | |
(set! %%%export-envframe-lookup~101 envframe-lookup) | |
(set! %%%export-envframe-lookup-decl~102 envframe-lookup-decl) | |
(set! %%%export-envframe-lookup-def~103 envframe-lookup-def) | |
(set! %%%export-envframe-import!~104 envframe-import!) | |
(set! %%%export-envframe-new~105 envframe-new) | |
(set! %%%export-env-lookup~106 env-lookup) | |
(set! %%%export-env-current-frame~107 env-current-frame) | |
(set! %%%export-env-current-add-unknown!~108 env-current-add-unknown!) | |
(set! %%%export-env-up/merge!~109 env-up/merge!) | |
(set! %%%export-env-new-envframe!~110 env-new-envframe!) | |
(set! %%%export-env-new~111 env-new))) | |
(begin | |
(define %%%export-interfacelib~112 #f) | |
(define %%%export-id-$define/primitive?~113 #f) | |
(define %%%export-id-$define-aux-syntax?~114 #f) | |
(define %%%export-id-$bind-variable?~115 #f) | |
(define %%%export-id-$bind-definition?~116 #f) | |
(define %%%export-id-$extend-env?~117 #f) | |
(define %%%export-id-$inject?~118 #f) | |
(define %%%export-id-$inject/multi?~119 #f) | |
(define %%%export-id-$inject/form?~120 #f) | |
(define %%%export-id-$inject/splice?~121 #f) | |
(define %%%export-id-$alias?~122 #f) | |
(define %%%export-id-$quote?~123 #f) | |
(define %%%export-id-define-syntax?~124 #f) | |
(define %%%export-id-syntax-error?~125 #f) | |
(define %%%export-id-syntax-rules?~126 #f) | |
(let ((env-new %%%export-env-new~111) | |
(env-new-envframe! %%%export-env-new-envframe!~110) | |
(env-up/merge! %%%export-env-up/merge!~109) | |
(env-current-add-unknown! %%%export-env-current-add-unknown!~108) | |
(env-current-frame %%%export-env-current-frame~107) | |
(env-lookup %%%export-env-lookup~106) | |
(envframe-new %%%export-envframe-new~105) | |
(envframe-import! %%%export-envframe-import!~104) | |
(envframe-lookup-def %%%export-envframe-lookup-def~103) | |
(envframe-lookup-decl %%%export-envframe-lookup-decl~102) | |
(envframe-lookup %%%export-envframe-lookup~101) | |
(envframe-rename-bindings! %%%export-envframe-rename-bindings!~100) | |
(envframe-prefix-bindings! %%%export-envframe-prefix-bindings!~99) | |
(envframe-except-bindings! %%%export-envframe-except-bindings!~98) | |
(envframe-only-bindings! %%%export-envframe-only-bindings!~97) | |
(envframe-add-binding! %%%export-envframe-add-binding!~96) | |
(envframe-def-binding! %%%export-envframe-def-binding!~95) | |
(envframe-decl-binding! %%%export-envframe-decl-binding!~94) | |
(id-primitive? %%%export-id-primitive?~93) | |
(id-aux-syntax? %%%export-id-aux-syntax?~92) | |
(id-macro? %%%export-id-macro?~91) | |
(id-variable? %%%export-id-variable?~90) | |
(id-library %%%export-id-library~89) | |
(id-gensym-ident %%%export-id-gensym-ident~88) | |
(id-global-name %%%export-id-global-name~87) | |
(id-source-name %%%export-id-source-name~86) | |
(id-set-library! %%%export-id-set-library!~85) | |
(id-set-gensym-ident! %%%export-id-set-gensym-ident!~84) | |
(id-set-global-name! %%%export-id-set-global-name!~83) | |
(id-new-aux-syntax %%%export-id-new-aux-syntax~82) | |
(id-new-primitive %%%export-id-new-primitive~81) | |
(id-new-library-macro %%%export-id-new-library-macro~80) | |
(id-new-library-variable %%%export-id-new-library-variable~79) | |
(id-new-macro %%%export-id-new-macro~78) | |
(id-new-variable %%%export-id-new-variable~77) | |
(id? %%%export-id?~76)) | |
(define lib '(r7c-expander-interface)) | |
(define-syntax | |
xid | |
(syntax-rules () ((_ sym) (id-new-library-macro 'sym 'sym lib)))) | |
(define %$define/primitive (xid $define/primitive)) | |
(define %$define-aux-syntax (xid $define-aux-syntax)) | |
(define %$bind-variable (xid $bind-variable)) | |
(define %$bind-definition (xid $bind-definition)) | |
(define %$extend-env (xid $extend-env)) | |
(define %$inject (xid $inject)) | |
(define %$inject/splice (xid $inject/splice)) | |
(define %$inject/multi (xid $inject/multi)) | |
(define %$inject/form (xid $inject/form)) | |
(define %$alias (xid $alias)) | |
(define %$quote (xid $quote)) | |
(define %define-syntax (xid define-syntax)) | |
(define %syntax-rules (xid syntax-rules)) | |
(define %syntax-error (xid syntax-error)) | |
(define (id-$define/primitive? x) (eq? x %$define/primitive)) | |
(define (id-$define-aux-syntax? x) (eq? x %$define-aux-syntax)) | |
(define (id-$bind-variable? x) (eq? x %$bind-variable)) | |
(define (id-$bind-definition? x) (eq? x %$bind-definition)) | |
(define (id-$extend-env? x) (eq? x %$extend-env)) | |
(define (id-$inject? x) (eq? x %$inject)) | |
(define (id-$inject/splice? x) (eq? x %$inject/splice)) | |
(define (id-$inject/multi? x) (eq? x %$inject/multi)) | |
(define (id-$inject/form? x) (eq? x %$inject/form)) | |
(define (id-$alias? x) (eq? x %$alias)) | |
(define (id-$quote? x) (eq? x %$quote)) | |
(define (id-define-syntax? x) (eq? x %define-syntax)) | |
(define (id-syntax-rules? x) (eq? x %syntax-rules)) | |
(define (id-syntax-error? x) (eq? x %syntax-error)) | |
(define (libs) | |
(let ((ef (envframe-new))) | |
(for-each | |
(lambda (s e) (envframe-add-binding! ef s e)) | |
'($define/primitive | |
$define-aux-syntax | |
$bind-variable | |
$bind-definition | |
$extend-env | |
$inject | |
$inject/splice | |
$inject/multi | |
$inject/form | |
$alias | |
$quote | |
define-syntax | |
syntax-rules | |
syntax-error) | |
(list %$define/primitive | |
%$define-aux-syntax | |
%$bind-variable | |
%$bind-definition | |
%$extend-env | |
%$inject | |
%$inject/splice | |
%$inject/multi | |
%$inject/form | |
%$alias | |
%$quote | |
%define-syntax | |
%syntax-rules | |
%syntax-error)) | |
ef)) | |
(define (interfacelib) (cons lib (libs))) | |
(set! %%%export-interfacelib~112 interfacelib) | |
(set! %%%export-id-$define/primitive?~113 id-$define/primitive?) | |
(set! %%%export-id-$define-aux-syntax?~114 id-$define-aux-syntax?) | |
(set! %%%export-id-$bind-variable?~115 id-$bind-variable?) | |
(set! %%%export-id-$bind-definition?~116 id-$bind-definition?) | |
(set! %%%export-id-$extend-env?~117 id-$extend-env?) | |
(set! %%%export-id-$inject?~118 id-$inject?) | |
(set! %%%export-id-$inject/multi?~119 id-$inject/multi?) | |
(set! %%%export-id-$inject/form?~120 id-$inject/form?) | |
(set! %%%export-id-$inject/splice?~121 id-$inject/splice?) | |
(set! %%%export-id-$alias?~122 id-$alias?) | |
(set! %%%export-id-$quote?~123 id-$quote?) | |
(set! %%%export-id-define-syntax?~124 id-define-syntax?) | |
(set! %%%export-id-syntax-error?~125 id-syntax-error?) | |
(set! %%%export-id-syntax-rules?~126 id-syntax-rules?))) | |
(begin | |
(define %%%export-expand-forms!~127 #f) | |
(let ((id-syntax-rules? %%%export-id-syntax-rules?~126) | |
(id-syntax-error? %%%export-id-syntax-error?~125) | |
(id-define-syntax? %%%export-id-define-syntax?~124) | |
(id-$quote? %%%export-id-$quote?~123) | |
(id-$alias? %%%export-id-$alias?~122) | |
(id-$inject/splice? %%%export-id-$inject/splice?~121) | |
(id-$inject/form? %%%export-id-$inject/form?~120) | |
(id-$inject/multi? %%%export-id-$inject/multi?~119) | |
(id-$inject? %%%export-id-$inject?~118) | |
(id-$extend-env? %%%export-id-$extend-env?~117) | |
(id-$bind-definition? %%%export-id-$bind-definition?~116) | |
(id-$bind-variable? %%%export-id-$bind-variable?~115) | |
(id-$define-aux-syntax? %%%export-id-$define-aux-syntax?~114) | |
(id-$define/primitive? %%%export-id-$define/primitive?~113) | |
(interfacelib %%%export-interfacelib~112) | |
(env-new %%%export-env-new~111) | |
(env-new-envframe! %%%export-env-new-envframe!~110) | |
(env-up/merge! %%%export-env-up/merge!~109) | |
(env-current-add-unknown! %%%export-env-current-add-unknown!~108) | |
(env-current-frame %%%export-env-current-frame~107) | |
(env-lookup %%%export-env-lookup~106) | |
(envframe-new %%%export-envframe-new~105) | |
(envframe-import! %%%export-envframe-import!~104) | |
(envframe-lookup-def %%%export-envframe-lookup-def~103) | |
(envframe-lookup-decl %%%export-envframe-lookup-decl~102) | |
(envframe-lookup %%%export-envframe-lookup~101) | |
(envframe-rename-bindings! %%%export-envframe-rename-bindings!~100) | |
(envframe-prefix-bindings! %%%export-envframe-prefix-bindings!~99) | |
(envframe-except-bindings! %%%export-envframe-except-bindings!~98) | |
(envframe-only-bindings! %%%export-envframe-only-bindings!~97) | |
(envframe-add-binding! %%%export-envframe-add-binding!~96) | |
(envframe-def-binding! %%%export-envframe-def-binding!~95) | |
(envframe-decl-binding! %%%export-envframe-decl-binding!~94) | |
(id-primitive? %%%export-id-primitive?~93) | |
(id-aux-syntax? %%%export-id-aux-syntax?~92) | |
(id-macro? %%%export-id-macro?~91) | |
(id-variable? %%%export-id-variable?~90) | |
(id-library %%%export-id-library~89) | |
(id-gensym-ident %%%export-id-gensym-ident~88) | |
(id-global-name %%%export-id-global-name~87) | |
(id-source-name %%%export-id-source-name~86) | |
(id-set-library! %%%export-id-set-library!~85) | |
(id-set-gensym-ident! %%%export-id-set-gensym-ident!~84) | |
(id-set-global-name! %%%export-id-set-global-name!~83) | |
(id-new-aux-syntax %%%export-id-new-aux-syntax~82) | |
(id-new-primitive %%%export-id-new-primitive~81) | |
(id-new-library-macro %%%export-id-new-library-macro~80) | |
(id-new-library-variable %%%export-id-new-library-variable~79) | |
(id-new-macro %%%export-id-new-macro~78) | |
(id-new-variable %%%export-id-new-variable~77) | |
(id? %%%export-id?~76)) | |
(define (expand! top-level? forms env cb-gensym) | |
(define (re-enter) (expand! top-level? forms env cb-gensym)) | |
(define (next) (expand! top-level? (cdr forms) env cb-gensym)) | |
(define (enter p) (expand! top-level? p env cb-gensym)) | |
(define (gensym p orig) (cb-gensym p orig top-level?)) | |
(define (erase-next) | |
(let ((d (cdr forms))) | |
(cond ((pair? d) | |
(set-car! forms (car d)) | |
(set-cdr! forms (cdr d)) | |
(re-enter)) | |
((null? d) (set-car! forms '(begin))) | |
(else (error "oops" forms))))) | |
(define (expand-car! maybe-macro? thepair env) | |
(define (handle-variable lookup) | |
(set-car! thepair (id-global-name lookup))) | |
(define (handle-unknown) (env-current-add-unknown! env thepair)) | |
(unless (pair? thepair) (error "pair required" thepair)) | |
(let ((a (car thepair))) | |
(cond ((symbol? a) | |
(let ((lookup (env-lookup env a))) | |
(cond (maybe-macro? | |
(cond ((and lookup (id-macro? lookup)) | |
(set-car! thepair lookup)) | |
(lookup (handle-variable lookup)) | |
(else (handle-unknown)))) | |
(lookup | |
(when (id-macro? lookup) | |
(error "macro not allowed here" thepair)) | |
(handle-variable lookup)) | |
(else (handle-unknown)))))))) | |
(define (expand-variable! top-level? forms env) | |
(unless (or (pair? forms) (null? forms)) (error "huh?" forms)) | |
(when (pair? forms) | |
(let ((a (car forms))) | |
(cond ((pair? a) (expand! top-level? forms env cb-gensym)) | |
(else | |
(expand-car! #f forms env) | |
(expand-variable! top-level? (cdr forms) env)))))) | |
(define (expand-$inject splice-env? multi-env? forms a) | |
(define new-frame? (not (or splice-env? multi-env?))) | |
(let ((sym (cadr a)) (body* (cddr a))) | |
(when new-frame? (env-new-envframe! env)) | |
(expand! (and splice-env? top-level?) body* env cb-gensym) | |
(when new-frame? (env-up/merge! env)) | |
(set-car! forms (cdr a)) | |
(next))) | |
(define (expand-$inject/form forms a) | |
(let ((body* (cdr a))) | |
(expand! top-level? body* env cb-gensym) | |
(set-car! forms body*))) | |
(cond ((pair? forms) | |
(let ((a (car forms))) | |
(cond ((pair? a) | |
(let ((i (car a))) | |
(cond ((symbol? i) | |
(expand-car! #t a env) | |
(let ((i2 (car a))) | |
(cond ((symbol? i2) | |
(expand-variable! | |
top-level? | |
(cdr a) | |
env) | |
(next)) | |
(else (re-enter))))) | |
((pair? i) (enter a) (next)) | |
((not (id? i)) (error "Invalid invocation" a)) | |
((id-$bind-variable? i) | |
(let ((sym (cadr a))) | |
(unless (symbol? sym) | |
(error "symbol required" a)) | |
(envframe-decl-binding! | |
(env-current-frame env) | |
sym | |
(id-new-variable sym)) | |
(set-car! forms sym) | |
(next))) | |
((id-$bind-definition? i) | |
(let ((sym (cadr a))) | |
(unless (symbol? sym) | |
(error "symbol required" a)) | |
(let ((id (id-new-variable sym)) | |
(gsym (gensym a sym))) | |
(id-set-global-name! id gsym) | |
(envframe-def-binding! | |
(env-current-frame env) | |
sym | |
id) | |
(set-car! forms gsym) | |
(next)))) | |
((id-$extend-env? i) | |
(let ((sym* (cadr a)) (body* (cddr a))) | |
(let ((cf (env-current-frame env))) | |
(for-each | |
(lambda (sym) | |
(or (let ((decl (envframe-lookup-decl | |
cf | |
sym))) | |
(and decl | |
(begin | |
(envframe-add-binding! | |
cf | |
sym | |
decl) | |
#t))) | |
(let ((def (envframe-lookup-def | |
cf | |
sym))) | |
(and def | |
(begin | |
(envframe-add-binding! | |
cf | |