1 ;;;============================================================================
3 ;;; File: "_ptree1.scm"
5 ;;; Copyright (c) 1994-2011 by Marc Feeley, All Rights Reserved.
9 (include-adt "_envadt.scm")
10 (include-adt "_gvmadt.scm")
11 (include "_ptreeadt.scm")
12 (include-adt "_sourceadt.scm")
14 '(begin;**************brad
15 (##include "_sourceadt.scm")
16 (##include "_envadt.scm")
17 (##include "_utilsadt.scm")
18 (##include "_hostadt.scm")
21 ;;;----------------------------------------------------------------------------
23 ;; Parse tree manipulation module: (part 1)
24 ;; ------------------------------
26 ;; This module contains procedures to construct the parse tree of a Scheme
27 ;; expression and manipulate the parse tree.
29 (define next-node-stamp #f)
31 (define (node-children-set! x y)
33 (for-each (lambda (child) (node-parent-set! child x)) y)
34 (node-fv-invalidate! x))
36 (define (node-fv-invalidate! x)
40 (node-fv-set! node #t)
41 (node-bfv-set! node #t)
42 (loop (node-parent node))))))
44 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
46 ;; Procedures to create parse tree nodes and extract sub-nodes.
48 (define (new-cst source env val)
49 (make-cst #f '() #t #t env source val))
51 (define (new-ref source env var)
52 (let ((node (make-ref #f '() #t #t env source var)))
53 (var-refs-set! var (ptset-adjoin (var-refs var) node))
56 (define (new-ref-extended-bindings source name env)
57 (new-ref source (add-extended-bindings env)
58 (env-lookup-global-var env name)))
60 (define (new-set source env var val)
61 (let ((node (make-set #f (list val) #t #t env source var)))
62 (var-sets-set! var (ptset-adjoin (var-sets var) node))
63 (node-parent-set! val node)
68 (car (node-children x))
69 (compiler-internal-error "set-val, 'set' node expected" x)))
71 (define (new-def source env var val)
72 (let ((node (make-def #f (list val) #t #t env source var)))
73 (var-sets-set! var (ptset-adjoin (var-sets var) node))
74 (node-parent-set! val node)
79 (car (node-children x))
80 (compiler-internal-error "def-val, 'def' node expected" x)))
82 (define (new-tst source env pre con alt)
83 (let ((node (make-tst #f (list pre con alt) #t #t env source)))
84 (node-parent-set! pre node)
85 (node-parent-set! con node)
86 (node-parent-set! alt node)
91 (car (node-children x))
92 (compiler-internal-error "tst-pre, 'tst' node expected" x)))
96 (cadr (node-children x))
97 (compiler-internal-error "tst-con, 'tst' node expected" x)))
101 (caddr (node-children x))
102 (compiler-internal-error "tst-alt, 'tst' node expected" x)))
104 (define (new-conj source env pre alt)
105 (let ((node (make-conj #f (list pre alt) #t #t env source)))
106 (node-parent-set! pre node)
107 (node-parent-set! alt node)
112 (car (node-children x))
113 (compiler-internal-error "conj-pre, 'conj' node expected" x)))
117 (cadr (node-children x))
118 (compiler-internal-error "conj-alt, 'conj' node expected" x)))
120 (define (new-disj source env pre alt)
121 (let ((node (make-disj #f (list pre alt) #t #t env source)))
122 (node-parent-set! pre node)
123 (node-parent-set! alt node)
128 (car (node-children x))
129 (compiler-internal-error "disj-pre, 'disj' node expected" x)))
133 (cadr (node-children x))
134 (compiler-internal-error "disj-alt, 'disj' node expected" x)))
136 (define (new-prc source env name c-name parms opts keys rest? body)
137 (let* ((children (list body))
138 (node (make-prc #f children #t #t env source
139 name c-name parms opts keys rest?)))
140 (for-each (lambda (x) (var-bound-set! x node)) parms)
141 (node-parent-set! body node)
146 (car (node-children x))
147 (compiler-internal-error "prc-body, 'proc' node expected" x)))
149 (define (prc-req-and-opt-parms-only? x)
150 (and (not (prc-keys x))
151 (not (prc-rest? x))))
153 (define (new-call source env oper args)
154 (let ((node (make-app #f (cons oper args) #t #t env source)))
155 (node-parent-set! oper node)
156 (for-each (lambda (x) (node-parent-set! x node)) args)
159 (define (new-call* source env oper args)
160 (new-call source env oper args))
164 (car (node-children x))
165 (compiler-internal-error "app-oper, 'call' node expected" x)))
169 (cdr (node-children x))
170 (compiler-internal-error "app-args, 'call' node expected" x)))
172 (define (oper-pos? node)
173 (let ((parent (node-parent node)))
176 (eq? (app-oper parent) node))
179 (define (new-fut source env val)
180 (let ((node (make-fut #f (list val) #t #t env source)))
181 (node-parent-set! val node)
186 (car (node-children x))
187 (compiler-internal-error "fut-val, 'fut' node expected" x)))
189 (define (new-disj-call source env pre oper alt)
190 (new-call* source env
191 (let* ((temp (new-temp-variable source 'cond-temp))
193 (inner-env (env-frame env parms)))
194 (new-prc source env #f #f parms '() #f #f
195 (new-tst source inner-env
196 (new-ref source inner-env temp)
197 (new-call* source inner-env
199 (list (new-ref source inner-env temp)))
203 (define (new-seq source env before after)
204 (let ((temp (new-temp-variable source 'begin-temp)))
205 (new-call* source env
206 (new-prc source env #f #f (list temp) '() #f #f
210 (define (new-let ptree proc vars vals body)
212 (new-call (node-source ptree) (node-env ptree)
213 (new-prc (node-source proc) (node-env proc)
224 (define temp-variable-stamp #f)
226 (define (new-temp-variable source name)
227 (make-var (string->symbol
228 (string-append (symbol->string name)
230 (number->string (temp-variable-stamp))))
236 (define (new-variables sources)
237 (map new-variable sources))
239 (define (new-variable source)
240 (make-var (source-code source) #t (ptset-empty) (ptset-empty) source))
242 (define (set-prc-names! vars vals)
243 (let loop ((vars vars) (vals vals))
244 (if (not (null? vars))
245 (let ((var (car vars))
248 (prc-name-set! val (symbol->string (var-name var))))
249 (loop (cdr vars) (cdr vals))))))
251 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
253 ;; Procedures to get variable classes from nodes.
255 (define (free-variables node) ; set of free variables used in the expression
256 (if (eq? (node-fv node) #t)
257 (let ((x (varset-union-multi (map free-variables (node-children node)))))
260 (varset-adjoin x (ref-var node)))
262 (varset-adjoin x (set-var node)))
264 (varset-difference x (bound-variables node)))
265 ((and (app? node) (prc? (app-oper node)))
266 (varset-difference x (bound-variables (app-oper node))))
271 (define (bound-free-variables node) ; set of bound free variables used in expr
272 (if (eq? (node-bfv node) #t)
274 (list->varset (keep bound? (varset->list (free-variables node))))))
277 (define (bound-variables node) ; set of variables bound by a procedure
278 (list->varset (prc-parms node)))
280 (define (mutable? var) ; var must be a bound variable (i.e. non-global)
281 (not (ptset-empty? (var-sets var))))
286 (define (global? var)
289 (define (global-single-def var) ; get definition of a global if it is only
290 (and (global? var) ; defined once and it will never change
291 (let ((sets (ptset->list (var-sets var))))
295 (block-compilation? (node-env (car sets)))
296 (def-val (car sets))))))
298 (define (global-proc-obj node)
299 (let ((var (ref-var node)))
301 (let ((name (var-name var)))
302 (standard-proc-obj (target.prim-info name)
306 (define (global-singly-bound? node)
307 (or (global-single-def (ref-var node))
308 (global-proc-obj node)))
310 (define (app->specialized-proc node)
311 (let ((oper (app-oper node))
312 (args (app-args node))
313 (env (node-env node)))
314 (specialize-app oper args env)))
316 (define (specialize-app oper args env)
319 (let ((val (cst-val oper)))
323 (global-proc-obj oper))
329 (define (specialize-proc proc args env)
331 (nb-args-conforms? (length args) (proc-obj-call-pat proc))
332 (let loop ((proc proc))
334 ((proc-obj-specialize proc)
336 (map (lambda (arg) (if (cst? arg) (cst-val arg) void-object))
342 (define (nb-args-conforms? n call-pat)
343 (pattern-member? n call-pat))
345 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
349 ;; Dialect related declarations:
351 ;; (ieee-scheme) use IEEE Scheme
352 ;; (r4rs-scheme) use R4RS Scheme
353 ;; (r5rs-scheme) use R5RS Scheme
354 ;; (gambit-scheme) use Gambit Scheme
355 ;; (multilisp) use Multilisp
357 ;; Partial-evaluation declarations:
359 ;; (constant-fold) can constant-fold primitives
360 ;; (not constant-fold) can't constant-fold primitives
362 ;; Lambda-lifting declarations:
364 ;; (lambda-lift) can lambda-lift user procedures
365 ;; (not lambda-lift) can't lambda-lift user procedures
367 ;; Inlining declarations:
369 ;; (inline) compiler may inline user procedures
370 ;; (not inline) no user procedure will be inlined
372 ;; (inline-primitives) can inline all primitives
373 ;; (inline-primitives <var1> ...) can inline primitives <var1> ...
374 ;; (not inline-primitives) can't inline any primitives
375 ;; (not inline-primitives <var1> ...) can't inline primitives <var1> ...
377 ;; (inlining-limit n) inlined user procedures must not be
380 ;; Compilation strategy declarations:
382 ;; (block) global vars defined are only mutated by code in the current file
383 ;; (separate) global vars defined can be mutated by other code
385 ;; (core) toplevel expressions and definitions must be compiled to code
386 ;; (not core) toplevel expressions and definitions belong to another module
388 ;; Global variable binding declarations:
390 ;; (standard-bindings) compiler can assume standard bindings
391 ;; (standard-bindings <var1> ...) assume st. bind. for vars specified
392 ;; (not standard-bindings) can't assume st. bind. for any var
393 ;; (not standard-bindings <var1> ...) can't assume st. bind. for vars spec.
395 ;; (extended-bindings) compiler can assume extended bindings
396 ;; (extended-bindings <var1> ...) assume ext. bind. for vars specified
397 ;; (not extended-bindings) can't assume ext. bind. for any var
398 ;; (not extended-bindings <var1> ...) can't assume ext. bind. for vars spec.
400 ;; (run-time-bindings) should check bindings at run-time
401 ;; (run-time-bindings <var1> ...) check at run-time for vars specified
402 ;; (not run-time-bindings) should not check bindings at run-time
403 ;; (not run-time-bindings <var1> ...) don't check at run-time for vars specified
405 ;; Code safety declarations:
407 ;; (safe) runtime errors won't crash system
408 ;; (not safe) assume program doesn't contain errors
410 ;; (warnings) show warnings
411 ;; (not warnings) suppress warnings
413 ;; Interrupt checking declarations:
415 ;; (interrupts-enabled) allow interrupts
416 ;; (not interrupts-enabled) disallow interrupts
418 ;; Environment map declarations:
420 ;; (environment-map) generate environment maps
421 ;; (not environment-map) don't generate environment maps
423 ;; Proper tail calls declarations:
425 ;; (proper-tail-calls) generate proper tail calls
426 ;; (not proper-tail-calls) don't generate proper tail calls
428 ;; Optimizing dead local variables declarations:
430 ;; (optimize-dead-local-variables) optimize dead local variables
431 ;; (not optimize-dead-local-variables) don't optimize dead local variables
433 (define-flag-decl ieee-scheme-sym 'dialect)
434 (define-flag-decl r4rs-scheme-sym 'dialect)
435 (define-flag-decl r5rs-scheme-sym 'dialect)
436 (define-flag-decl gambit-scheme-sym 'dialect)
437 (define-flag-decl multilisp-sym 'dialect)
439 (define-boolean-decl constant-fold-sym)
441 (define-boolean-decl lambda-lift-sym)
443 (define-boolean-decl inline-sym)
444 (define-namable-boolean-decl inline-primitives-sym)
445 (define-parameterized-decl inlining-limit-sym)
447 (define-flag-decl block-sym 'compilation-strategy)
448 (define-flag-decl separate-sym 'compilation-strategy)
450 (define-boolean-decl core-sym)
452 (define-namable-boolean-decl standard-bindings-sym)
453 (define-namable-boolean-decl extended-bindings-sym)
454 (define-namable-boolean-decl run-time-bindings-sym)
456 (define-boolean-decl safe-sym)
458 (define-boolean-decl warnings-sym)
460 (define-boolean-decl interrupts-enabled-sym)
462 (define-boolean-decl debug-sym)
463 (define-boolean-decl debug-location-sym)
464 (define-boolean-decl debug-source-sym)
465 (define-boolean-decl debug-environments-sym)
467 (define-boolean-decl environment-map-sym) ;; deprecated: use debug-environments
469 (define-boolean-decl proper-tail-calls-sym)
471 (define-boolean-decl optimize-dead-local-variables-sym)
473 (define (scheme-dialect env) ; returns dialect in effect
474 (declaration-value 'dialect #f gambit-scheme-sym env))
476 (define (constant-fold? env) ; true iff should constant-fold primitives
477 (declaration-value constant-fold-sym #f #t env))
479 (define (lambda-lift? env) ; true iff should lambda-lift
480 (declaration-value lambda-lift-sym #f #t env))
482 (define (inline? env) ; true iff should inline
483 (declaration-value inline-sym #f #t env))
485 (define (inline-primitive? name env) ; true iff name can be inlined
486 (declaration-value inline-primitives-sym name #t env))
488 (define (add-not-inline-primitives env)
489 (env-declare env (list inline-primitives-sym #f)))
491 (define (inlining-limit env) ; returns the inlining limit
492 (max 0 (min 1000000 (declaration-value inlining-limit-sym #f 350 env))))
494 (define (block-compilation? env) ; true iff block compilation strategy
495 (eq? (declaration-value 'compilation-strategy #f separate-sym env)
498 (define (core? env) ; true iff core code
499 (declaration-value core-sym #f #t env))
501 (define (standard-binding? name env) ; true iff name's binding is standard
502 (declaration-value standard-bindings-sym name #f env))
504 (define (extended-binding? name env) ; true iff name's binding is extended
505 (declaration-value extended-bindings-sym name #f env))
507 (define (add-extended-bindings env)
508 (env-declare env (list extended-bindings-sym #t)))
510 (define (run-time-binding? name env) ; true iff name's binding is checked at run-time
511 (declaration-value run-time-bindings-sym name #t env))
513 (define (safe? env) ; true iff system should prevent fatal runtime errors
514 (declaration-value safe-sym #f #t env))
516 (define (add-not-safe env)
517 (env-declare env (list safe-sym #f)))
519 (define (warnings? env) ; true iff warnings are not suppressed
520 (declaration-value warnings-sym #f #t env))
522 (define (intrs-enabled? env) ; true iff interrupt checks should be generated
523 (declaration-value interrupts-enabled-sym #f #t env))
525 (define (add-not-interrupts-enabled env)
526 (env-declare env (list interrupts-enabled-sym #f)))
528 (define (debug? env) ; true iff debugging information should be generated
529 (declaration-value debug-sym #f compiler-option-debug env))
531 (define (debug-location? env) ; true iff source code location debugging information should be generated
532 (declaration-value debug-location-sym #f compiler-option-debug-location env))
534 (define (debug-source? env) ; true iff source code debugging information should be generated
535 (declaration-value debug-source-sym #f compiler-option-debug-source env))
537 (define (debug-environments? env) ; true iff environment debugging information should be generated
538 (declaration-value debug-environments-sym #f compiler-option-debug-environments env))
540 (define (environment-map? env) ; true iff environment map should be generated
541 (declaration-value environment-map-sym #f #f env))
543 (define (proper-tail-calls? env) ; true iff proper tail calls should be generated
544 (declaration-value proper-tail-calls-sym #f #t env))
546 (define (add-proper-tail-calls env)
547 (env-declare env (list proper-tail-calls-sym #t)))
549 (define (optimize-dead-local-variables? env) ; true iff dead local variables should be optimized
550 (declaration-value optimize-dead-local-variables-sym #f #t env))
552 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
556 (define (standard-proc-obj proc name env)
560 (standard-binding? name env)
561 (extended-binding? name env)
562 (scheme-dialect env))
565 (define (standard-procedure? proc std? ext? dialect)
566 (let ((standard (proc-obj-standard proc)))
567 (if (eq? standard 'extended)
570 (or (eq? standard 'ieee)
571 (and (not (eq? dialect ieee-scheme-sym))
572 (or (eq? standard 'r4rs)
573 (and (not (eq? dialect r4rs-scheme-sym))
574 (or (eq? standard 'r5rs)
575 (not (eq? dialect r5rs-scheme-sym)))))))))))
577 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
579 ;; (parse-program program env module-name proc) returns a (non-empty)
580 ;; list of parse trees, one for each top-level expression in the program.
581 ;; An artificial reference of the constant #f is added to the program
582 ;; if it is otherwise empty.
584 (define (parse-program program env module-name proc)
586 (define (parse-prog program env lst proc)
588 (proc (reverse lst) env)
589 (let ((source (car program)))
591 (cond ((macro-expr? source env)
593 (cons (macro-expand source env) (cdr program))
598 ((**begin-cmd-or-expr? source)
600 (append (begin-body source) (cdr program))
605 ((**define-expr? source env)
606 (let* ((var-source (definition-name source env))
607 (var (source-code var-source))
608 (v (env-lookup-var env var var-source)))
612 (display " " *ptree-port*)
613 (write (var-name v) *ptree-port*)
614 (newline *ptree-port*)))
616 (let ((node (pt (definition-value source) env 'true)))
617 (set-prc-names! (list v) (list node))
621 (cons (new-def source env v node)
625 ((or (**define-macro-expr? source env)
626 (**define-syntax-expr? source env))
630 (display " \"macro\"" *ptree-port*)
631 (newline *ptree-port*)))
635 (add-macro source env)
639 ((**include-expr? source)
642 (display " " *ptree-port*))
644 (let ((x (include-expr->source source *ptree-port*)))
647 (newline *ptree-port*))
650 (cons x (cdr program))
655 ((**declare-expr? source)
659 (display " \"declare\"" *ptree-port*)
660 (newline *ptree-port*)))
664 (add-declarations source env)
668 ((**namespace-expr? source)
672 (display " \"namespace\"" *ptree-port*)
673 (newline *ptree-port*)))
677 (add-namespace source env)
681 ;; ((**require-expr? source)
688 ((**c-define-type-expr? source)
689 (let ((name (source-code (c-type-definition-name source)))
690 (type (c-type-definition-type source)))
694 (display " \"c-define-type\"" *ptree-port*)
695 (newline *ptree-port*)))
697 (add-c-type name type)
705 ((**c-declare-expr? source)
706 (let ((body (source-code (c-declaration-body source))))
710 (display " \"c-declare\"" *ptree-port*)
711 (newline *ptree-port*)))
721 ((**c-initialize-expr? source)
722 (let ((body (source-code (c-initialization-body source))))
726 (display " \"c-initialize\"" *ptree-port*)
727 (newline *ptree-port*)))
737 ((**c-define-expr? source env)
738 (let* ((var-source (c-definition-name source))
739 (var (source-code var-source))
740 (v (env-lookup-var env var var-source))
741 (param-types (c-definition-param-types source))
742 (result-type (c-definition-result-type source))
743 (proc-name-source (c-definition-proc-name source))
744 (proc-name (source-code proc-name-source))
745 (scope-source (c-definition-scope source))
746 (scope (source-code scope-source)))
750 (display " " *ptree-port*)
751 (write (var-name v) *ptree-port*)
752 (newline *ptree-port*)))
754 (build-c-define param-types result-type proc-name scope)
756 (let ((node (pt (c-definition-value source) env 'true)))
757 (set-prc-names! (list v) (list node))
758 (prc-c-name-set! node proc-name)
762 (cons (new-def source env v node)
770 (display " \"expr\"" *ptree-port*)
771 (newline *ptree-port*)))
776 (cons (pt source env 'true) lst)
781 (display "Parsing:" *ptree-port*)
782 (newline *ptree-port*)))
784 (c-interface-begin module-name)
793 (newline *ptree-port*))
795 (check-multiple-global-defs env)
797 (proc (if (null? lst)
798 (list (new-cst (expression->source false-object #f) env
802 (c-interface-end)))))
804 (define (check-multiple-global-defs env)
805 (let ((global-vars (env-global-variables env)))
808 (let ((defs (keep def? (ptset->list (var-sets var)))))
809 (if (> (length defs) 1)
812 (if (warnings? (node-env def))
813 (compiler-user-warning
814 (source-locat (node-source def))
815 "More than one 'define' of global variable"
820 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
822 ;; (pt source env use) returns the parse tree for the Scheme source expression
823 ;; 'source' in the environment 'env'. If 'source' is not syntactically
824 ;; correct, an error is signaled. The value of 'use' determines what the
825 ;; expression's value will be used for; it must be one of the following:
827 ;; true : the true value of the expression is needed
828 ;; pred : the value is used as a predicate
829 ;; none : the value is not needed (but its side effect might)
831 (define (pt-syntax-error source msg . args)
832 (apply compiler-user-error
833 (cons (source-locat source)
837 (define (pt source env use)
838 (cond ((macro-expr? source env) (pt (macro-expand source env) env use))
839 ((self-eval-expr? source) (pt-self-eval source env use))
840 ((**quote-expr? source) (pt-quote source env use))
841 ((**quasiquote-expr? source) (pt-quasiquote source env use))
842 ((var-expr? source env) (pt-var source env use))
843 ((**set!-expr? source env) (pt-set! source env use))
844 ((**lambda-expr? source env) (pt-lambda source env use))
845 ((**if-expr? source) (pt-if source env use))
846 ((**cond-expr? source) (pt-cond source env use))
847 ((**and-expr? source) (pt-and source env use))
848 ((**or-expr? source) (pt-or source env use))
849 ((**case-expr? source) (pt-case source env use))
850 ((**let-expr? source env) (pt-let source env use))
851 ((**let*-expr? source env) (pt-let* source env use))
852 ((**letrec-expr? source env) (pt-letrec source env use))
853 ((**begin-expr? source) (pt-begin source env use))
854 ((**do-expr? source env) (pt-do source env use))
855 ((**delay-expr? source env) (pt-delay source env use))
856 ((**future-expr? source env) (pt-future source env use))
857 ((**define-expr? source env)
858 (pt-syntax-error source "Ill-placed 'define'"))
859 ((**define-macro-expr? source env)
860 (pt-syntax-error source "Ill-placed 'define-macro'"))
861 ((**define-syntax-expr? source env)
862 (pt-syntax-error source "Ill-placed 'define-syntax'"))
863 ((**include-expr? source)
864 (pt-syntax-error source "Ill-placed 'include'"))
865 ((**declare-expr? source)
866 (pt-syntax-error source "Ill-placed 'declare'"))
867 ((**namespace-expr? source)
868 (pt-syntax-error source "Ill-placed 'namespace'"))
869 ;; ((**require-expr? source)
870 ;; (pt-syntax-error source "Ill-placed 'require'"))
871 ((**c-define-type-expr? source)
872 (pt-syntax-error source "Ill-placed 'c-define-type'"))
873 ((**c-declare-expr? source)
874 (pt-syntax-error source "Ill-placed 'c-declare'"))
875 ((**c-initialize-expr? source)
876 (pt-syntax-error source "Ill-placed 'c-initialize'"))
877 ((**c-lambda-expr? source) (pt-c-lambda source env use))
878 ((**c-define-expr? source env)
879 (pt-syntax-error source "Ill-placed 'c-define'"))
880 ((combination-expr? source) (pt-combination source env use))
882 (pt-syntax-error source "Ill-formed expression"))))
884 (define (macro-expand source env)
885 (let ((code (source-code source)))
886 (let* ((descr (env-lookup-macro env (source-code (car code))))
887 (expander (##macro-descr-expander descr)))
889 (if (##macro-descr-def-syntax? descr)
891 (apply expander (cdr (source->expression source))))
894 (define (pt-self-eval source env use)
895 (let ((val (source->expression source)))
897 (new-cst source env void-object)
898 (new-cst source env val))))
900 (define (pt-quote source env use)
901 (let ((code (source-code source)))
903 (new-cst source env void-object)
904 (new-cst source env (source->expression (cadr code))))))
906 (define (pt-quasiquote source env use)
907 (let ((code (source-code source)))
908 (pt-quasiquotation (cadr code) 1 env)))
910 (define (pt-quasiquotation form level env)
913 ((quasiquote-expr? form)
914 (pt-quasiquotation-list form (source-code form) (+ level 1) env))
915 ((unquote-expr? form)
917 (pt (cadr (source-code form)) env 'true)
918 (pt-quasiquotation-list form (source-code form) (- level 1) env)))
919 ((unquote-splicing-expr? form)
921 (pt-syntax-error form "Ill-placed 'unquote-splicing'")
922 (pt-quasiquotation-list form (source-code form) (- level 1) env)))
923 ((pair? (source-code form))
924 (pt-quasiquotation-list form (source-code form) level env))
925 ((vector-object? (source-code form))
926 (let ((lst (vect->list (source-code form))))
929 (pt-quasiquotation-list form lst level env)
932 (new-cst form env (source->expression form)))))
934 (define (pt-quasiquotation-list form l level env)
936 (if (and (unquote-splicing-expr? (car l)) (= level 1))
937 (let ((x (pt (cadr (source-code (car l))) env 'true)))
942 (pt-quasiquotation-list form (cdr l) 1 env)
945 (pt-quasiquotation (car l) level env)
946 (pt-quasiquotation-list form (cdr l) level env)
949 (new-cst form env '()))
951 (pt-quasiquotation l level env))))
953 (define (append-form source ptree1 ptree2 env)
955 (define (call oper-sym args)
956 (new-call* source (add-not-safe env)
957 (new-ref-extended-bindings source oper-sym env)
960 (cond ((and (cst? ptree1) (cst? ptree2))
962 (append (cst-val ptree1) (cst-val ptree2))))
963 ((and (cst? ptree2) (null? (cst-val ptree2)))
966 (call **quasi-append-sym (list ptree1 ptree2)))))
968 (define (cons-form source ptree1 ptree2 env)
970 (define (call oper-sym args)
971 (new-call* source (add-not-safe env)
972 (new-ref-extended-bindings source oper-sym env)
975 (cond ((and (cst? ptree1) (cst? ptree2))
977 (cons (cst-val ptree1) (cst-val ptree2))))
978 ((and (cst? ptree2) (null? (cst-val ptree2)))
979 (call **quasi-list-sym (list ptree1)))
981 (app->specialized-proc ptree2))
984 (if (eq? proc **quasi-list-proc-obj)
985 (call **quasi-list-sym (cons ptree1 (app-args ptree2)))
986 (call **quasi-cons-sym (list ptree1 ptree2)))))
988 (call **quasi-cons-sym (list ptree1 ptree2)))))
990 (define (vector-form source ptree env)
992 (define (call oper-sym args)
993 (new-call* source (add-not-safe env)
994 (new-ref-extended-bindings source oper-sym env)
999 (list->vect (cst-val ptree))))
1000 ((list-construction? source ptree env)
1003 (call **quasi-vector-sym elems)))
1005 (call **quasi-list->vector-sym (list ptree)))))
1007 (define (list-construction? source ptree env)
1009 (let ((val (cst-val ptree)))
1010 (if (proper-length val)
1011 (map (lambda (elem-val)
1017 (app->specialized-proc ptree))
1020 (cond ((eq? proc **quasi-cons-proc-obj)
1021 (let ((args (app-args ptree)))
1022 (and (eqv? 2 (proper-length args))
1023 (let* ((arg1 (car args))
1025 (x (list-construction? source arg2 env)))
1028 ((eq? proc **quasi-list-proc-obj)
1035 (define (pt-var source env use)
1037 (new-cst source env void-object)
1039 (env-lookup-var env (source-code source) source))))
1041 (define (pt-set! source env use)
1042 (let* ((code (source-code source))
1044 (if (not (var-expr? var env))
1045 (pt-syntax-error var "Identifier expected"))
1047 (env-lookup-var env (source-code var) var)
1048 (pt (caddr code) env 'true))))
1050 (define (pt-lambda source env use)
1052 (define (check-none-result node)
1054 (new-cst source env void-object)
1057 (define (bind-default-bindings default-bindings env)
1058 (if (null? default-bindings)
1059 (pt-body source (cddr (source-code source)) env 'true)
1060 (let* ((binding (car default-bindings))
1061 (var1 (vector-ref binding 0))
1062 (var2 (vector-ref binding 1))
1063 (val (vector-ref binding 2))
1064 (parm-source (vector-ref binding 3))
1066 (new-call* parm-source env
1067 (new-prc parm-source env #f #f vars '() #f #f
1068 (bind-default-bindings
1069 (cdr default-bindings)
1070 (env-frame env vars)))
1071 (list (new-tst parm-source env
1072 (new-call* parm-source env
1073 (new-ref-extended-bindings
1077 (list (new-ref parm-source env var1)
1078 (new-cst parm-source env absent-object)))
1080 (new-ref parm-source env var1)))))))
1082 (define (split-default-bindings parms env cont)
1083 (let loop ((lst parms)
1090 (cont (reverse rev-vars)
1091 (reverse rev-defaults)
1092 (reverse rev-bindings)
1098 (parameter-source parameter))
1100 (parameter-default-source parameter))
1102 (new-variable parm-source))
1105 (pt val-source env 'true)
1106 (new-cst parm-source env
1110 (cons var1 rev-vars)
1111 (cons (cst-val val) rev-defaults)
1113 (env-frame env (list var1)))
1114 (let ((var2 (new-variable parm-source)))
1116 (cons var1 rev-vars)
1117 (cons absent-object rev-defaults)
1118 (cons (vector var1 var2 val parm-source)
1120 (env-frame env (list var2)))))))))
1123 (source-code source))
1125 (extract-parameters (source->parms (cadr code)) env))
1126 (required-parameters
1127 (vector-ref all-parms 0))
1128 (optional-parameters
1129 (vector-ref all-parms 1))
1131 (vector-ref all-parms 2))
1133 (vector-ref all-parms 3))
1135 (vector-ref all-parms 4))
1137 (new-variables (map parameter-source required-parameters)))
1140 (list (new-variable (parameter-source rest-parameter)))
1144 (split-default-bindings
1145 (or optional-parameters '())
1146 (env-frame env required-vars)
1147 (lambda (opt-vars opt-defaults opt-bindings opt-env)
1148 (split-default-bindings
1149 (or key-parameters '())
1150 (if dsssl-style-rest? (env-frame opt-env rest-vars) opt-env)
1151 (lambda (key-vars key-defaults key-bindings key-env)
1155 (cons (string->keyword-object
1156 (symbol->string (var-name (car x))))
1158 (pair-up key-vars key-defaults))))
1160 (append required-vars opt-vars key-vars rest-vars)))
1161 (new-prc source env #f #f outer-vars opt-defaults keys
1163 (if dsssl-style-rest? 'dsssl #t))
1164 (bind-default-bindings
1165 (append opt-bindings key-bindings)
1166 (env-frame env outer-vars)))))))))))
1168 (define (parameter-name parm)
1169 (vector-ref parm 0))
1171 (define (parameter-source parm)
1172 (vector-ref parm 1))
1174 (define (parameter-default-source parm)
1175 (vector-ref parm 2))
1177 (define (extract-parameters param-list env)
1179 (define (parm-expected-err source)
1180 (pt-syntax-error source "Identifier expected"))
1182 (define (parm-or-default-binding-expected-err source)
1183 (pt-syntax-error source "Parameter must be an identifier or default binding"))
1185 (define (duplicate-parm-err source)
1186 (pt-syntax-error source "Duplicate parameter in parameter list"))
1188 (define (duplicate-rest-parm-err source)
1189 (pt-syntax-error source "Duplicate rest parameter in parameter list"))
1191 (define (rest-parm-expected-err source)
1192 (pt-syntax-error source "#!rest must be followed by a parameter"))
1194 (define (rest-parm-must-be-last-err source)
1195 (pt-syntax-error source "Rest parameter must be last"))
1197 (define (default-binding-err source)
1198 (pt-syntax-error source "Ill-formed default binding"))
1200 (define (optional-illegal-err source)
1201 (pt-syntax-error source "Ill-placed #!optional"))
1203 (define (key-illegal-err source)
1204 (pt-syntax-error source "Ill-placed #!key"))
1206 (define (key-expected-err source)
1207 (pt-syntax-error source "#!key expected after rest parameter"))
1209 (define (default-binding-illegal-err source)
1210 (pt-syntax-error source "Ill-placed default binding"))
1212 (let loop ((lst param-list)
1213 (rev-required-parms '())
1214 (rev-optional-parms #f)
1217 (state 1)) ; 1 = required parms or #!optional/#!rest/#!key
1218 ; 2 = optional parms or #!rest/#!key
1220 ; 4 = key parms (or #!rest if rest-parm=#f)
1222 (define (done rest-parm2)
1223 (vector (reverse rev-required-parms)
1224 (and rev-optional-parms (reverse rev-optional-parms))
1226 (and rest-parm (= state 4))
1227 (if (or (not rev-key-parms)
1228 (and (null? rev-key-parms) (not rest-parm2)))
1230 (reverse rev-key-parms))))
1232 (define (parm-exists? parm lst)
1235 (or (eq? parm (vector-ref (car lst) 0))
1236 (parm-exists? parm (cdr lst)))))
1238 (define (check-if-duplicate parm parm-source)
1239 (if (or (parm-exists? parm rev-required-parms)
1240 (parm-exists? parm rev-optional-parms)
1241 (and rest-parm (eq? parm (vector-ref rest-parm 0)))
1242 (parm-exists? parm rev-key-parms))
1243 (duplicate-parm-err parm-source)))
1248 (let* ((parm-source (car lst))
1249 (parm (source-code parm-source)))
1250 (cond ((optional-object? parm)
1251 (if (not (= state 1))
1252 (optional-illegal-err parm-source))
1259 ((rest-object? parm)
1261 (duplicate-rest-parm-err parm-source))
1262 (if (pair? (cdr lst))
1263 (let* ((parm-source (cadr lst))
1264 (parm (source-code parm-source)))
1265 (if (bindable-var? parm-source env)
1267 (check-if-duplicate parm parm-source)
1269 (if (null? (cddr lst))
1270 (done (vector parm parm-source))
1271 (rest-parm-must-be-last-err parm-source))
1275 (vector parm parm-source)
1278 (parm-expected-err parm-source)))
1279 (rest-parm-expected-err parm-source)))
1282 (key-illegal-err parm-source))
1290 (key-expected-err parm-source))
1291 ((bindable-var? parm-source env)
1292 (check-if-duplicate parm parm-source)
1296 (cons (vector parm parm-source)
1305 (cons (vector parm parm-source #f)
1315 (cons (vector parm parm-source #f)
1319 (if (not (or (= state 2) (= state 4)))
1320 (default-binding-illegal-err parm-source))
1321 (let ((length (proper-length parm)))
1322 (if (not (eqv? length 2))
1323 (default-binding-err parm-source)))
1324 (let* ((parm-source (car parm))
1325 (val-source (cadr parm))
1326 (parm (source-code parm-source)))
1327 (if (bindable-var? parm-source env)
1329 (check-if-duplicate parm parm-source)
1334 (cons (vector parm parm-source val-source)
1344 (cons (vector parm parm-source val-source)
1347 (parm-expected-err parm-source))))
1349 (if (not (= state 1))
1350 (parm-or-default-binding-expected-err parm-source)
1351 (parm-expected-err parm-source))))))
1353 (let* ((parm-source lst)
1354 (parm (source-code parm-source)))
1355 (if (bindable-var? parm-source env)
1358 (duplicate-rest-parm-err parm-source))
1359 (check-if-duplicate parm parm-source)
1360 (done (vector parm parm-source)))
1361 (parm-expected-err parm-source)))))))
1363 (define (source->parms source)
1364 (let ((x (source-code source)))
1365 (if (or (pair? x) (null? x)) x source)))
1367 (define (pt-body source body env use)
1369 (define (letrec-defines vars vals envs body env)
1373 "Body must contain at least one expression"))
1374 ((macro-expr? (car body) env)
1375 (letrec-defines vars
1378 (cons (macro-expand (car body) env)
1381 ((**begin-cmd-or-expr? (car body))
1382 (letrec-defines vars
1385 (append (begin-body (car body))
1388 ((**define-expr? (car body) env)
1389 (let* ((var-source (definition-name (car body) env))
1390 (var (source-code var-source))
1391 (v (env-define-var env var var-source)))
1392 (letrec-defines (cons v vars)
1393 (cons (definition-value (car body)) vals)
1397 ((or (**define-macro-expr? (car body) env)
1398 (**define-syntax-expr? (car body) env))
1399 (letrec-defines vars
1403 (add-macro (car body) env)))
1404 ((**include-expr? (car body))
1406 (display " " *ptree-port*))
1407 (let ((x (include-expr->source (car body) *ptree-port*)))
1409 (newline *ptree-port*))
1410 (letrec-defines vars
1415 ((**declare-expr? (car body))
1416 (letrec-defines vars
1420 (add-declarations (car body) env)))
1421 ((**namespace-expr? (car body))
1422 (letrec-defines vars
1426 (add-namespace (car body) env)))
1427 ;; ((**require-expr? (car body))
1428 ;; (letrec-defines vars
1434 (pt-sequence source body env use))
1436 (let ((vars* (reverse vars)))
1437 (let loop ((vals* '()) (l1 vals) (l2 envs))
1438 (if (not (null? l1))
1439 (loop (cons (pt (car l1) (car l2) 'true) vals*)
1442 (pt-recursive-let source vars* vals* body env use)))))))
1444 (letrec-defines '() '() '() body (env-frame env '())))
1446 (define (pt-sequence source seq env use)
1447 (cond ;; ((length? seq 0)
1448 ;; ;; treat empty sequence as constant evaluating to the void object
1449 ;; (new-cst source env void-object))
1451 (pt (car seq) env use))
1454 (pt (car seq) env 'none)
1455 (pt-sequence source (cdr seq) env use)))))
1457 (define (pt-if source env use)
1458 (let ((code (source-code source)))
1460 (pt (cadr code) env 'pred)
1461 (pt (caddr code) env use)
1462 (if (length? code 3)
1463 (new-cst source env void-object)
1464 (pt (cadddr code) env use)))))
1466 (define (pt-cond source env use)
1468 (define (pt-clauses clauses)
1469 (if (length? clauses 0)
1470 (new-cst source env void-object)
1471 (let* ((clause-source (car clauses))
1472 (clause (source-code clause-source)))
1473 (cond ((eq? (source-code (car clause)) else-sym)
1474 (pt-sequence clause-source (cdr clause) env use))
1476 (new-disj clause-source env
1477 (pt (car clause) env (if (eq? use 'true) 'true 'pred))
1478 (pt-clauses (cdr clauses))))
1479 ((eq? (source-code (cadr clause)) =>-sym)
1480 (new-disj-call clause-source env
1481 (pt (car clause) env 'true)
1482 (pt (caddr clause) env 'true)
1483 (pt-clauses (cdr clauses))))
1485 (new-tst clause-source env
1486 (pt (car clause) env 'pred)
1487 (pt-sequence clause-source (cdr clause) env use)
1488 (pt-clauses (cdr clauses))))))))
1490 (pt-clauses (cdr (source-code source))))
1492 (define (pt-and source env use)
1494 (define (pt-exprs exprs)
1495 (cond ((length? exprs 0)
1496 (new-cst source env #t))
1498 (pt (car exprs) env use))
1500 (new-conj (car exprs) env
1501 (pt (car exprs) env (if (eq? use 'true) 'true 'pred))
1502 (pt-exprs (cdr exprs))))))
1504 (pt-exprs (cdr (source-code source))))
1506 (define (pt-or source env use)
1508 (define (pt-exprs exprs)
1509 (cond ((length? exprs 0)
1510 (new-cst source env false-object))
1512 (pt (car exprs) env use))
1514 (new-disj (car exprs) env
1515 (pt (car exprs) env (if (eq? use 'true) 'true 'pred))
1516 (pt-exprs (cdr exprs))))))
1518 (pt-exprs (cdr (source-code source))))
1520 (define (pt-case source env use)
1521 (let ((code (source-code source))
1522 (temp (new-temp-variable source 'case-temp)))
1524 (define (pt-clauses clauses)
1525 (if (length? clauses 0)
1526 (new-cst source env void-object)
1527 (let* ((clause-source (car clauses))
1528 (clause (source-code clause-source)))
1530 (define (pt-inlined-memv constants)
1535 (new-ref-extended-bindings clause-source **eqv?-sym env)
1536 (list (new-ref clause-source env
1538 (new-cst (car clause) env
1539 (car constants))))))
1540 (if (null? (cdr constants))
1542 (new-disj clause-source env
1544 (pt-inlined-memv (cdr constants))))))
1547 (if (eq? (source-code (car clause)) else-sym)
1548 (pt-sequence clause-source (cdr clause) env use)
1549 (new-tst clause-source env
1550 (pt-inlined-memv (source->expression (car clause)))
1551 (pt-sequence clause-source (cdr clause) env use)
1552 (pt-clauses (cdr clauses)))))))
1554 (new-call* source env
1555 (new-prc source env #f #f (list temp) '() #f #f
1556 (pt-clauses (cddr code)))
1557 (list (pt (cadr code) env 'true)))))
1559 (define (pt-let source env use)
1560 (let ((code (source-code source)))
1561 (if (bindable-var? (cadr code) env)
1563 (list (new-variable (cadr code))))
1565 (map source-code (source-code (caddr code))))
1567 (new-variables (map car bindings)))
1569 (map (lambda (x) (pt (cadr x) env 'true)) bindings))
1571 (env-frame env vars))
1573 (env-frame inner-env1 self))
1575 (list (new-prc source inner-env1
1582 (pt-body source (cdddr code) inner-env2 use)))))
1583 (set-prc-names! self self-proc)
1584 (set-prc-names! vars vals)
1585 (new-call* source env
1586 (new-prc source env #f #f self '() #f #f
1587 (new-call* source inner-env1
1588 (new-ref source inner-env1 (car self))
1591 (if (null? (source-code (cadr code)))
1592 (pt-body source (cddr code) env use)
1594 (map source-code (source-code (cadr code))))
1596 (new-variables (map car bindings)))
1598 (map (lambda (x) (pt (cadr x) env 'true)) bindings))
1600 (env-frame env vars)))
1601 (set-prc-names! vars vals)
1602 (new-call* source env
1610 (pt-body source (cddr code) inner-env use))
1613 (define (pt-let* source env use)
1614 (let ((code (source-code source)))
1616 (define (pt-bindings bindings env use)
1617 (if (null? bindings)
1618 (pt-body source (cddr code) env use)
1619 (let* ((binding-source
1622 (source-code binding-source))
1624 (list (new-variable (car binding))))
1626 (list (pt (cadr binding) env 'true)))
1628 (env-frame env vars)))
1629 (set-prc-names! vars vals)
1630 (new-call* binding-source env
1631 (new-prc binding-source env #f #f vars '() #f #f
1632 (pt-bindings (cdr bindings) inner-env use))
1635 (pt-bindings (source-code (cadr code)) env use)))
1637 (define (pt-letrec source env use)
1639 (source-code source))
1641 (map source-code (source-code (cadr code))))
1643 (new-variables (map car bindings)))
1645 (env-frame env vars*)))
1649 (map (lambda (x) (pt (cadr x) env* 'true)) bindings)
1654 (define (pt-recursive-let source vars vals body env use)
1656 (define (dependency-graph vars vals)
1657 (let ((var-set (list->varset vars)))
1659 (define (dgraph vars vals)
1662 (let ((var (car vars)) (val (car vals)))
1663 (cons (make-gnode var (varset-intersection
1665 (bound-free-variables val)))
1666 (dgraph (cdr vars) (cdr vals))))))
1668 (dgraph vars vals)))
1670 (define (val-of var)
1671 (list-ref vals (- (length vars) (length (memq var vars)))))
1673 (define (bind-in-order order)
1675 (pt-body source body env use)
1677 ; get vars to be bound and vars to be assigned
1679 (let* ((vars-set (car order))
1680 (vars (varset->list vars-set)))
1681 (let loop1 ((l (reverse vars)) (vars-b '()) (vals-b '()) (vars-a '()))
1684 (let* ((var (car l))
1687 (not (varset-intersects? (bound-free-variables val)
1696 (cons var vars-a))))
1699 (let loop2 ((l vars-a))
1702 (let* ((var (car l))
1705 (new-set source env var val)
1708 (bind-in-order (cdr order)))))
1713 (new-call* source env
1727 (new-call* source env
1743 (set-prc-names! vars vals)
1748 (dependency-graph vars vals)))))
1750 (define (pt-begin source env use)
1751 (pt-sequence source (cdr (source-code source)) env use))
1753 (define (pt-do source env use)
1755 (source-code source))
1757 (new-temp-variable source 'do-temp))
1759 (map source-code (source-code (cadr code))))
1761 (new-variables (map car bindings)))
1763 (map (lambda (x) (pt (cadr x) env 'true)) bindings))
1765 (env-frame env (list loop)))
1767 (env-frame inner-env1 vars))
1770 (pt (if (length? x 2) (car x) (caddr x)) inner-env2 'true))
1773 (source-code (caddr code))))
1774 (set-prc-names! vars init)
1775 (new-call* source env
1776 (new-prc source env #f #f (list loop) '() #f #f
1777 (new-call* source inner-env1
1778 (new-ref source inner-env1
1782 (new-prc source env #f #f vars '() #f #f
1783 (new-tst source inner-env2
1784 (pt (car exit) inner-env2 'pred)
1785 (if (length? exit 1)
1786 (new-cst (caddr code) inner-env2 void-object)
1787 (pt-sequence (caddr code) (cdr exit) inner-env2 use))
1788 (if (length? code 3)
1789 (new-call* source inner-env2
1790 (new-ref source inner-env2 loop)
1792 (new-seq source inner-env2
1793 (pt-sequence source (cdddr code) inner-env2 'none)
1794 (new-call* source inner-env2
1795 (new-ref source inner-env2
1799 (define (pt-combination source env use)
1800 (let* ((code (source-code source))
1801 (oper (pt (car code) env 'true)))
1802 (new-call* source env
1804 (map (lambda (x) (pt x env 'true)) (cdr code)))))
1806 (define (pt-delay source env use)
1807 (let ((code (source-code source)))
1808 (new-call* source (add-not-safe env)
1809 (new-ref-extended-bindings source **make-promise-sym env)
1810 (list (new-prc source env #f #f '() '() #f #f
1811 (pt (cadr code) env 'true))))))
1813 (define (pt-future source env use)
1814 (let ((code (source-code source)))
1816 (pt (cadr code) env 'true))))
1818 ;; Expression identification predicates and syntax checking.
1820 (define (self-eval-expr? source)
1821 (let ((code (source-code source)))
1822 (self-evaluating? code)))
1824 (define (self-evaluating? code)
1828 (keyword-object? code)
1829 (false-object? code)
1831 (end-of-file-object? code)
1833 (unbound1-object? code)
1834 (unbound2-object? code)
1835 (optional-object? code)
1838 ;; (body-object? code)
1841 (define (**quote-expr? source)
1842 (match **quote-sym 2 source))
1844 (define (**quasiquote-expr? source)
1845 (match **quasiquote-sym 2 source))
1847 (define (quasiquote-expr? source)
1848 (match quasiquote-sym 2 source))
1850 (define (unquote-expr? source)
1851 (match unquote-sym 2 source))
1853 (define (unquote-splicing-expr? source)
1854 (match unquote-splicing-sym 2 source))
1856 (define (var-expr? source env)
1857 (let ((code (source-code source)))
1858 (and (symbol-object? code)
1859 (not-macro source env code))))
1861 (define (not-macro source env name)
1862 (if (env-lookup-macro env name)
1863 (pt-syntax-error source "Macro name can't be used as a variable:" name)
1866 (define (bindable-var? source env)
1867 (let ((code (source-code source)))
1868 (symbol-object? code)))
1870 (define (**set!-expr? source env)
1871 (match **set!-sym 3 source))
1873 (define (**lambda-expr? source env)
1874 (match **lambda-sym -3 source))
1876 (define (lambda-expr? source env)
1877 (match lambda-sym -3 source))
1879 (define (**if-expr? source)
1880 (and (match **if-sym -3 source)
1881 (or (<= (length (source-code source)) 4)
1882 (ill-formed-special-form source))))
1884 (define (**cond-expr? source)
1885 (and (match **cond-sym -2 source)
1886 (proper-clauses? source)))
1888 (define (**and-expr? source)
1889 (match **and-sym -1 source))
1891 (define (**or-expr? source)
1892 (match **or-sym -1 source))
1894 (define (**case-expr? source)
1895 (and (match **case-sym -3 source)
1896 (proper-case-clauses? source)))
1898 (define (**let-expr? source env)
1899 (and (match **let-sym -3 source)
1900 (let ((code (source-code source)))
1901 (if (bindable-var? (cadr code) env)
1902 (and (proper-bindings? (caddr code) #t env)
1903 (or (> (length code) 3)
1904 (ill-formed-special-form source)))
1905 (proper-bindings? (cadr code) #t env)))))
1907 (define (**let*-expr? source env)
1908 (and (match **let*-sym -3 source)
1909 (proper-bindings? (cadr (source-code source)) #f env)))
1911 (define (**letrec-expr? source env)
1912 (and (match **letrec-sym -3 source)
1913 (proper-bindings? (cadr (source-code source)) #t env)))
1915 (define (**do-expr? source env)
1916 (and (match **do-sym -3 source)
1917 (proper-do-bindings? source env)
1918 (proper-do-exit? source)))
1920 (define (combination-expr? source)
1921 (let ((code (source-code source)))
1923 (let ((length (proper-length code)))
1926 (pt-syntax-error source "Ill-formed procedure call"))
1927 (pt-syntax-error source "Ill-formed procedure call"))))))
1929 (define (**delay-expr? source env)
1930 (and (not (eq? (scheme-dialect env) ieee-scheme-sym))
1931 (match **delay-sym 2 source)))
1933 (define (**future-expr? source env)
1934 (and (eq? (scheme-dialect env) multilisp-sym)
1935 (match **future-sym 2 source)))
1937 (define (macro-expr? source env)
1938 (let ((code (source-code source)))
1940 (symbol-object? (source-code (car code)))
1941 (let ((descr (env-lookup-macro env (source-code (car code)))))
1943 (let ((len (proper-length code)))
1945 (let ((size (##macro-descr-size descr)))
1946 (or (if (> size 0) (= len size) (>= len (- size)))
1947 (ill-formed-special-form source)))
1948 (ill-formed-special-form source))))))))
1950 (define (**begin-cmd-or-expr? source)
1951 (match **begin-sym -1 source))
1953 (define (**begin-expr? source)
1954 (match **begin-sym -2 source))
1956 (define (**define-expr? source env)
1957 (match **define-sym -2 source))
1959 (define (**define-macro-expr? source env)
1960 (match **define-macro-sym -3 source))
1962 (define (**define-syntax-expr? source env)
1963 (match **define-syntax-sym 3 source))
1965 (define (**include-expr? source)
1966 (and (match **include-sym 2 source)
1967 (let ((filename (cadr (source-code source))))
1968 (if (not (string? (source-code filename)))
1969 (pt-syntax-error filename "Filename expected"))
1972 (define (**declare-expr? source)
1973 (match **declare-sym -1 source))
1975 (define (**namespace-expr? source)
1976 (match **namespace-sym -1 source))
1978 ;(define (**require-expr? source)
1979 ;; (and (match **require-sym 2 source)
1980 ;; (let ((module-name (cadr (source-code source))))
1981 ;; (if (not (or (symbol-object? (source-code module-name))
1982 ;; (string? (source-code module-name))))
1983 ;; (pt-syntax-error module-name "Module name expected"))
1986 (define (match head size source)
1987 (let ((code (source-code source)))
1989 (eq? (source-code (car code)) head)
1990 (let ((length (proper-length code)))
1992 (or (if (> size 0) (= length size) (>= length (- size)))
1993 (ill-formed-special-form source))
1994 (ill-formed-special-form source))))))
1996 (define (ill-formed-special-form source)
1999 "Ill-formed special form:"
2000 (let* ((code (source-code source))
2001 (head (source-code (car code)))
2002 (name (symbol->string head))
2003 (len (string-length name)))
2005 (char=? #\# (string-ref name 0))
2006 (char=? #\# (string-ref name 1)))
2007 (string->symbol (substring name 2 len))
2010 (define (proper-length l)
2011 (define (length l n)
2012 (cond ((pair? l) (length (cdr l) (+ n 1)))
2017 (define (definition-name source env)
2018 (let* ((code (source-code source))
2019 (head-source (car code))
2020 (head (source-code head-source))
2021 (pattern-source (cadr code))
2022 (pattern (source-code pattern-source))
2023 (len (proper-length code)))
2024 (if (not (cond ((and (eq? head **define-sym)
2025 (not (pair? pattern)))
2028 ((or (eq? head **define-syntax-sym)
2029 (and (eq? head **define-macro-sym)
2030 (not (pair? pattern))))
2034 (ill-formed-special-form source))
2036 (if (and (not (eq? head **define-syntax-sym))
2041 (source-code name-source)))
2042 (if (not (symbol-object? name))
2043 (pt-syntax-error name-source "Identifier expected"))
2046 (define (definition-value source)
2047 (let ((code (source-code source))
2048 (loc (source-locat source)))
2049 (cond ((pair? (source-code (cadr code)))
2051 (cons (make-source **lambda-sym loc)
2052 (cons (parms->source (cdr (source-code (cadr code))) loc)
2055 ((null? (cddr code))
2057 (list (make-source **quote-sym loc)
2058 (make-source void-object loc))
2063 (define (parms->source parms loc)
2064 (if (or (pair? parms) (null? parms))
2065 (make-source parms loc)
2068 (define (proper-clauses? source)
2070 (define (proper-clauses clauses)
2072 (let* ((clause-source (car clauses))
2073 (clause (source-code clause-source))
2074 (length (proper-length clause)))
2077 (if (eq? (source-code (car clause)) else-sym)
2081 "Else clause must have a body"))
2082 ((not (null? (cdr clauses)))
2085 "Else clause must be last"))
2087 (proper-clauses (cdr clauses))))
2088 (if (and (>= length 2)
2089 (eq? (source-code (cadr clause)) =>-sym)
2093 "'=>' must be followed by a single expression")
2094 (proper-clauses (cdr clauses))))
2095 (pt-syntax-error clause-source "Ill-formed 'cond' clause"))
2096 (pt-syntax-error clause-source "Ill-formed 'cond' clause")))))
2098 (proper-clauses (cdr (source-code source))))
2100 (define (proper-case-clauses? source)
2102 (define (proper-case-clauses clauses)
2104 (let* ((clause-source (car clauses))
2105 (clause (source-code clause-source))
2106 (length (proper-length clause)))
2109 (if (eq? (source-code (car clause)) else-sym)
2110 (if (not (null? (cdr clauses)))
2113 "Else clause must be last")
2114 (proper-case-clauses (cdr clauses)))
2116 (proper-selector-list? (car clause))
2117 (proper-case-clauses (cdr clauses))))
2120 "A 'case' clause must have a selector list and a body"))
2121 (pt-syntax-error clause-source "Ill-formed 'case' clause")))))
2123 (proper-case-clauses (cddr (source-code source))))
2125 (define (proper-selector-list? source)
2126 (let* ((code (source-code source))
2127 (length (proper-length code)))
2132 "Selector list must contain at least one element"))
2133 (pt-syntax-error source "Ill-formed selector list"))))
2135 (define (proper-bindings? bindings check-dupl? env)
2137 (define (proper-bindings l seen)
2139 (let* ((binding-source (car l))
2140 (binding (source-code binding-source)))
2141 (if (eqv? (proper-length binding) 2)
2142 (let ((var (car binding)))
2143 (if (bindable-var? var env)
2144 (if (and check-dupl? (memq (source-code var) seen))
2145 (pt-syntax-error var "Duplicate variable in bindings")
2146 (proper-bindings (cdr l)
2147 (cons (source-code var) seen)))
2148 (pt-syntax-error var "Identifier expected")))
2149 (pt-syntax-error binding-source "Ill-formed binding"))))
2153 (pt-syntax-error bindings "Ill-formed binding list"))))
2155 (proper-bindings (source-code bindings) '()))
2157 (define (proper-do-bindings? source env)
2158 (let ((bindings (cadr (source-code source))))
2160 (define (proper-bindings l seen)
2162 (let* ((binding-source (car l))
2163 (binding (source-code binding-source))
2164 (length (proper-length binding)))
2165 (if (or (eqv? length 2) (eqv? length 3))
2166 (let ((var (car binding)))
2167 (if (bindable-var? var env)
2168 (if (memq (source-code var) seen)
2169 (pt-syntax-error var "Duplicate variable in bindings")
2170 (proper-bindings (cdr l)
2171 (cons (source-code var) seen)))
2174 "Identifier expected")))
2175 (pt-syntax-error binding-source "Ill-formed binding"))))
2179 (pt-syntax-error bindings "Ill-formed binding list"))))
2181 (proper-bindings (source-code bindings) '())))
2183 (define (proper-do-exit? source)
2184 (let* ((exit-source (caddr (source-code source)))
2185 (exit (source-code exit-source))
2186 (length (proper-length exit)))
2187 (if (and length (> length 0))
2189 (pt-syntax-error exit-source "Ill-formed exit clause"))))
2191 (define (begin-body source)
2192 (cdr (source-code source)))
2194 (define (length? l n)
2195 (cond ((null? l) (= n 0))
2196 ((> n 0) (length? (cdr l) (- n 1)))
2199 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2201 ;; Declaration handling:
2202 ;; --------------------
2204 ;; A declaration has the form: (##declare <item1> <item2> ...)
2206 ;; an <item> can be one of 6 types:
2208 ;; - flag declaration : (<id>)
2209 ;; - parameterized declaration : (<id> <parameter>)
2210 ;; - boolean declaration : (<id>) or (not <id>)
2211 ;; - namable declaration : (<id> <name>...)
2212 ;; - namable boolean declaration: (<id> <name>...) or (not <id> <name>...)
2214 (define (transform-declaration source)
2215 (let ((code (source-code source)))
2216 (if (not (pair? code))
2217 (pt-syntax-error source "Ill-formed declaration")
2218 (let* ((pos (not (eq? (source-code (car code)) not-sym)))
2219 (x (if pos code (cdr code))))
2221 (pt-syntax-error source "Ill-formed declaration")
2222 (let* ((id-source (car x))
2223 (id (source-code id-source)))
2225 (cond ((not (symbol-object? id))
2228 "Declaration name must be an identifier"))
2230 ((assq id flag-declarations)
2234 "Declaration can't be negated"))
2238 (cdr (assq id flag-declarations))
2241 (pt-syntax-error source "Ill-formed declaration"))))
2243 ((memq id parameterized-declarations)
2247 "Declaration can't be negated"))
2248 ((eqv? (proper-length x) 2)
2249 (let ((parm (source->expression (cadr x))))
2250 (if (not (and (integer? parm) (exact? parm)))
2251 (pt-syntax-error source "Exact integer expected")
2252 (parameterized-decl source id parm))))
2254 (pt-syntax-error source "Ill-formed declaration"))))
2256 ((memq id boolean-declarations)
2258 (boolean-decl source id pos)
2259 (pt-syntax-error source "Ill-formed declaration")))
2261 ((assq id namable-declarations)
2265 "Declaration can't be negated"))
2269 (cdr (assq id namable-declarations))
2271 (extract-names source (cdr x))))))
2273 ((memq id namable-boolean-declarations)
2274 (namable-boolean-decl
2278 (extract-names source (cdr x))))
2281 (pt-syntax-error id-source "Unknown declaration")))))))))
2283 (define (extract-names source lst)
2285 (define (extract lst)
2287 (let* ((name-source (car lst))
2288 (name (source-code name-source)))
2289 (if (symbol-object? name)
2290 (cons name (extract (cdr lst)))
2291 (pt-syntax-error name-source "Identifier expected"))))
2295 (pt-syntax-error source "Ill-formed declaration"))))
2299 (define (add-declarations source env)
2300 (let loop ((lst (cdr (source-code source))) (env env))
2303 (env-declare env (transform-declaration (car lst))))
2306 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2308 ;; Namespace handling:
2309 ;; ------------------
2311 (define (add-namespace source env)
2312 (let ((code (cdr (source-code source))))
2313 (let loop ((lst code) (env env))
2315 (let* ((form-source (car lst))
2316 (form (source-code form-source)))
2317 (if (not (pair? form))
2318 (pt-syntax-error source "Ill-formed namespace")
2319 (let* ((space-source (car form))
2320 (space (source-code space-source)))
2321 (cond ((not (string? space))
2322 (pt-syntax-error source "Ill-formed namespace"))
2323 ((not (valid-prefix? space))
2324 (pt-syntax-error space-source "Illegal namespace"))
2328 (define (extract lst)
2330 (let* ((name-source (car lst))
2331 (name (source-code name-source)))
2332 (if (symbol-object? name)
2333 (cons name (extract (cdr lst)))
2334 (pt-syntax-error name-source "Identifier expected"))))
2338 (pt-syntax-error source "Ill-formed namespace"))))
2343 (cons space (extract (cdr form)))))))))))
2346 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2351 (define (add-macro source env)
2352 (let ((def-syntax? (**define-syntax-expr? source env)))
2354 (define (form-size parms)
2355 (let loop ((lst parms) (n 1))
2357 (let ((parm (source-code (car lst))))
2358 (if (or (optional-object? parm)
2360 (rest-object? parm))
2369 (define (error-proc . msgs)
2370 (apply compiler-user-error
2371 (cons (source-locat source)
2372 (cons "(in macro body)" msgs))))
2374 (define (make-descr var proc size)
2376 (scheme-global-eval (source->expression proc)
2378 (if (not (procedure? expander))
2379 (pt-syntax-error proc "Macro expander must be a procedure")
2382 (##make-macro-descr def-syntax? size expander proc)))))
2384 (let* ((var (definition-name source env))
2385 (proc (definition-value source)))
2390 (if (or (**lambda-expr? proc env)
2391 (lambda-expr? proc env))
2395 (source->parms (cadr (source-code proc)))))
2396 (pt-syntax-error proc "Macro value must be a lambda expression"))))))
2398 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2400 (define (ptree.begin! info-port) ; initialize module
2401 (set! *ptree-port* info-port)
2402 (set! next-node-stamp (make-counter 0))
2403 (set! temp-variable-stamp (make-counter 0))
2406 (define (ptree.end!) ; finalize module
2407 (set! next-node-stamp #f)
2408 (set! temp-variable-stamp #f)
2411 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2413 ;; Stuff local to the module:
2415 (define *ptree-port* '())
2417 ;;;============================================================================