📄 psyntax.ss
字号:
(define eval-local-transformer (lambda (expanded) (let ((p (local-eval-hook expanded))) (if (procedure? p) p (syntax-error p "nonprocedure transfomer")))))(define chi-void (lambda () (build-application no-source (build-primref no-source 'void) '())))(define ellipsis? (lambda (x) (and (nonsymbol-id? x) (free-id=? x (syntax (... ...))))));;; data;;; strips all annotations from potentially circular reader output(define strip-annotation (lambda (x parent) (cond ((pair? x) (let ((new (cons #f #f))) (when parent (set-annotation-stripped! parent new)) (set-car! new (strip-annotation (car x) #f)) (set-cdr! new (strip-annotation (cdr x) #f)) new)) ((annotation? x) (or (annotation-stripped x) (strip-annotation (annotation-expression x) x))) ((vector? x) (let ((new (make-vector (vector-length x)))) (when parent (set-annotation-stripped! parent new)) (let loop ((i (- (vector-length x) 1))) (unless (fx< i 0) (vector-set! new i (strip-annotation (vector-ref x i) #f)) (loop (fx- i 1)))) new)) (else x))));;; strips syntax-objects down to top-wrap; if top-wrap is layered directly;;; on an annotation, strips the annotation as well.;;; since only the head of a list is annotated by the reader, not each pair;;; in the spine, we also check for pairs whose cars are annotated in case;;; we've been passed the cdr of an annotated list(define strip (lambda (x w) (if (top-marked? w) (if (or (annotation? x) (and (pair? x) (annotation? (car x)))) (strip-annotation x #f) x) (let f ((x x)) (cond ((syntax-object? x) (strip (syntax-object-expression x) (syntax-object-wrap x))) ((pair? x) (let ((a (f (car x))) (d (f (cdr x)))) (if (and (eq? a (car x)) (eq? d (cdr x))) x (cons a d)))) ((vector? x) (let ((old (vector->list x))) (let ((new (map f old))) (if (andmap eq? old new) x (list->vector new))))) (else x))))));;; lexical variables(define gen-var (lambda (id) (let ((id (if (syntax-object? id) (syntax-object-expression id) id))) (if (annotation? id) (build-lexical-var (annotation-source id) (annotation-expression id)) (build-lexical-var no-source id)))))(define lambda-var-list (lambda (vars) (let lvl ((vars vars) (ls '()) (w empty-wrap)) (cond ((pair? vars) (lvl (cdr vars) (cons (wrap (car vars) w) ls) w)) ((id? vars) (cons (wrap vars w) ls)) ((null? vars) ls) ((syntax-object? vars) (lvl (syntax-object-expression vars) ls (join-wraps w (syntax-object-wrap vars)))) ((annotation? vars) (lvl (annotation-expression vars) ls w)) ; include anything else to be caught by subsequent error ; checking (else (cons vars ls))))));;; core transformers(global-extend 'local-syntax 'letrec-syntax #t)(global-extend 'local-syntax 'let-syntax #f)(global-extend 'core 'fluid-let-syntax (lambda (e r w s) (syntax-case e () ((_ ((var val) ...) e1 e2 ...) (valid-bound-ids? (syntax (var ...))) (let ((names (map (lambda (x) (id-var-name x w)) (syntax (var ...))))) (for-each (lambda (id n) (case (binding-type (lookup n r)) ((displaced-lexical) (syntax-error (source-wrap id w s) "identifier out of context")))) (syntax (var ...)) names) (chi-body (syntax (e1 e2 ...)) (source-wrap e w s) (extend-env names (let ((trans-r (macros-only-env r))) (map (lambda (x) (make-binding 'macro (eval-local-transformer (chi x trans-r w)))) (syntax (val ...)))) r) w))) (_ (syntax-error (source-wrap e w s))))))(global-extend 'core 'quote (lambda (e r w s) (syntax-case e () ((_ e) (build-data s (strip (syntax e) w))) (_ (syntax-error (source-wrap e w s))))))(global-extend 'core 'syntax (let () (define gen-syntax (lambda (src e r maps ellipsis?) (if (id? e) (let ((label (id-var-name e empty-wrap))) (let ((b (lookup label r))) (if (eq? (binding-type b) 'syntax) (call-with-values (lambda () (let ((var.lev (binding-value b))) (gen-ref src (car var.lev) (cdr var.lev) maps))) (lambda (var maps) (values `(ref ,var) maps))) (if (ellipsis? e) (syntax-error src "misplaced ellipsis in syntax form") (values `(quote ,e) maps))))) (syntax-case e () ((dots e) (ellipsis? (syntax dots)) (gen-syntax src (syntax e) r maps (lambda (x) #f))) ((x dots . y) ; this could be about a dozen lines of code, except that we ; choose to handle (syntax (x ... ...)) forms (ellipsis? (syntax dots)) (let f ((y (syntax y)) (k (lambda (maps) (call-with-values (lambda () (gen-syntax src (syntax x) r (cons '() maps) ellipsis?)) (lambda (x maps) (if (null? (car maps)) (syntax-error src "extra ellipsis in syntax form") (values (gen-map x (car maps)) (cdr maps)))))))) (syntax-case y () ((dots . y) (ellipsis? (syntax dots)) (f (syntax y) (lambda (maps) (call-with-values (lambda () (k (cons '() maps))) (lambda (x maps) (if (null? (car maps)) (syntax-error src "extra ellipsis in syntax form") (values (gen-mappend x (car maps)) (cdr maps)))))))) (_ (call-with-values (lambda () (gen-syntax src y r maps ellipsis?)) (lambda (y maps) (call-with-values (lambda () (k maps)) (lambda (x maps) (values (gen-append x y) maps))))))))) ((x . y) (call-with-values (lambda () (gen-syntax src (syntax x) r maps ellipsis?)) (lambda (x maps) (call-with-values (lambda () (gen-syntax src (syntax y) r maps ellipsis?)) (lambda (y maps) (values (gen-cons x y) maps)))))) (#(e1 e2 ...) (call-with-values (lambda () (gen-syntax src (syntax (e1 e2 ...)) r maps ellipsis?)) (lambda (e maps) (values (gen-vector e) maps)))) (_ (values `(quote ,e) maps)))))) (define gen-ref (lambda (src var level maps) (if (fx= level 0) (values var maps) (if (null? maps) (syntax-error src "missing ellipsis in syntax form") (call-with-values (lambda () (gen-ref src var (fx- level 1) (cdr maps))) (lambda (outer-var outer-maps) (let ((b (assq outer-var (car maps)))) (if b (values (cdr b) maps) (let ((inner-var (gen-var 'tmp))) (values inner-var (cons (cons (cons outer-var inner-var) (car maps)) outer-maps))))))))))) (define gen-mappend (lambda (e map-env) `(apply (primitive append) ,(gen-map e map-env)))) (define gen-map (lambda (e map-env) (let ((formals (map cdr map-env)) (actuals (map (lambda (x) `(ref ,(car x))) map-env))) (cond ((eq? (car e) 'ref) ; identity map equivalence: ; (map (lambda (x) x) y) == y (car actuals)) ((andmap (lambda (x) (and (eq? (car x) 'ref) (memq (cadr x) formals))) (cdr e)) ; eta map equivalence: ; (map (lambda (x ...) (f x ...)) y ...) == (map f y ...) `(map (primitive ,(car e)) ,@(map (let ((r (map cons formals actuals))) (lambda (x) (cdr (assq (cadr x) r)))) (cdr e)))) (else `(map (lambda ,formals ,e) ,@actuals)))))) (define gen-cons (lambda (x y) (case (car y) ((quote) (if (eq? (car x) 'quote) `(quote (,(cadr x) . ,(cadr y))) (if (eq? (cadr y) '()) `(list ,x) `(cons ,x ,y)))) ((list) `(list ,x ,@(cdr y))) (else `(cons ,x ,y))))) (define gen-append (lambda (x y) (if (equal? y '(quote ())) x `(append ,x ,y)))) (define gen-vector (lambda (x) (cond ((eq? (car x) 'list) `(vector ,@(cdr x))) ((eq? (car x) 'quote) `(quote #(,@(cadr x)))) (else `(list->vector ,x))))) (define regen (lambda (x) (case (car x) ((ref) (build-lexical-reference 'value no-source (cadr x))) ((primitive) (build-primref no-source (cadr x))) ((quote) (build-data no-source (cadr x))) ((lambda) (build-lambda no-source (cadr x) (regen (caddr x)))) ((map) (let ((ls (map regen (cdr x)))) (build-application no-source (if (fx= (length ls) 2) (build-primref no-source 'map) ; really need to do our own checking here (build-primref no-source 2 'map)) ; require error check ls))) (else (build-application no-source (build-primref no-source (car x)) (map regen (cdr x))))))) (lambda (e r w s) (let ((e (source-wrap e w s))) (syntax-case e () ((_ x) (call-with-values (lambda () (gen-syntax e (syntax x) r '() ellipsis?)) (lambda (e maps) (regen e)))) (_ (syntax-error e)))))))(global-extend 'core 'lambda (lambda (e r w s) (syntax-case e () ((_ . c) (chi-lambda-clause (source-wrap e w s) (syntax c) r w (lambda (vars body) (build-lambda s vars body)))))))(global-extend 'core 'let (let () (define (chi-let e r w s constructor ids vals exps) (if (not (valid-bound-ids? ids)) (syntax-error e "duplicate bound variable in") (let ((labels (gen-labels ids)) (new-vars (map gen-var ids))) (let ((nw (make-binding-wrap ids labels w)) (nr (extend-var-env labels new-vars r))) (constructor s new-vars (map (lambda (x) (chi x r w)) vals) (chi-body exps (source-wrap e nw s) nr nw)))))) (lambda (e r w s) (syntax-case e () ((_ ((id val) ...) e1 e2 ...) (chi-let e r w s build-let (syntax (id ...)) (syntax (val ...)) (syntax (e1 e2 ...)))) ((_ f ((id val) ...) e1 e2 ...) (id? (syntax f)) (chi-let e r w s build-named-let (syntax (f id ...)) (syntax (val ...)) (sy
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -