1 ;;; "scaexpp.scm" syntax-case macros
2 ;;; Copyright (C) 1992 R. Kent Dybvig
4 ;;; Permission to copy this software, in whole or in part, to use this
5 ;;; software for any lawful purpose, and to redistribute this software
6 ;;; is granted subject to the restriction that all copies made of this
7 ;;; software must include this copyright notice in full. This software
8 ;;; is provided AS IS, with NO WARRANTY, EITHER EXPRESS OR IMPLIED,
9 ;;; INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY
10 ;;; OR FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE
11 ;;; AUTHORS BE LIABLE FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES OF ANY
12 ;;; NATURE WHATSOEVER.
14 ;;; Written by Robert Hieb & Kent Dybvig
16 ;;; This file was munged by a simple minded sed script since it left
17 ;;; its original authors' hands. See syncase.sh for the horrid details.
20 (letrec ((lambda-var-list (lambda (vars)
21 ((letrec ((lvl (lambda (vars ls)
42 (gen-var (lambda (id) (gen-sym (id-sym-name id))))
43 (gen-sym (lambda (sym)
44 (syncase:new-symbol-hook (symbol->string sym))))
46 (if (syntax-object? x)
47 (strip (syntax-object-expression x))
50 (if (if (eq? a (car x))
60 (if (syncase:andmap eq? old new)
68 (if (memv g000139 '(ref))
69 (syncase:build-lexical-reference (cadr x))
70 (if (memv g000139 '(primitive))
71 (syncase:build-global-reference (cadr x))
72 (if (memv g000139 '(id))
73 (syncase:build-identifier (cadr x))
74 (if (memv g000139 '(quote))
75 (syncase:build-data (cadr x))
83 (syncase:build-application
84 (syncase:build-global-reference
89 (gen-vector (lambda (x)
90 (if (eq? (car x) 'list)
91 (syncase:list* 'vector (cdr x))
92 (if (eq? (car x) 'quote)
95 (list->vector (cadr x)))
96 (list 'list->vector x)))))
97 (gen-append (lambda (x y)
100 (list 'append x y))))
101 (gen-cons (lambda (x y)
102 (if (eq? (car y) 'list)
103 (syncase:list* 'list x (cdr y))
104 (if (if (eq? (car x) 'quote)
109 (cons (cadr x) (cadr y)))
112 (list 'cons x y))))))
113 (gen-map (lambda (e map-env)
114 ((lambda (formals actuals)
115 (if (eq? (car e) 'ref)
119 (if (eq? (car x) 'ref)
126 (list 'primitive (car e))
137 (list 'lambda formals e)
140 (map (lambda (x) (list 'ref (car x)))
142 (gen-ref (lambda (var level maps k)
149 (lambda (outer-var outer-maps)
155 (cons (cons (cons outer-var
160 (assq outer-var (car maps))))))))
161 (chi-syntax (lambda (src exp r w)
162 ((letrec ((gen (lambda (e maps k)
166 (if (eq? (binding-type
175 "missing ellipsis in")
193 "invalid context for ... in")
209 (if (not (eq? g000140
240 (if (not (eq? g000143
284 (if (not (eq? g000146
304 (if (not (eq? g000148
320 (if (not (eq? g000150
356 (lambda (e maps) (regen e)))))
357 (ellipsis? (lambda (x)
358 ;; I dont know what this is supposed to do, and removing it seemed harmless.
359 ;; (if (if (top-level-bound? 'dp) dp #f)
365 (chi-syntax-definition (lambda (e w)
369 (if (not (eq? g000152
396 (chi-definition (lambda (e w)
400 (if (not (eq? g000155
414 (cons '#(syntax-object
436 (if (not (eq? g000158
450 (if (not (eq? g000160
456 (list '#(syntax-object
485 (chi-sequence (lambda (e w)
488 (if (not (eq? g000163 'no))
492 (syntax-error g000164)))
495 '(pair (any) each any)
498 (chi-macro-def (lambda (def r w)
499 (syncase:eval-hook (chi def null-env w))))
500 (chi-local-syntax (lambda (e r w)
504 (if (not (eq? g000165
512 (if (valid-bound-ids?
564 (if (not (eq? g000168
579 (chi-body (lambda (body source r w)
580 (if (null? (cdr body))
582 ((letrec ((parse1 (lambda (body
591 "no expressions in body")
592 ((letrec ((parse2 (lambda (e)
624 '(syntax-definition))
646 (if (valid-bound-ids?
650 ((lambda (new-var-names
654 (syncase:build-letrec
661 (syncase:build-sequence
693 "invalid identifier"))))))))
702 (map (lambda (x) (wrap x w)) body)
707 (syntax-type (lambda (e r w)
708 (if (syntax-object? e)
710 (syntax-object-expression e)
713 (syntax-object-wrap e)
716 (identifier? (car e))
734 (cons 'syntax-definition
735 (chi-syntax-definition
750 (lookup n (car e) r)))
751 (id-var-name (car e) w))
753 (chi-args (lambda (args r w source source-w)
755 (cons (chi (car args) r w)
764 (if (syntax-object? args)
766 (syntax-object-expression
776 (wrap source source-w)))))))
777 (chi-ref (lambda (e name binding w)
779 (if (memv g000172 '(lexical))
780 (syncase:build-lexical-reference name)
783 '(global global-unbound))
784 (syncase:build-global-reference name)
788 (binding-type binding))))
789 (chi-macro (letrec ((check-macro-output (lambda (x)
792 (begin (check-macro-output
802 ((letrec ((g000174 (lambda (i)
806 (begin (check-macro-output
821 "encountered raw symbol")
828 (check-macro-output x)
830 (p (wrap e (join-wraps mw w)))))
832 (chi-pair (lambda (e r w k)
833 ((lambda (first rest)
865 (syncase:build-application
879 (id-var-name first w))
880 (syncase:build-application
882 (chi-args rest r w e w))))
888 (chi-ref e n (lookup n e r) w))
892 (if (syntax-object? e)
893 (chi (syntax-object-expression e)
897 (syntax-object-wrap e)))
898 (if ((lambda (g000176)
912 (syncase:build-data e)
913 (syntax-error (wrap e w))))))))
914 (chi-top (lambda (e r w)
916 (chi-pair e r w chi-top)
917 (if (syntax-object? e)
919 (syntax-object-expression e)
923 (syntax-object-wrap e)))
928 (if (syntax-object? x)
930 (syntax-object-expression x)
933 (syntax-object-wrap x)))
936 (make-syntax-object x w))))))
938 (if (syntax-object? x)
941 (cons (wrap (car e) w)
949 (syntax-object-expression x)
950 (syntax-object-wrap x))
952 (bound-id-member? (lambda (x list)
953 (if (not (null? list))
960 (bound-id=? x (car list)))
962 (valid-bound-ids? (lambda (ids)
963 (if ((letrec ((all-ids? (lambda (ids)
975 ((letrec ((unique? (lambda (ids)
979 (if (not (bound-id-member?
990 (bound-id=? (lambda (i j)
991 (if (eq? (id-sym-name i)
994 (if (eq? (car i) (car j))
999 (id-var-name&marks i empty-wrap)
1000 (id-var-name&marks j empty-wrap))
1002 (free-id=? (lambda (i j)
1003 (if (eq? (id-sym-name i) (id-sym-name j))
1004 (eq? (id-var-name i empty-wrap)
1005 (id-var-name j empty-wrap))
1007 (id-var-name&marks (lambda (id w)
1012 (syntax-object-expression
1016 ((lambda (n&m first)
1019 ((letrec ((search (lambda (rib)
1023 (if (if (eq? (caar rib)
1037 (if ((lambda (g000182)
1051 (id-var-name (lambda (id w)
1056 (syntax-object-expression
1058 (syntax-object-wrap id)))
1060 (car (id-var-name&marks id w))
1061 (id-var-name id (cdr w))))))
1062 (same-marks? (lambda (x y)
1066 (if (eqv? (car x) (car y))
1072 (join-wraps2 (lambda (w1 w2)
1075 (if (if (not (pair? x))
1080 (cons x (join-wraps2 w1 w2))))
1083 (join-wraps1 (lambda (w1 w2)
1087 (join-wraps1 (cdr w1) w2)))))
1088 (join-wraps (lambda (w1 w2)
1093 (if (pair? (car w2))
1095 (join-wraps2 w1 w2))))))
1096 (make-wrap-rib (lambda (ids new-names w)
1099 (cons ((lambda (n&m)
1101 (cons (car new-names)
1110 (make-binding-wrap (lambda (ids new-names w)
1113 (cons (make-wrap-rib
1118 (new-mark-wrap (lambda ()
1121 (list current-mark)))
1125 (id-sym-name (lambda (x)
1128 (syntax-object-expression x))))
1133 (if (syntax-object? x)
1135 (syntax-object-expression x))
1138 (global-extend (lambda (type sym val)
1142 (lookup (lambda (name id r)
1143 (if (eq? name (id-sym-name id))
1144 (global-lookup name)
1145 ((letrec ((search (lambda (r name)
1147 '(displaced-lexical)
1165 (extend-syntax-env (lambda (vars vals r)
1168 (cons (cons (car vars)
1175 (extend-var-env append)
1176 (extend-macro-env (lambda (vars vals r)
1179 (cons (cons (car vars)
1187 (global-lookup (lambda (sym)
1192 (syncase:get-global-definition-hook sym))))
1193 (extend-global-env (lambda (sym binding)
1194 (syncase:put-global-definition-hook
1199 (arg-check (lambda (pred? x who)
1201 (syncase:error-hook who "invalid argument" x)
1203 (id-error (lambda (x)
1206 "invalid context for identifier")))
1207 (scope-error (lambda (id)
1210 "invalid context for bound identifier")))
1211 (syntax-object-wrap (lambda (x) (vector-ref x 2)))
1212 (syntax-object-expression (lambda (x) (vector-ref x 1)))
1213 (make-syntax-object (lambda (expression wrap)
1218 (syntax-object? (lambda (x)
1220 (if (= (vector-length x) 3)
1221 (eq? (vector-ref x 0)
1225 (global-extend 'core 'letrec-syntax chi-local-syntax)
1226 (global-extend 'core 'let-syntax chi-local-syntax)
1233 (if (not (eq? g000135 'no))
1234 ((lambda (__ _e) (syncase:build-data (strip _e)))
1239 (if (not (eq? g000137 'no))
1241 (syntax-error (wrap e w)))
1243 (syntax-error g000138)))
1251 '(pair (any) pair (any) atom)
1260 (if (not (eq? g000131 'no))
1261 ((lambda (__ _x) (chi-syntax e _x r w))
1266 (if (not (eq? g000133 'no))
1268 (syntax-error (wrap e w)))
1270 (syntax-error g000134)))
1278 '(pair (any) pair (any) atom)
1288 (if (not (eq? g000126 'no))
1289 ((lambda (__ _id _level _exp)
1290 (if (if (valid-bound-ids? _id)
1298 (map unwrap _level))
1301 (syncase:build-lambda
1324 (each pair (any) pair (any) atom)
1332 (if (not (eq? g000129 'no))
1334 (syntax-error (wrap e w)))
1336 (syntax-error g000130)))
1349 (if (not (eq? g000120 'no))
1350 ((lambda (__ _id _e1 _e2)
1351 (if (not (valid-bound-ids? _id))
1354 "invalid parameter list")
1356 (syncase:build-lambda
1368 (map gen-var _id))))
1375 (if (not (eq? g000122 'no))
1376 ((lambda (__ _ids _e1 _e2)
1378 (if (not (valid-bound-ids?
1383 "invalid parameter list")
1385 (syncase:build-improper-lambda
1402 (lambda-var-list _ids)))
1409 (if (not (eq? g000124
1451 (if (not (eq? g000115 'no))
1453 (lambda (__ _id _val _e1 _e2)
1454 (if (valid-bound-ids? _id)
1457 (syncase:build-letrec
1484 (each pair (any) pair (any) atom)
1493 (if (not (eq? g000118 'no))
1495 (syntax-error (wrap e w)))
1497 (syntax-error g000119)))
1510 (if (not (eq? g000109 'no))
1511 ((lambda (__ _test _then)
1512 (syncase:build-conditional
1515 (chi (list '#(syntax-object
1525 (if (not (eq? g000111 'no))
1526 ((lambda (__ _test _then _else)
1527 (syncase:build-conditional
1537 (if (not (eq? g000113
1564 '(pair (any) pair (any) pair (any) atom)
1574 (if (not (eq? g000103 'no))
1575 ((lambda (__ _id _val)
1582 (syncase:build-lexical-assignment
1589 (syncase:build-global-assignment
1599 (id-var-name _id w))
1607 '(pair (any) pair (any) pair (any) atom)
1612 (if (not (eq? g000106 'no))
1614 (syntax-error (wrap e w)))
1616 (syntax-error g000107)))
1629 (if (eqv? k chi-top)
1630 (chi (list '#(syntax-object syncase:void (top)))
1635 "no expressions in body of"))
1636 (syncase:build-sequence
1637 ((letrec ((dobody (lambda (body)
1649 (chi-sequence e w))))
1654 (if (eqv? k chi-top)
1657 (global-extend 'global n '())
1658 (syncase:build-global-definition
1660 (chi (cadr n&v) r empty-wrap)))
1661 (id-var-name (car n&v) empty-wrap)))
1662 (chi-definition e w))
1665 "invalid context for definition"))))
1670 (if (eqv? k chi-top)
1674 (id-var-name (car n&v) empty-wrap)
1675 (chi-macro-def (cadr n&v) r empty-wrap))
1676 (chi (list '#(syntax-object syncase:void (top)))
1679 (chi-syntax-definition e w))
1682 "invalid context for definition"))))
1684 (lambda (x) (chi-top x null-env top-wrap)))
1685 (set! implicit-identifier
1687 (arg-check id? id 'implicit-identifier)
1688 (arg-check symbol? sym 'implicit-identifier)
1689 (if (syntax-object? id)
1690 (wrap sym (syntax-object-wrap id))
1692 (set! syntax-object->datum (lambda (x) (strip x)))
1693 (set! generate-temporaries
1695 (arg-check list? ls 'generate-temporaries)
1696 (map (lambda (x) (wrap (syncase:new-symbol-hook "g") top-wrap)) ls)))
1697 (set! free-identifier=?
1699 (arg-check id? x 'free-identifier=?)
1700 (arg-check id? y 'free-identifier=?)
1702 (set! bound-identifier=?
1704 (arg-check id? x 'bound-identifier=?)
1705 (arg-check id? y 'bound-identifier=?)
1707 (set! identifier? (lambda (x) (id? x)))
1709 (lambda (object . messages)
1711 (lambda (x) (arg-check string? x 'syntax-error))
1714 (syncase:error-hook 'expand-syntax message (strip object)))
1715 (if (null? messages)
1717 (apply string-append messages)))))
1718 (set! syncase:install-global-transformer
1719 (lambda (sym p) (global-extend 'macro sym p)))
1721 (letrec ((match (lambda (e p k w r)
1725 (if (memv g000100 '(any))
1730 (if (if (identifier?
1744 (syntax-object-expression
1760 (match* (lambda (e p k w r)
1762 (if (memv g000101 '(pair))
1776 (if (memv g000101 '(each))
1777 (if (eq? (cadr p) 'any)
1793 ((letrec ((collect (lambda (l)
1830 (syncase:void)))))))
1832 (match-empty (lambda (p r)
1834 (if (memv g000102 '(any))
1862 (syncase:void))))))))
1864 (match-each-any (lambda (e w)
1880 (syntax-object-expression
1887 (match-each (lambda (e p k w)
1903 (match (car e) p k w '()))
1906 (if (syntax-object? e)
1908 (syntax-object-expression
1917 (set! syntax-dispatch
1918 (lambda (expression pattern keys)
1925 (syncase:install-global-transformer
1931 (if (not (eq? g00094 'no))
1933 (lambda (__ _x _v _e1 _e2)
1934 (if (syncase:andmap identifier? _x)
1935 (cons (cons '#(syntax-object
1948 (each pair (any) pair (any) atom)
1958 (if (not (eq? g00097 'no))
1960 (lambda (__ _f _x _v _e1 _e2)
1964 (cons (list '#(syntax-object
1968 (cons '#(syntax-object
1985 (each pair (any) pair (any) atom)
1991 (lambda () (syntax-error g00098))))
1994 (syncase:install-global-transformer
1997 (letrec ((syncase:build-dispatch-call (lambda (args body val)
2000 (if (not (eq? g00045
2005 (if (not (eq? g00047
2010 (if (not (eq? g00065
2014 (list (list '#(syntax-object
2019 (list '#(syntax-object
2039 (if (not (eq? g00049
2045 (if (not (eq? g00063
2049 (list (list '#(syntax-object
2055 (list '#(syntax-object
2059 (list '#(syntax-object
2080 (if (not (eq? g00051
2087 (if (not (eq? g00061
2091 (list (list '#(syntax-object
2098 (list '#(syntax-object
2102 (list '#(syntax-object
2106 (list '#(syntax-object
2129 (if (not (eq? g00053
2137 (if (not (eq? g00059
2141 (list (list '#(syntax-object
2149 (list '#(syntax-object
2153 (list '#(syntax-object
2157 (list '#(syntax-object
2161 (list '#(syntax-object
2186 (if (not (eq? g00055
2191 (if (not (eq? g00057
2195 (list '#(syntax-object
2198 (list '#(syntax-object
2266 (extract-bound-syntax-ids (lambda (pattern keys)
2267 ((letrec ((gen (lambda (p
2281 (if (not (eq? g00067
2305 (if (not (eq? g00070
2318 (if (not (eq? g00072
2327 (if (not (eq? g00074
2357 (valid-syntax-pattern? (lambda (pattern keys)
2358 (letrec ((check? (lambda (p
2368 (if (if (not (ellipsis?
2380 (if (not (eq? g00076
2403 (if (not (eq? g00079
2416 (if (not (eq? g00081
2425 (if (not (eq? g00083
2455 (valid-keyword? (lambda (k)
2457 (not (free-identifier=?
2461 (convert-syntax-dispatch-pattern (lambda (pattern
2463 ((letrec ((gen (lambda (p)
2468 (cons '#(syntax-object
2474 (list '#(syntax-object
2480 (if (not (eq? g00085
2486 (cons '#(syntax-object
2504 (if (not (eq? g00088
2508 (cons '#(syntax-object
2517 (if (not (eq? g00090
2520 (cons '#(syntax-object
2527 (if (not (eq? g00092
2530 (cons '#(syntax-object
2558 (key-index (lambda (p keys)
2560 (length (memid p keys)))))
2561 (key? (lambda (p keys)
2562 (if (identifier? p) (memid p keys) #f)))
2563 (memid (lambda (i ids)
2564 (if (not (null? ids))
2565 (if (bound-identifier=? i (car ids))
2567 (memid i (cdr ids)))
2569 (ellipsis? (lambda (x)
2571 (free-identifier=? x '...)
2577 (if (not (eq? g00029 'no))
2578 ((lambda (__ _val _key)
2579 (if (syncase:andmap valid-keyword? _key)
2580 (list '#(syntax-object
2602 (if (not (eq? g00032 'no))
2609 (if (if (identifier?
2616 (not (free-identifier=?
2623 (list (list '#(syntax-object
2641 (pair (any) pair (any) atom)
2648 (if (not (eq? g00035 'no))
2658 (if (if (syncase:andmap
2661 (valid-syntax-pattern?
2667 (if (not (eq? g00043
2672 (list '#(syntax-object
2675 (list (list '#(syntax-object
2679 (list '#(syntax-object
2683 (list '#(syntax-object
2689 (list '#(syntax-object
2693 (list '#(syntax-object
2698 (list '#(syntax-object
2701 (list '#(syntax-object
2704 (list '#(syntax-object
2708 (list '#(syntax-object
2715 (cons '#(syntax-object
2718 (cons '#(syntax-object
2746 (list (convert-syntax-dispatch-pattern
2752 (syncase:build-dispatch-call
2753 (extract-bound-syntax-ids
2787 (if (not (eq? g00038
2799 (if (if (syncase:andmap
2802 (valid-syntax-pattern?
2808 (if (not (eq? g00041
2814 (list '#(syntax-object
2817 (list (list '#(syntax-object
2821 (list '#(syntax-object
2825 (list '#(syntax-object
2829 (cons '#(syntax-object
2832 (cons '#(syntax-object
2845 (list '#(syntax-object
2849 (list '#(syntax-object
2855 (list '#(syntax-object
2859 (list '#(syntax-object
2864 (list '#(syntax-object
2867 (list '#(syntax-object
2870 (list '#(syntax-object
2874 (list '#(syntax-object
2901 (list (convert-syntax-dispatch-pattern
2910 (syncase:build-dispatch-call
2911 (extract-bound-syntax-ids
2914 (list '#(syntax-object
2919 (list '#(syntax-object