mac-test.scm 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  1. (test-init "macros" 127)
  2. (test 'ok 'letxx (let ((xx #f)) (cond (#t xx 'ok))))
  3. (test 'ok 'let=> (let ((=> #f)) (cond (#t => 'ok))))
  4. (begin-for-syntax
  5. (load (string-append src-prefix "mac1.scm")))
  6. (test '(1 2) 'something (something 1 2))
  7. (test '(2 3) 'something (something 2 3))
  8. ;;; From Common Lisp the Language 2nd ed page 198
  9. (defmacro arithmetic-if (test neg-form zero-form pos-form)
  10. (let ((var (gentemp)))
  11. `(let ((,var ,test))
  12. (cond ((< , var 0) ,neg-form)
  13. ((= ,var 0) ,zero-form)
  14. (#t ,pos-form)))))
  15. (test "POS" 'arithmetic-if-pos (arithmetic-if 234 "NEG" "ZERO" "POS"))
  16. (test "NEG" 'arithmetic-if-pos (arithmetic-if -234 "NEG" "ZERO" "POS"))
  17. ;;; Posted to comp.lang.scheme by mooreb@lark.cc.ukans.edu (Brian M. Moore)
  18. (test '(x) 'lambda*3
  19. ((lambda lambda lambda) 'x))
  20. (test '(1 2 3) 'lambda-begin
  21. ((lambda (begin) (begin 1 2 3)) (lambda lambda lambda)))
  22. ;;; From R5RS:
  23. (test 'now 'let-syntax-1
  24. (let-syntax
  25. ((when (syntax-rules ()
  26. ((when test stmt1 stmt2 ...)
  27. (if test
  28. (begin stmt1 stmt2 ...))))))
  29. (let ((if #t))
  30. (when if (set! if 'now))
  31. if)))
  32. ;;; From R5RS:
  33. (test 'outer 'let-syntax-2
  34. (let ((x 'outer))
  35. (let-syntax ((m (syntax-rules () ((m) x))))
  36. (let ((x 'inner))
  37. (m))))) ; => outer
  38. ;;; Based on an example Listed as an "error" in R5RS.
  39. ;;; (We don't actually complain about the erroneous version.)
  40. (test 6 'let-syntax-3
  41. (let-syntax
  42. ((foo (syntax-rules ()
  43. ((foo (proc args ...) body ...)
  44. (define proc
  45. (lambda (args ...)
  46. body ...))))))
  47. (let ((x 3))
  48. (foo (plus x y) (+ x y))
  49. (let () ;; Added this extra let to make it legit.
  50. (define foo x)
  51. (plus foo x)))))
  52. ;;; From R5RS:
  53. (test 7 'letrec-syntax-1
  54. (letrec-syntax
  55. ((my-or (syntax-rules ()
  56. ((my-or) #f)
  57. ((my-or e) e)
  58. ((my-or e1 e2 ...)
  59. (let ((temp e1))
  60. (if temp
  61. temp
  62. (my-or e2 ...)))))))
  63. (let ((x #f)
  64. (y 7)
  65. (temp 8)
  66. (let odd?)
  67. (if even?))
  68. (my-or x
  69. (let temp)
  70. (if y)
  71. y))))
  72. (define (internal-define-syntax)
  73. (let ()
  74. (define-syntax ten (syntax-rules () ((ten) 10)))
  75. (define x (ten))
  76. x))
  77. (test 10 internal-define-syntax)
  78. ;; Based on bug report from Stephen L. Peters <portnoy@portnoy.org>:
  79. (define-syntax test-ds1 (syntax-rules () ((test-ds1 x) (list 'x))))
  80. (test '((t1)) 'test-ds1 (test-ds1 (t1)))
  81. (test '((t2)) 'test-ds2
  82. (begin
  83. (define-syntax test-ds2 (syntax-rules () ((test-ds2 x) (list 'x))))
  84. (test-ds2 (t2))))
  85. (define x 1)
  86. (define y 2)
  87. (define z 3)
  88. (define-syntax test-ds3
  89. (syntax-rules () ((test-ds3 x y) (let ((y x) (x z) (z y)) (list x y z)))))
  90. (test '(3 2 3) 'test-ds3 (test-ds3 y z))
  91. (test '() 'cut-1 ((cut list)))
  92. (test '() 'cut-2 ((cut list <...>)))
  93. (test '(1) 'cut-3 ((cut list 1)))
  94. (test '(1) 'cut-4 ((cut list <>) 1))
  95. (test '(1) 'cut-5 ((cut list <...>) 1))
  96. (test '(1 2) 'cut-6 ((cut list 1 2)))
  97. (test '(1 2) 'cut-7 ((cut list 1 <>) 2))
  98. (test '(1 2) 'cut-8 ((cut list 1 <...>) 2))
  99. (test '(1 2 3 4) 'cut-9 ((cut list 1 <...>) 2 3 4))
  100. (test '(1 2 3 4) 'cut-10 ((cut list 1 <> 3 <>) 2 4))
  101. (test '(1 2 3 4 5 6) 'cut-11 ((cut list 1 <> 3 <...>) 2 4 5 6))
  102. (test '(ok) 'cut-12 (let* ((x 'wrong) (y (cut list x))) (set! x 'ok) (y)))
  103. (test 2 'cut-13
  104. (let ((a 0))
  105. (map (cut + (begin (set! a (+ a 1)) a) <>)
  106. '(1 2))
  107. a))
  108. ;; cutes
  109. (test '() 'cute-1 ((cute list)))
  110. (test '() 'cute-2 ((cute list <...>)))
  111. (test '(1) 'cute-3 ((cute list 1)))
  112. (test '(1) 'cute-4 ((cute list <>) 1))
  113. (test '(1) 'cute-5 ((cute list <...>) 1))
  114. (test '(1 2) 'cute-6 ((cute list 1 2)))
  115. (test '(1 2) 'cute-7 ((cute list 1 <>) 2))
  116. (test '(1 2) 'cute-8 ((cute list 1 <...>) 2))
  117. (test '(1 2 3 4) 'cute-9 ((cute list 1 <...>) 2 3 4))
  118. (test '(1 2 3 4) 'cute-10 ((cute list 1 <> 3 <>) 2 4))
  119. (test '(1 2 3 4 5 6) 'cute-11 ((cute list 1 <> 3 <...>) 2 4 5 6))
  120. (test 1 'cute-12
  121. (let ((a 0))
  122. (map (cute + (begin (set! a (+ a 1)) a) <>)
  123. '(1 2))
  124. a))
  125. (define-syntax test-set
  126. (syntax-rules ()
  127. ((test-set)
  128. (let ((s 1))
  129. (set! s (+ s 1))
  130. s))))
  131. (test 2 'test-set (test-set))
  132. (define-syntax test-colon
  133. (syntax-rules ()
  134. ((test-colon x)
  135. (let loop ((size :: <int> 10))
  136. (+ size x)))))
  137. (test 14 'test-colon (test-colon 4))
  138. ;; Bug reported by 2003-05-22 by Bruce R. Lewis <brlewis@ALUM.MIT.EDU>.
  139. (define-syntax one
  140. (syntax-rules ()
  141. ((one var)
  142. (begin
  143. (define extra 1)
  144. (define var extra)))))
  145. (one xx1)
  146. (test 1 'one xx1)
  147. ;; Bug reported by 2003-05-22 by Bruce R. Lewis <brlewis@ALUM.MIT.EDU>.
  148. (define-syntax lit1
  149. (syntax-rules (literal)
  150. ((lit1 literal)
  151. "worked")
  152. ((lit1 a)
  153. (lit1 literal))))
  154. (test "worked" 'lit1 (lit1 20))
  155. ;; Based on bug reported 2003-05-19 by Sven.Hartrumpf@FernUni-Hagen.de
  156. (test "no-bogus-feature" 'cond-expand-not-1
  157. (cond-expand ((not bogus-feature)
  158. "no-bogus-feature")
  159. (else "has-bogus-feature")))
  160. (test "has-srfi-4" 'cond-expand-not-2
  161. (cond-expand ((not srfi-4)
  162. "no-srfi-4")
  163. (else "has-srfi-4")))
  164. ;; Based on bug reported 2003-06-01 by Sven.Hartrumpf@FernUni-Hagen.de
  165. (cond-expand (kawa
  166. (define found-kawa-feature "yes"))
  167. (else
  168. (define found-kawa-feature "no")))
  169. (test "yes" 'found-kawa-feature found-kawa-feature)
  170. ;; Based on bug reported 2003-06-02 by Sven.Hartrumpf@FernUni-Hagen.de
  171. (cond-expand
  172. ((not no-such-srfi)
  173. (define third caddr))
  174. (else))
  175. (test 'z third '(x y z))
  176. (test 1 'test-class-exists-1
  177. (cond-expand (class-exists:java.lang.StringBuilder 1) (else 0)))
  178. (test 0 'test-class-exists-2
  179. (cond-expand (class-exists:java.lang.StringMunger 1) (else 0)))
  180. (define-syntax or-with-keyword-test
  181. (syntax-rules (default-value:)
  182. ((or-with-keyword-test val default-value: default)
  183. (if val
  184. val
  185. default))
  186. ((or-with-keyword-test val)
  187. (or-with-keyword-test default-value: #f))))
  188. (test 'ok 'or-with-keyword-test (or-with-keyword-test #f default-value: 'ok))
  189. ;; Al Petrofsky posting to comp.lang.scheme 2002-03-03:
  190. (test "(1 2 3 a)" 'letrec-test
  191. (format #f "~S"
  192. (let ((a 1))
  193. (letrec-syntax
  194. ((foo (syntax-rules ()
  195. ((_ b)
  196. (bar a b))))
  197. (bar (syntax-rules ()
  198. ((_ c d)
  199. (cons c (let ((c 3))
  200. (list d c 'c)))))))
  201. (let ((a 2))
  202. (foo a))))))
  203. ;; A posting by Taylor Campell to comp.lang.scheme 2004/10/9:
  204. (test #(1 2 unquote (list 3 4)) 'unquote-vector `#(1 2 unquote (list 3 4)))
  205. ;; Example in Dybvig's "The Scheme Programming Language" 3rd ed chapter 8:
  206. (test #t 'dybvig-SchemePL3-8Syntax-ex1
  207. (let ()
  208. (define even? (lambda (x) (or (= x 0) (odd? (- x 1)))))
  209. (define-syntax odd? (syntax-rules () ((_ x) (not (even? x)))))
  210. (even? 10)))
  211. ;; Example in Dybvig's "The Scheme Programming Language" 3rd ed chapter 8:
  212. (test 0 'dybvig-SchemePL3-8Syntax-ex2
  213. (let ()
  214. (define-syntax bind-to-zero
  215. (syntax-rules () ((_ id) (define id 0))))
  216. (bind-to-zero x)
  217. x))
  218. (test '(1 2) 'dybvig-SchemePL3-8Syntax-ex3
  219. (let ((f (lambda (x) (+ x 1))))
  220. (let-syntax ((f (syntax-rules () ((_ x) x)))
  221. (g (syntax-rules () ((_ x) (f x)))))
  222. (list (f 1) (g 1)))))
  223. (test '(1 1) 'dybvig-SchemePL3-8Syntax-ex4
  224. (with-compile-options
  225. warn-unused: #f
  226. (let ((f (lambda (x) (+ x 1))))
  227. (letrec-syntax ((f (syntax-rules () ((_ x) x)))
  228. (g (syntax-rules () ((_ x) (f x)))))
  229. (list (f 1) (g 1))))))
  230. ;; Savannah bug report #10561 from Chris Dean
  231. (define-syntax log-mode
  232. (syntax-rules ()
  233. ((log-mode mode)
  234. (case 'mode
  235. ((error) "error mode")
  236. ((warning) "warning mode")
  237. (else "bad mode")))))
  238. (test "warning mode" 'log-mode (log-mode warning))
  239. ;; Savannah bug report #9483
  240. (define-syntax macro-chain
  241. (syntax-rules ()
  242. ((macro-chain . z)
  243. (letrec-syntax
  244. ((m1 (syntax-rules () ((m1 x) (id (m2 x)))))
  245. (m2 (syntax-rules () ((m2 x) (id (m3 x)))))
  246. (m3 (syntax-rules () ((m3 x) (quote x))))
  247. (id (syntax-rules () ((id x) x))))
  248. (m1 z)))))
  249. (test '(1) 'macro-chain (macro-chain 1))
  250. ;; From FLT MzScheme Manual section 12.3.5 Macro-Gnerated Top-Level
  251. (define-syntax def-and-use-of-x
  252. (syntax-rules ()
  253. ((def-and-use-of-x val)
  254. ; x below originates from this macro:
  255. (begin (define x val) x))))
  256. (define x1 1)
  257. (test 2 'mzscheme-lang-12.3.5-1 (def-and-use-of-x 2))
  258. (test 1 'mzscheme-lang-12.3.5-2 x1)
  259. ;; From FLT MzScheme Manual section 12.3.5 Macro-Generated Top-Level
  260. (define-syntax def-and-use
  261. (syntax-rules ()
  262. ((def-and-use x val)
  263. ; x below was provided by the macro use:
  264. (begin (define x val) x))))
  265. (set! x 2)
  266. (test 3 'mzscheme-lang-12.3.5-3 (def-and-use x 3))
  267. (set! fail-expected "mzscheme-lang-12.3.5-4 is 2 but should be 3")
  268. ;; Note this works if def-and-use uses set! instead of define.
  269. ;; Probably chalk this up to Kawa's top-level define being different.
  270. (test 3 'mzscheme-lang-12.3.5-4 x)
  271. ;; Example from Chez Scheme User's Guide by Kent Dybvig:
  272. (define-syntax loop
  273. (lambda (x)
  274. (syntax-case x ()
  275. ((k e ...)
  276. (with-syntax ((break (datum->syntax #'k 'break)))
  277. #'(call-with-current-continuation
  278. (lambda (break)
  279. (let f () e ... (f)))))))))
  280. (test '(a a a) 'test-loop-macro
  281. (let ((n 3) (ls '()))
  282. (loop
  283. (if (= n 0) (break ls))
  284. (set! ls (cons 'a ls))
  285. (set! n (- n 1)))))
  286. ;; Based on SRFI-57 reference implementation by Andre van Tonder.
  287. (define-syntax top:if-free=
  288. (syntax-rules ()
  289. ((top:if-free= x y kt kf)
  290. (begin
  291. (define-syntax if-free=:test
  292. (syntax-rules (x)
  293. ((if-free=:test x kt* kf*) kt*)
  294. ((if-free=:test z kt* kf*) kf*)))
  295. (if-free=:test y kt kf)))))
  296. (define-syntax free=
  297. (syntax-rules ()
  298. ((free= x y)
  299. (let () (top:if-free= x y #t #f)))))
  300. (test '(#t #f #t #f) 'test-free=
  301. (list (free= x x) (free= y x) (free= abba abba) (free= y x)))
  302. (define-syntax check-matching
  303. (syntax-rules ()
  304. ((check-matching 1 #(a b c)) (list c #(b a)))
  305. ((check-matching 2 #(a b ... c)) (list c b ... a))
  306. ((check-matching 3 a b ... c) #(c b ... a))
  307. ((check-matching 4 a b c ...) (list a b c ...))
  308. ((check-matching 5 a b c ... z) (list a b c ... 'last z))
  309. ((check-matching 6 a b c ... z . r) (list a b c ... 'last z 'cdr r))
  310. ((check-matching 7 a 1 ... 1 . r) (list a 'cdr r))
  311. ((check-matching 8 (a ...) ... (r ...))
  312. (list (+ a ...) ... 'R r ... 'F (+ a ... ...)))
  313. ((check-matching 9 (a ...) ...) (list #(A a ... ... Z) '(A a ... ... Z)))
  314. ((check-matching a . b) "no-match")
  315. ))
  316. (test '(3 #(2 1)) 'check-matching-1 (check-matching 1 #(1 2 3)))
  317. (test "no-match" 'check-matching-2a (check-matching 2 1 2 3 4 5))
  318. (test '(5 2 3 4 1) 'check-matching-2 (check-matching 2 #(1 2 3 4 5)))
  319. (test #(5 2 3 4 1) 'check-matching-3 (check-matching 3 1 2 3 4 5))
  320. (test "no-match" 'check-matching-4a (check-matching 4 1))
  321. (test '(1 2) 'check-matching-4b (check-matching 4 1 2))
  322. (test '(1 2 3) 'check-matching-4c (check-matching 4 1 2 3))
  323. (test '(1 2 3 4) 'check-matching-4d (check-matching 4 1 2 3 4))
  324. (test "no-match" 'check-matching-5a (check-matching 5 1))
  325. (test "no-match" 'check-matching-5b (check-matching 5 1 2))
  326. (test '(1 2 last 3) 'check-matching-5c (check-matching 5 1 2 3))
  327. (test '(1 2 3 last 4) 'check-matching-5d (check-matching 5 1 2 3 4))
  328. (test '(1 2 3 4 last 5) 'check-matching-5e (check-matching 5 1 2 3 4 5))
  329. (test '(1 2 3 last 4 cdr 5) 'check-matching-6a (check-matching 6 1 2 3 4 . 5))
  330. (test '(1 2 3 4 last 5 cdr ()) 'check-matching-6b (check-matching 6 1 2 3 4 5))
  331. (test '(10 cdr ()) 'check-matching-7a (check-matching 7 10 1 1 1))
  332. (test '(10 cdr 100) 'check-matching-7b (check-matching 7 10 1 1 1 . 100))
  333. (test '(10 cdr 100) 'check-matching-7c (check-matching 7 10 1 . 100))
  334. (test "no-match" 'check-matching-7d (check-matching 7 10 . 100))
  335. (test '(3 12 R 8 9 F 15)
  336. 'check-matching-8 (check-matching 8 (1 2) (3 4 5) (8 9)))
  337. (test '(#(A 1 2 3 4 5 Z) (A 1 2 3 4 5 Z))
  338. 'check-matching-9 (check-matching 9 (1 2) (3 4 5)))
  339. ;; Savannah bug #13821
  340. (define-macro (test-13821 #!key (args ()))
  341. (letrec ((double (lambda (x) (* x 2))))
  342. `(+ ,@(map double args))))
  343. (test 12 'test-13821 (test-13821 args: (1 2 3)))
  344. ;; Savannah bug #14097
  345. (define-syntax slot
  346. (syntax-rules ()
  347. ((_ obj slotname)
  348. (field obj (quote slotname)))
  349. ((_ slotname)
  350. (field (this) (quote slotname)))))
  351. (define-simple-class <xclass> ()
  352. (x init: 0)
  353. ((incx) ::void
  354. (set! (slot x) (+ 1 (slot x))))
  355. ((incx2) ::void
  356. (set! (slot (this) x) (+ 1 (slot (this) x)))))
  357. (define xinstance (make <xclass>))
  358. (with-compile-options warn-invoke-unknown-method: #f
  359. (invoke xinstance 'incx))
  360. (test 1 'xclass (slot xinstance x))
  361. (define x (list "X1" "X2"))
  362. (define y (list "Y1" "Y2"))
  363. ;; See Bawden: Quasiquotation in Lisp (1999), Appendix B.
  364. (test '(a ("X1" "X2") ("Y1" "Y2") b) 'unquote-1
  365. (quasiquote (a (unquote x y) b)))
  366. (test '(a "X1" "X2" "Y1" "Y2" b) 'unquote-2
  367. (quasiquote (a (unquote-splicing x y) b)))
  368. ;; Savannah bug #39501 "invalid use of unquote-splicing"
  369. (define-macro (a-39501)
  370. `(define-macro (b-39501 . x) `(+ 1 ,@x)))
  371. (a-39501)
  372. (test 7 'savannah-39501 (b-39501 1 2 3))
  373. (begin ;; Test that we can define and use a syntax-case macro in same module.
  374. (define-syntax local-defmac-or
  375. (lambda (x)
  376. (syntax-case x ()
  377. ((_) (syntax #f))
  378. ((_ e) (syntax e))
  379. ((_ e1 e2 e3 ...)
  380. (syntax
  381. (let ((t e1)) (if t t (local-defmac-or e2 e3 ...))))))))
  382. (test 4 'local-defmac-or (local-defmac-or #f 4 5)))
  383. (test '(2 1) 'srfi-72-example-1
  384. (let-syntax ((main (lambda (form)
  385. (define (make-swap x y)
  386. #`(let ((t #,x))
  387. (set! #,x #,y)
  388. (set! #,y t)))
  389. #`(let ((s 1)
  390. (t 2))
  391. #,(make-swap #'s #'t)
  392. (list s t)))))
  393. (main)))
  394. (test '(1 2) 'srfi-72-example-2
  395. (let ((x 1))
  396. (let-syntax ((m (lambda (form)
  397. (let ((x 2))
  398. #`(list x #,x)))))
  399. (m))))
  400. (test '(1 3) 'srfi-72-example-3
  401. (let ((x 1))
  402. (let-syntax ((m (lambda (form)
  403. (let ((x (car '(3))))
  404. #`(list x #,x)))))
  405. (m))))
  406. ;; From R6RS, except [...] replaced by (...), and
  407. ;; using letrec-syntax instead of nested define-syntax.
  408. (test '(#t #f)
  409. 'free-identifier-1
  410. (let ((fred 17))
  411. (letrec-syntax
  412. ((a (lambda (x)
  413. (syntax-case x ()
  414. ((_ id) #'(b id fred)))))
  415. (b (lambda (x)
  416. (syntax-case x ()
  417. ((_ id1 id2)
  418. #`(list
  419. #,(free-identifier=? #'id1 #'id2)
  420. #,(bound-identifier=? #'id1 #'id2)))))))
  421. (a fred))))
  422. (begin
  423. ;; Note we need to compile define and define-for-syntax
  424. ;; in the same compilation unit for it to make sense.
  425. (define x-72-x3 1)
  426. (define-for-syntax x-72-x3 2)
  427. (test '(1 2) 'srfi-72-example-4
  428. (let-syntax ((m (lambda (form)
  429. #`(list x-72-x3 #,x-72-x3))))
  430. (m))))
  431. ;; Based on Savannah bug #17984 Chris Wegrzyn <chris.wegrzyn@gmail.com>
  432. ;; Compile time error in expansion of hygienic macros ending in literals
  433. (define thisfails
  434. (letrec-syntax
  435. ((outer
  436. (syntax-rules ()
  437. ((outer expr)
  438. (begin expr "this fails")))))
  439. (outer "third")))
  440. (test "this fails" 'savannah-bug-17984 thisfails)
  441. ;; Savannah bug #18504 Margus Freudenthal <margus@cyber.ee>
  442. ;; Cannot generate (define-simple-class) using syntax-case macros
  443. (define-syntax aa
  444. (lambda (x)
  445. (syntax-case x ()
  446. ((_ cl arg argtype)
  447. #`(define-simple-class cl ()
  448. (arg type: argtype))))))
  449. (aa MyClass myparam <String>)
  450. (define aa-instance ::MyClass (MyClass myparam: "sarg"))
  451. (test (as <String> "sarg") 'savannah-bug-18504 aa-instance:myparam)
  452. ;; Savannah bug #18105: Chris Wegrzyn <chris.wegrzyn@gmail.com>
  453. ;; with-syntax causes NullPointerException during compilation but not in repl
  454. (begin
  455. (define-syntax crashing-syntax
  456. (lambda (x)
  457. (syntax-case x ()
  458. ((k args e1)
  459. (with-syntax ((bodye1 (syntax e1)))
  460. (syntax
  461. (lambda args (begin bodye1))))))))
  462. (test 3 'savannah-bug-18105 ((crashing-syntax (arg1 arg2) 3) 1 2)))
  463. ;; Luis Casillas <luis@casillas.org> posted to Kawa list 2007-02-02:
  464. (define-for-syntax (alter-syntax-datum proc stx)
  465. ;; must use define-syntax-datum in PLT
  466. (datum->syntax-object stx (proc (syntax-object->datum stx))))
  467. (define-syntax define-symbol-altering-macro
  468. (syntax-rules ()
  469. ((_ (macro-name arg) expr . exprs)
  470. (define-symbol-altering-macro macro-name (lambda (arg) expr . exprs)))
  471. ((_ macro-name proc)
  472. (define-syntax macro-name
  473. (lambda (stx)
  474. (syntax-case stx ()
  475. ((_ sym . args)
  476. (let ((new-sym (alter-syntax-datum proc (syntax sym))))
  477. #`(#,new-sym . args)))))))))
  478. (define-symbol-altering-macro (call-reversename sym)
  479. (string->symbol
  480. (list->string
  481. (reverse
  482. (string->list
  483. (symbol->string sym))))))
  484. (test 7 'symbol-altering-macro (call-reversename xam 3 2 7 6))
  485. ;; Based on a bug reported by Dan Stanger <DStanger@EatonVance.Com>.
  486. (define (test-literal-capture-1)
  487. (letrec-syntax
  488. ((define-input
  489. (syntax-rules () ((define-input var) (define var 1))))
  490. (test-out
  491. (syntax-rules (test-content-type! define-input)
  492. ((test-out (test-content-type! expr ...)) (test-content-type! expr ...))
  493. ((test-out (define-input form)) (error (define-input form)))
  494. ((test-out expr) (list expr)))))
  495. (test-out (symbol->string (quote b)))))
  496. (test '("b") test-literal-capture-1)
  497. ;; A test submitted by Felix Klock <felix_klock_ii@mac.com>
  498. (define (test-literal-capture-2)
  499. (let-syntax ((testm1 (syntax-rules (local-macro)
  500. ((testm1 (local-macro e)) `((lit1 ,e)))
  501. ((testm1 e) `((els1 ,e))))))
  502. (append
  503. (testm1 'in-a)
  504. (testm1 (local-macro 'in-b))
  505. (let-syntax ((local-macro (syntax-rules ()
  506. ((local-macro e) `((2 ,e))))))
  507. (append
  508. (testm1 (local-macro 'in-c))
  509. (let-syntax ((testm2 (syntax-rules (local-macro)
  510. ((testm2 (local-macro e))
  511. `((lit2 ,e)))
  512. ((testm2 e)
  513. `((els2 ,e))))))
  514. (testm2 (local-macro 'in-d)))
  515. (let-syntax ((testm3 (syntax-rules (local-macro)
  516. ((testm3 (local-macro e))
  517. `((lit3 ,e)))
  518. ((testm3 e)
  519. `((els3 ,e)))))
  520. (local-macro (syntax-rules ()
  521. ((local-macro e)
  522. `((4 ,e))))))
  523. (testm3 (local-macro 'in-e)))
  524. (let-syntax ((testm5 (syntax-rules (local-macro)
  525. ((testm5 (local-macro e))
  526. `((lit5 ,e)))
  527. ((testm4 e)
  528. `((els5 ,e))))))
  529. (let-syntax ((local-macro (syntax-rules ()
  530. ((local-macro e)
  531. `((6 ,e))))))
  532. (testm5 (local-macro 'in-f))))
  533. (let-syntax ((local-macro (syntax-rules ()
  534. ((local-macro e)
  535. `((7 ,e))))))
  536. (let-syntax ((testm8 (syntax-rules (local-macro)
  537. ((testm8 (local-macro e))
  538. `((lit8 ,e)))
  539. ((testm8 e)
  540. `((els8 ,e))))))
  541. (testm8 (local-macro 'in-g))))
  542. )))))
  543. (test '((els1 in-a) (lit1 in-b) (els1 ((2 in-c))) (lit2 in-d) (els3 ((4 in-e))) (els5 ((6 in-f))) (lit8 in-g))
  544. test-literal-capture-2)
  545. ;; Savannah bug #26993 "String literals in syntax-rules don't match".
  546. (define-syntax foo-26993
  547. (syntax-rules ()
  548. ((foo-26993 "foo") 'ok)))
  549. (test 'ok 'test-savannah-26993 (foo-26993 "foo"))
  550. ;; Savannah bug #27042: Bad interaction between syntax-rules and call-with-values
  551. ;; (Though the was actually in the hygiene handling of lambda,
  552. ;; and had nothing to do specifically with call-with-values.)
  553. (test '(0 10 0) 'test-savannah-27042
  554. (let-syntax ((dlet
  555. (syntax-rules ()
  556. ((dlet (var val) body)
  557. (let ((saved var))
  558. (set! var val)
  559. (call-with-values (lambda () body)
  560. (lambda (result)
  561. (set! var saved)
  562. result)))))))
  563. (let* ((x 0)
  564. (x0 x)
  565. (x1
  566. (dlet (x (+ x 10))
  567. x))
  568. (x2 x))
  569. (list x0 x1 x2))))
  570. (test '(2 1) 'r7rs-test1
  571. (let ((x 1) (y 2))
  572. (define-syntax swap!
  573. (syntax-rules ()
  574. ((swap! a b)
  575. (let ((tmp a))
  576. (set! a b)
  577. (set! b tmp)))))
  578. (swap! x y)
  579. (list x y)))
  580. (define-syntax r7rs-rec1
  581. (lambda (x)
  582. (syntax-case x ()
  583. ((_ x e)
  584. (identifier? #'x)
  585. #'(letrec ((x e)) x))
  586. ((_ x e)
  587. "not an identifier"))))
  588. (test '(1 2 6 24 120) 'r7rs-rec1
  589. (map (r7rs-rec1 fact
  590. (lambda (n)
  591. (if (= n 0)
  592. 1
  593. (* n (fact (- n 1))))))
  594. '(1 2 3 4 5)))
  595. (test "not an identifier" 'r7rs-rec2
  596. (r7rs-rec1 5 (lambda (x) x)) )
  597. (test '(#t #f) 'free-identifier-1
  598. (let ((fred 17))
  599. (define-syntax a
  600. (lambda (x)
  601. (syntax-case x ()
  602. ((_ id) #'(b id fred)))))
  603. (define-syntax b
  604. (lambda (x)
  605. (syntax-case x ()
  606. ((_ id1 id2)
  607. #`(list
  608. #,(free-identifier=? #'id1 #'id2)
  609. #,(bound-identifier=? #'id1 #'id2))))))
  610. (a fred)))
  611. (test '(#t #f) 'free-identifier-2
  612. (let ((fred 17))
  613. (letrec-syntax
  614. ((a
  615. (lambda (x)
  616. (syntax-case x ()
  617. ((_ id) #'(b id fred)))))
  618. (b
  619. (lambda (x)
  620. (syntax-case x ()
  621. ((_ id1 id2)
  622. #`(list
  623. #,(free-identifier=? #'id1 #'id2)
  624. #,(bound-identifier=? #'id1 #'id2)))))))
  625. (a fred))))
  626. (define-syntax my-let
  627. (lambda (x)
  628. (define unique-ids?
  629. (lambda (ls)
  630. (or (null? ls)
  631. (and (let notmem? ((x (car ls)) (ls (cdr ls)))
  632. (or (null? ls)
  633. (and (not (bound-identifier=? x (car ls)))
  634. (notmem? x (cdr ls)))))
  635. (unique-ids? (cdr ls))))))
  636. (syntax-case x ()
  637. ((_ ((i v) ...) e1 e2 ...)
  638. (unique-ids? #'(i ...))
  639. #'((lambda (i ...) e1 e2 ...) v ...))
  640. ((_ . rest)
  641. "syntax error"))))
  642. (test "syntax error" 'bound-identifier-1
  643. (my-let ((a 3) (a 4)) (+ a a)))
  644. (test 7 'bound-identifier-2
  645. (my-let ((a 3) (b 4)) (+ a b)))
  646. (test 7 'bound-identifier-3
  647. (let-syntax
  648. ((dolet (lambda (x)
  649. (syntax-case x ()
  650. ((_ b)
  651. #'(my-let ((a 3) (b 4)) (+ a b)))))))
  652. (dolet a)))
  653. ;; For comparison, check with builtin let.
  654. (test 7 'bound-identifier-4
  655. (let-syntax
  656. ((dolet (lambda (x)
  657. (syntax-case x ()
  658. ((_ b)
  659. #'(let ((a 3) (b 4)) (+ a b)))))))
  660. (dolet a)))
  661. ;; Savannah bug #35552: bound-identifier=?
  662. ;; Note the SRFI-72 specifies the result #f, but MzScheme/Racket
  663. ;; and Chez Scheme both return #t.
  664. (test #t 'bound-identifier-5
  665. (bound-identifier=? #'+ #'+))
  666. (define-syntax my-case
  667. (lambda (x)
  668. (syntax-case x ()
  669. ((_ e0 ((k ...) e1 e2 ...) ...
  670. (else-key else-e1 else-e2 ...))
  671. (and (identifier? #'else-key)
  672. (free-identifier=? #'else-key #'else))
  673. #'(let ((t e0))
  674. (cond
  675. ((memv t '(k ...)) e1 e2 ...)
  676. ...
  677. (else else-e1 else-e2 ...))))
  678. ((_ e0 ((ka ...) e1a e2a ...)
  679. ((kb ...) e1b e2b ...) ...)
  680. #'(let ((t e0))
  681. (cond
  682. ((memv t '(ka ...)) e1a e2a ...)
  683. ((memv t '(kb ...)) e1b e2b ...)
  684. ...)))
  685. ((_ . rest)
  686. "syntax error"))))
  687. (test "syntax error" 'my-case-1
  688. (let ((else #f))
  689. (my-case 0 (else (list "oops")))))
  690. (test '("oops") 'my-case-2
  691. (let ((xy #f))
  692. (my-case 0 (else (list "oops")))))
  693. ;; Savannah bug report #35526, simplified version
  694. (define-syntax foo-35526a
  695. (syntax-rules ()
  696. ((foo-35526a bar-id stuff ...)
  697. (let ((f (lambda () "+bar+")))
  698. (let-syntax ((bar-id (syntax-rules ()
  699. ((bar-id) (f)))))
  700. (list stuff ...))))))
  701. (define (baz-35526a)
  702. (foo-35526a bar (bar) (bar)))
  703. (test '("+bar+" "+bar+") 'savannah-35526a (baz-35526a))
  704. ;; Savannah bug report #35526, original version
  705. (define-syntax (foo-35526b form)
  706. (syntax-case form ()
  707. ((foo-id stuff ...)
  708. (with-syntax ((bar-id (datum->syntax (syntax foo-id) 'bar)))
  709. (syntax
  710. (let ((f (lambda () 'bar2)))
  711. (let-syntax ((bar-id (syntax-rules ()
  712. ((bar-id) (f)))))
  713. (list stuff ...))))))))
  714. (define (baz-35526b)
  715. (foo-35526b (bar) (bar)))
  716. (test '(bar2 bar2) 'savannah-35526b (baz-35526b))
  717. ;; #35555: Tail-call in syntax-case
  718. (define (foo-35555 forms)
  719. (syntax-case forms ()
  720. (((x . y) . rest)
  721. (foo-35555 #'rest))
  722. (() #t)
  723. (_ #f)))
  724. (define-syntax bar-35555
  725. (lambda (forms)
  726. (foo-35555 (cdr forms))))
  727. (test #t 'bar-35555-1 (bar-35555 (a b) (c d)))
  728. (test #t 'bar-35555-2 (bar-35555))
  729. (test #f 'bar-35555-3 (foo-35555 123))
  730. ;; Savannah bug report #39946 "NullPointerException when using syntax->datum"
  731. (test '(+ 1 2) 'savannah-39946 (syntax->datum (syntax (+ 1 2))))
  732. ;; This example is in the Kawa internals documentation.
  733. (define-syntax mac1
  734. (syntax-rules ()
  735. ((mac1-nest v1 init exp)
  736. (let ((v1 init))
  737. (let ((i 2))
  738. (list exp i))))))
  739. (define j 10)
  740. (test '(11 2) 'test-mac1 (mac1 i 1 (+ i j)))
  741. ;; Savannah bug report #40616 "Unhygienic syntax-rules"
  742. (define-syntax def-a
  743. (syntax-rules ()
  744. ((_) (define a 'wrong))))
  745. (test 'correct 'savannah-40616
  746. (let ((a 'correct)) (def-a) a))
  747. (begin
  748. (define xlist '())
  749. (define-syntax def-b
  750. (syntax-rules ()
  751. ((_ val)
  752. (begin (define a val)
  753. (set! xlist (cons a xlist))))))
  754. (def-b 12)
  755. (def-b 42)
  756. (test '(42 12) 'savannah-40616-2 xlist))