1; Part of Scheme 48 1.9.  See file COPYING for notices and license.
2
3; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber, Robert Ransom
4
5; Macro expansion.
6
7;----------------
8; Scanning for definitions.
9;
10; Returns a list of forms expanded to the point needed to distinguish
11; definitions from other forms.  Definitions and syntax definitions are
12; added to ENV.
13
14(define (scan-forms forms env)
15  (let loop ((forms forms) (expanded '()))
16    (if (null? forms)
17	(reverse expanded)
18	(let ((form (expand-head (car forms) env))
19	      (more-forms (cdr forms)))
20	  (cond ((define? form)
21		 (loop more-forms
22		       (cons (scan-define form env) expanded)))
23		((define-syntax? form)
24		 (loop more-forms
25		       (append (scan-define-syntax form env)
26			       expanded)))
27		((begin? form)
28		 (loop (append (cdr form) more-forms)
29		       expanded))
30		(else
31		 (loop more-forms (cons form expanded))))))))
32
33(define (expand-scanned-form form env)
34  (if (define? form)
35      (expand-define form env)
36      (expand form env)))
37
38(define (scan-define form env)
39  (let ((new-form (destructure-define form)))
40    (if new-form
41	 (begin
42	   (comp-env-define! env (cadr new-form) usual-variable-type)
43	   new-form)
44	 (syntax-violation 'syntax-rules "ill-formed definition" form))))
45
46(define (expand-define form env)
47  (make-node operator/define
48	     (list (car form)
49		   (expand (cadr form) env)
50		   (expand (caddr form) env))))
51
52(define (scan-define-syntax form env)
53  (if (and (or (this-long? form 3)
54	       (this-long? form 4))  ; may have name list for reifier
55	   (name? (cadr form)))
56      (let ((name (cadr form))
57	    (source (caddr form))
58	    (package (extract-package-from-comp-env env)))
59	(comp-env-define! env
60			  name
61			  syntax-type
62			  (process-syntax (if (null? (cdddr form))
63					      source
64					      `(cons ,source ',(cadddr form)))
65					  env
66					  name
67					  package))
68	'())
69      (syntax-violation 'define-syntax "ill-formed syntax definition" form)))
70
71; This is used by the ,expand command.
72
73(define (expand-form form env)
74  (let loop ((forms (list form)) (expanded '()))
75    (if (null? forms)
76	(if (= (length expanded) 1)
77	    (car expanded)
78	    (make-node operator/begin (cons 'begin (reverse expanded))))
79	(let ((form (expand-head (car forms) env))
80	      (more-forms (cdr forms)))
81	  (cond ((define? form)
82		 (let* ((new-form (destructure-define form))
83			(temp (if new-form
84				  (expand-define new-form env)
85				  (syntax-violation 'expand "ill-formed definition"
86						    form))))
87		   (loop more-forms (cons temp expanded))))
88		((define-syntax? form)
89		 (loop more-forms
90		       (cons (make-node operator/define-syntax
91					(list (car form)
92					      (expand (cadr form) env)
93					      (make-node operator/quote
94							 `',(caddr form))))
95			     expanded)))
96		((begin? form)
97		 (loop (append (cdr form) more-forms)
98		       expanded))
99		(else
100		 (loop more-forms
101		       (cons (expand form env) expanded))))))))
102
103;----------------
104; Looking for definitions.
105; This expands the form until it reaches a name, a form whose car is an
106; operator, a form whose car is unknown, or a literal.
107
108(define (expand-head form env)
109  (cond ((node? form)
110	 (if (and (name-node? form)
111		  (not (node-ref form 'binding)))
112	     (expand-name (node-form form) env)
113	     form))
114	((name? form)
115	 (expand-name form env))
116        ((pair? form)
117	 (let ((op (expand-head (car form) env)))
118	   (if (and (node? op)
119		    (name-node? op))
120	       (let ((probe (node-ref op 'binding)))
121		 (if (binding? probe)
122		     (let ((s (binding-static probe)))
123		       (cond ((and (transform? s)
124				   (eq? (binding-type probe) syntax-type))
125			      (expand-macro-application
126			        s (cons op (cdr form)) env expand-head))
127			     ((and (operator? s)
128				   (eq? s operator/structure-ref))
129			      (expand-structure-ref form env expand-head))
130			     (else
131			      (cons op (cdr form)))))
132		     (cons op (cdr form))))
133	       (cons op (cdr form)))))
134	(else
135	 form)))
136
137; Returns a DEFINE of the form (define <id> <value>).  This handles the following
138; kinds of defines:
139;  (define <id> <value>)
140;  (define <id>)		        ; value is unassigned
141;  (define (<id> . <formals>) <value>)  ; value is a lambda
142; The return value is #f if any syntax error is found.
143
144(define (destructure-define form)
145  (if (at-least-this-long? form 2)
146      (let ((pat (cadr form))
147	    (operator (car form)))
148	(cond ((pair? pat)
149	       (if (and (name? (car pat))
150			(names? (cdr pat))
151			(not (null? (cddr form))))
152		   `(,operator ,(car pat)
153			       (,operator/lambda ,(cdr pat)
154						 . ,(cddr form)))
155		   #f))
156	      ((null? (cddr form))
157	       `(,operator ,pat (,operator/unassigned)))
158	      ((null? (cdddr form))
159	       `(,operator ,pat ,(caddr form)))
160	      (else
161	       #f)))
162      #f))
163
164(define (make-operator-predicate operator-id)
165  (let ((operator (get-operator operator-id syntax-type)))
166    (lambda (form)
167      (and (pair? form)
168	   (eq? operator
169		(static-value (car form)))))))
170
171(define define?        (make-operator-predicate 'define))
172(define begin?         (make-operator-predicate 'begin))
173(define define-syntax? (make-operator-predicate 'define-syntax))
174
175(define (static-value form)
176  (if (and (node? form)
177	   (name-node? form))
178      (let ((probe (node-ref form 'binding)))
179	(if (binding? probe)
180	    (binding-static probe)
181	    #f))
182      #f))
183
184; --------------------
185; The horror of internal defines
186
187; This returns a single node, either a LETREC, if there are internal definitions,
188; or a BEGIN if there aren't any.  If there are no expressions we turn the last
189; definition back into an expression, thus causing the correct warning to be
190; printed by the compiler.
191
192(define (expand-body body env)
193  (if (null? (cdr body))  ;++
194      (expand (car body) env)
195      (call-with-values
196       (lambda ()
197	 (scan-body-forms body env '()))
198       (lambda (defs exps env)
199	 (if (null? defs)
200	     (make-node operator/begin (cons 'begin (expand-list exps env)))
201	     (call-with-values
202	      (lambda ()
203		(if (null? exps)
204		    (values (reverse (cdr defs))
205			    `((,operator/define ,(caar defs) ,(cdar defs))))
206		    (values (reverse defs)
207			    exps)))
208	      (lambda (defs exps)
209		(expand-letrec operator/letrec
210			       (map car defs)
211			       (map cdr defs)
212			       exps
213			       env))))))))
214
215; Walk through FORMS looking for definitions.  ENV is the current environment,
216; DEFS a list of definitions found so far.
217;
218; Returns three values: a list of (define <name> <value>) lists, a list of
219; remaining forms, and the environment to use for expanding all of the above.
220
221(define (scan-body-forms forms env defs)
222  (if (null? forms)
223      (values defs '() env)
224      (let ((form (expand-head (car forms) env))
225	    (more-forms (cdr forms)))
226	(cond ((define? form)
227	       (let ((new-form (destructure-define form)))
228		 (if new-form
229		     (let* ((name (cadr new-form))
230			    (node (make-node operator/name name)))
231		       (scan-body-forms more-forms
232					(bind1 name node env)
233					(cons (cons node
234						    (caddr new-form))
235					      defs)))
236		     (syntax-violation 'scan-body-forms
237				       "ill-formed definition" form))))
238	      ((begin? form)
239	       (call-with-values
240		(lambda ()
241		  (scan-body-forms (cdr form)
242				   env
243				   defs))
244		(lambda (new-defs exps env)
245		  (cond ((null? exps)
246			 (scan-body-forms more-forms env new-defs))
247			((eq? new-defs defs)
248			 (values defs (append exps more-forms) env))
249			(else
250			 (body-lossage forms env))))))
251	      (else
252	       (values defs (cons form more-forms) env))))))
253
254(define (body-lossage node env)
255  (syntax-violation 'body
256		    "definitions and expressions intermixed"
257		    (schemify node env)))
258
259;--------------------
260; Expands all macros in FORM and returns a node.
261
262(define (expand form env)
263  (cond ((node? form)
264	 (if (and (name-node? form)
265		  (not (node-ref form 'binding)))
266	     (expand-name (node-form form) env)
267	     form))
268	((name? form)
269	 (expand-name form env))
270        ((pair? form)
271	 (if (operator? (car form))
272	     (expand-operator-form (car form) (car form) form env)
273	     (let ((op-node (expand (car form) env)))
274	       (if (name-node? op-node)
275		   (let ((probe (node-ref op-node 'binding)))
276		     (if (binding? probe)
277			 (let ((s (binding-static probe)))
278			   (cond ((operator? s)
279				  (expand-operator-form s op-node form env))
280				 ((and (transform? s)
281				       (eq? (binding-type probe) syntax-type))
282				  ;; Non-syntax transforms get done later
283				  (expand-macro-application
284				   s (cons op-node (cdr form)) env expand))
285				 (else
286				  (expand-call op-node form env))))
287			 (expand-call op-node form env)))
288		   (expand-call op-node form env)))))
289	((literal? form)
290	 (expand-literal form))
291	;; ((qualified? form) ...)
292	(else
293	 (syntax-violation 'expand "invalid expression" form))))
294
295(define (expand-list exps env)
296  (map (lambda (exp)
297	 (expand exp env))
298       exps))
299
300(define (expand-literal exp)
301  (make-node operator/literal (make-immutable! exp)))
302
303(define (expand-call proc-node exp env)
304  (if (list? exp)
305      (make-node operator/call
306		 (cons proc-node (expand-list (cdr exp) env)))
307      (syntax-violation 'expand-call "invalid expression" exp)))
308
309; An environment is a procedure that takes a name and returns one of
310; the following:
311;
312;  1. A binding record.
313;  2. A pair (<binding-record> . <path>)
314;  3. A node, which is taken to be a substitution for the name.
315;     Or, for lexically bound variables, this is just a name node.
316;  4. #f, for unbound variables
317;
318; In case 1, EXPAND caches the binding as the node's BINDING property.
319; In case 2, it simply returns the node.
320
321(define (expand-name name env)
322  (let ((binding (lookup env name)))
323    (if (node? binding)
324	binding
325	(let ((node (make-node operator/name name)))
326	  (node-set! node 'binding (or binding 'unbound))
327	  node))))
328
329; Expand a macro.  EXPAND may either be expand or expand-head.
330
331(define (expand-macro-application transform form env-of-use expand)
332  (call-with-values
333   (lambda ()
334     (maybe-apply-macro-transform transform
335				  form
336				  (node-form (car form))
337				  env-of-use))
338   (lambda (new-form new-env)
339     (if (eq? new-form form)
340	 (syntax-violation (schemify (car form) env-of-use)
341			   "use of macro doesn't match definition"
342			   (cons (schemify (car form) env-of-use)
343				 (desyntaxify (cdr form))))
344	 (expand new-form new-env)))))
345
346;--------------------
347; Specialist classifiers for particular operators
348
349(define (expand-operator-form op op-node form env)
350  ((operator-table-ref expanders (operator-uid op))
351   op op-node form env))
352
353(define expanders
354  (make-operator-table (lambda (op op-node form env)
355			 (if (let ((nargs (operator-nargs op)))
356			       (or (not nargs)
357				   (and (list? (cdr form))
358					(= nargs (length (cdr form))))))
359			     (make-node op
360					(cons op-node
361					      (expand-list (cdr form) env)))
362			     (expand-call op-node form env)))))
363
364(define (define-expander name proc)
365  (operator-define! expanders name syntax-type proc))
366
367; Definitions are not expressions.
368
369(define-expander 'define
370  (lambda (op op-node exp env)
371    (syntax-violation 'define
372		      (if (destructure-define exp)
373			  "definition in expression context"
374			  "ill-formed definition")
375		      exp)))
376
377; Remove generated names from quotations.
378
379(define-expander 'quote
380  (lambda (op op-node exp env)
381    (if (this-long? exp 2)
382	(make-node op (list op (desyntaxify (cadr exp))))
383	(syntax-violation 'quote "invalid expression" exp))))
384
385; Don't evaluate, but don't remove generated names either.  This is
386; used when writing macro-defining macros.  Once we have avoided the
387; use of DESYNTAXIFY it is safe to replace this with regular QUOTE.
388
389(define-expander 'code-quote
390  (lambda (op op-node exp env)
391    (if (this-long? exp 2)
392	(make-node operator/quote (list op (cadr exp)))
393	(syntax-violation 'code-quote "invalid expression" exp))))
394
395; Convert one-armed IF to two-armed IF.
396
397(define-expander 'if
398  (lambda (op op-node exp env)
399    (cond ((this-long? exp 3)
400	   (make-node op
401		      (cons op
402			    (expand-list (append (cdr exp)
403						 (list (unspecific-node)))
404					 env))))
405	  ((this-long? exp 4)
406	   (make-node op
407		      (cons op (expand-list (cdr exp) env))))
408	  (else
409	   (syntax-violation 'if "invalid expression" exp)))))
410
411(define (unspecific-node)
412  (make-node operator/unspecific '(unspecific)))
413
414; For the module system:
415
416(define-expander 'structure-ref
417  (lambda (op op-node form env)
418    (expand-structure-ref form env expand)))
419
420; This is also called by EXPAND-HEAD, which passes in a different expander.
421
422(define (expand-structure-ref form env expander)
423  (let ((struct-node (expand (cadr form) env))
424	(lose (lambda ()
425		(syntax-violation 'structure-ref "invalid structure reference" form))))
426    (if (and (this-long? form 3)
427	     (name? (caddr form))
428	     (name-node? struct-node))
429	(let ((b (node-ref struct-node 'binding)))
430	  (if (and (binding? b)
431		   (binding-static b)) ; (structure? ...)
432	      (expander (generate-name (desyntaxify (caddr form))
433				       (binding-static b)
434				       (node-form struct-node))
435			env)
436	      (lose)))
437	(lose))))
438
439; Scheme 48 internal special form principally for use by the
440; DEFINE-STRUCTURES macro.
441
442(define-expander '%file-name%
443  (lambda (op op-node form env)
444    (make-node operator/quote `',(source-file-name env))))
445
446; Checking the syntax of others special forms
447
448(define-expander 'lambda
449  (lambda (op op-node exp env)
450    (if (and (at-least-this-long? exp 3)
451	     (names? (cadr exp)))
452	(expand-lambda (cadr exp) (cddr exp) env)
453	(syntax-violation 'lambda "invalid expression" exp))))
454
455(define (expand-lambda names body env)
456  (call-with-values
457    (lambda ()
458      (bind-names names env))
459    (lambda (names env)
460      (make-node operator/lambda
461		 (list 'lambda names (expand-body body env))))))
462
463(define (bind-names names env)
464  (let loop ((names names) (nodes '()) (out-names '()))
465    (cond ((null? names)
466	   (values (reverse nodes)
467		   (bind out-names nodes env)))
468	  ((name? names)
469	   (let ((last (make-node operator/name names)))
470	     (values (append (reverse nodes) last)
471		     (bind (cons names out-names) (cons last nodes) env))))
472	  (else
473	   (let ((node (make-node operator/name (car names))))
474	     (loop (cdr names) (cons node nodes) (cons (car names) out-names)))))))
475
476(define (names? l)
477  (or (null? l)
478      (name? l)
479      (and (pair? l)
480	   (name? (car l))
481	   (names? (cdr l)))))
482
483(define-expander 'set!
484  (lambda (op op-node exp env)
485    (if (and (this-long? exp 3)
486	     (name? (cadr exp)))
487	(make-node op (cons op (expand-list (cdr exp) env)))
488	(syntax-violation 'set! "invalid expression" exp))))
489
490(define (letrec-expander op/letrec)
491  (lambda (op op-node exp env)
492    (if (and (at-least-this-long? exp 3)
493	     (let-specs? (cadr exp)))
494	(let ((specs (cadr exp))
495	      (body (cddr exp)))
496	  (let* ((names (map (lambda (spec)
497			       (make-node operator/name (car spec)))
498			     specs))
499		 (env (bind (map car specs) names env)))
500	    (expand-letrec op/letrec names (map cadr specs) body env)))
501	(syntax-violation 'letrec "invalid expression" exp))))
502
503(define-expander 'letrec
504  (letrec-expander operator/letrec))
505
506(define-expander 'letrec*
507  (letrec-expander operator/letrec*))
508
509(define (expand-letrec op/letrec names values body env)
510  (let* ((new-specs (map (lambda (name value)
511			   (list name
512				 (expand value env)))
513			 names
514			 values)))
515    (make-node op/letrec
516	       (list 'letrec new-specs (expand-body body env)))))
517
518(define-expander 'loophole
519  (lambda (op op-node exp env)
520    (if (this-long? exp 3)
521	(make-node op (list op
522			    (sexp->type (desyntaxify (cadr exp)) #t)
523			    (expand (caddr exp) env)))
524	(syntax-violation 'loophole "invalid expression" exp))))
525
526(define-expander 'let-syntax
527  (lambda (op op-node exp env)
528    (if (and (at-least-this-long? exp 3)
529	     (let-specs? (cadr exp)))
530	(let ((specs (cadr exp)))
531	  (expand-body (cddr exp)
532		       (bind (map car specs)
533			     (map (lambda (spec)
534				    (make-binding syntax-type
535						  (list 'let-syntax)
536						  (process-syntax (cadr spec)
537								  env
538								  (car spec)
539								  env)))
540				  specs)
541			     env)))
542	(syntax-violation 'let-syntax "invalid expression" exp))))
543
544(define-expander 'letrec-syntax
545  (lambda (op op-node exp env)
546    (if (and (at-least-this-long? exp 3)
547	     (let-specs? (cadr exp)))
548	(let* ((specs (cadr exp))
549	       (bindings (map (lambda (spec)
550				(make-binding syntax-type
551					      (list 'letrec-syntax)
552					      'unassigned))
553			      specs))
554	       (new-env (bind (map car specs) bindings env)))
555	  (for-each (lambda (spec binding)
556		      (set-binding-static! binding
557					   (process-syntax (cadr spec)
558							   new-env
559							   (car spec)
560							   new-env)))
561		    specs bindings)
562	  (expand-body (cddr exp) new-env))
563	(syntax-violation 'letrec-syntax "invalid expression" exp))))
564
565(define (process-syntax form env name env-or-package)
566  (let ((eval+env (force (comp-env-macro-eval env))))
567    (make-transform/macro ((car eval+env) form (cdr eval+env))
568			  env-or-package
569			  syntax-type
570			  form
571			  name)))
572
573; This just looks up the names that the LAP code will want and replaces them
574; with the appropriate node.
575;
576; (lap <id> (<free name> ...) <instruction> ...)
577
578(define-expander 'lap
579  (lambda (op op-node exp env)
580    (if (and (at-least-this-long? exp 4)
581	     (name? (cdr exp))
582	     (every name? (caddr exp)))
583	(make-node op `(,op
584			,(desyntaxify (cadr exp))
585			,(map (lambda (name)
586				(expand-name (cadr exp) env))
587			      (caddr exp))
588			. ,(cdddr exp)))
589	(syntax-violation 'lap "invalid expression" exp))))
590
591; --------------------
592; Syntax checking utilities
593
594(define (this-long? l n)
595  (cond ((null? l)
596	 (= n 0))
597	((pair? l)
598	 (this-long? (cdr l) (- n 1)))
599	(else
600	 #f)))
601
602(define (at-least-this-long? l n)
603  (cond ((null? l)
604	 (<= n 0))
605	((pair? l)
606	 (at-least-this-long? (cdr l) (- n 1)))
607	(else
608	 #f)))
609
610(define (let-specs? x)
611  (or (null? x)
612      (and (pair? x)
613	   (let ((s (car x)))
614	     (and (pair? s)
615		  (name? (car s))
616		  (pair? (cdr s))
617		  (null? (cddr s))))
618	   (let-specs? (cdr x)))))
619
620; --------------------
621; Utilities
622
623(define (literal? exp)
624  (or (number? exp) (char? exp) (string? exp) (boolean? exp)
625      (code-vector? exp)))
626
627(define (syntax? d)
628  (cond ((operator? d)
629	 (eq? (operator-type d) syntax-type))
630	((transform? d)
631	 (eq? (transform-type d) syntax-type))
632	(else #f)))
633