syntax.test 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
  1. ;;;; syntax.test --- test suite for Guile's syntactic forms -*- scheme -*-
  2. ;;;;
  3. ;;;; Copyright (C) 2001, 2003, 2004, 2005, 2006, 2009, 2010,
  4. ;;;; 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
  5. ;;;;
  6. ;;;; This library is free software; you can redistribute it and/or
  7. ;;;; modify it under the terms of the GNU Lesser General Public
  8. ;;;; License as published by the Free Software Foundation; either
  9. ;;;; version 3 of the License, or (at your option) any later version.
  10. ;;;;
  11. ;;;; This library is distributed in the hope that it will be useful,
  12. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. ;;;; Lesser General Public License for more details.
  15. ;;;;
  16. ;;;; You should have received a copy of the GNU Lesser General Public
  17. ;;;; License along with this library; if not, write to the Free Software
  18. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. (define-module (test-suite test-syntax)
  20. #:use-module (ice-9 regex)
  21. #:use-module (ice-9 local-eval)
  22. #:use-module ((system syntax) #:select (syntax?))
  23. #:use-module (test-suite lib))
  24. (define exception:generic-syncase-error
  25. "source expression failed to match")
  26. (define exception:unexpected-syntax
  27. "unexpected syntax")
  28. (define exception:bad-expression
  29. "Bad expression")
  30. (define exception:missing/extra-expr
  31. "Missing or extra expression")
  32. (define exception:missing-expr
  33. "Missing expression")
  34. (define exception:empty-body
  35. "empty body")
  36. (define exception:body-should-end-with-expr
  37. "body should end with an expression")
  38. (define exception:extra-expr
  39. "Extra expression")
  40. (define exception:illegal-empty-combination
  41. "Illegal empty combination")
  42. (define exception:bad-lambda
  43. "bad lambda")
  44. (define exception:bad-let
  45. "bad let$")
  46. (define exception:bad-letrec
  47. "bad letrec$")
  48. (define exception:bad-letrec*
  49. "bad letrec\\*$")
  50. (define exception:bad-set!
  51. "bad set!")
  52. (define exception:bad-quote
  53. '(quote . "bad syntax"))
  54. (define exception:bad-bindings
  55. "Bad bindings")
  56. (define exception:bad-binding
  57. "Bad binding")
  58. (define exception:duplicate-binding
  59. "duplicate bound variable")
  60. (define exception:bad-body
  61. "^bad body")
  62. (define exception:bad-formals
  63. "invalid argument list")
  64. (define exception:bad-formal
  65. "Bad formal")
  66. (define exception:duplicate-formals
  67. "duplicate identifier in argument list")
  68. (define exception:missing-clauses
  69. "Missing clauses")
  70. (define exception:misplaced-else-clause
  71. "Misplaced else clause")
  72. (define exception:bad-case-clause
  73. "Bad case clause")
  74. (define exception:bad-case-labels
  75. "Bad case labels")
  76. (define exception:bad-cond-clause
  77. "Bad cond clause")
  78. (define exception:too-many-args
  79. "too many arguments")
  80. (define exception:wrong-number-of-values
  81. '(wrong-number-of-args . "number of (values)|(arguments)"))
  82. (define exception:zero-expression-sequence
  83. "sequence of zero expressions")
  84. (define exception:variable-ref
  85. '(misc-error . "Unbound variable"))
  86. ;; (put 'pass-if-syntax-error 'scheme-indent-function 1)
  87. (define-syntax pass-if-syntax-error
  88. (syntax-rules ()
  89. ((_ name pat exp)
  90. (pass-if name
  91. (catch 'syntax-error
  92. (lambda () exp (error "expected syntax-error exception"))
  93. (lambda (k who what where form . maybe-subform)
  94. (if (if (pair? pat)
  95. (and (eq? who (car pat))
  96. (string-match (cdr pat) what))
  97. (string-match pat what))
  98. #t
  99. (error "unexpected syntax-error exception" what pat))))))))
  100. (with-test-prefix "expressions"
  101. (with-test-prefix "Bad argument list"
  102. (pass-if-syntax-error "improper argument list of length 1"
  103. exception:generic-syncase-error
  104. (eval '(let ((foo (lambda (x y) #t)))
  105. (foo . 1))
  106. (interaction-environment)))
  107. (pass-if-syntax-error "improper argument list of length 2"
  108. exception:generic-syncase-error
  109. (eval '(let ((foo (lambda (x y) #t)))
  110. (foo 1 . 2))
  111. (interaction-environment))))
  112. (with-test-prefix "missing or extra expression"
  113. ;; R5RS says:
  114. ;; *Note:* In many dialects of Lisp, the empty combination, (),
  115. ;; is a legitimate expression. In Scheme, combinations must
  116. ;; have at least one subexpression, so () is not a syntactically
  117. ;; valid expression.
  118. ;; Fixed on 2001-3-3
  119. (pass-if-syntax-error "empty parentheses \"()\""
  120. exception:unexpected-syntax
  121. (eval '()
  122. (interaction-environment)))))
  123. (with-test-prefix "quote"
  124. #t)
  125. (with-test-prefix "quasiquote"
  126. (with-test-prefix "unquote"
  127. (pass-if "repeated execution"
  128. (let ((foo (let ((i 0)) (lambda () (set! i (+ i 1)) `(,i)))))
  129. (and (equal? (foo) '(1)) (equal? (foo) '(2))))))
  130. (with-test-prefix "unquote-splicing"
  131. (pass-if "extra arguments"
  132. (equal? (eval '(quasiquote ((unquote-splicing (list 1 2) (list 3 4))))
  133. (interaction-environment))
  134. '(1 2 3 4)))))
  135. (with-test-prefix "begin"
  136. (pass-if "valid (begin)"
  137. (eval '(begin (begin) #t) (interaction-environment)))
  138. (if (not (include-deprecated-features))
  139. (pass-if-syntax-error "invalid (begin)"
  140. exception:zero-expression-sequence
  141. (eval '(begin (if #t (begin)) #t) (interaction-environment)))))
  142. (define-syntax matches?
  143. (syntax-rules (<>)
  144. ((_ (op arg ...) pat) (let ((x (op arg ...)))
  145. (matches? x pat)))
  146. ((_ x ()) (null? x))
  147. ((_ x (a . b)) (and (pair? x)
  148. (matches? (car x) a)
  149. (matches? (cdr x) b)))
  150. ((_ x <>) #t)
  151. ((_ x pat) (equal? x 'pat))))
  152. (with-test-prefix "lambda"
  153. (with-test-prefix "bad formals"
  154. (pass-if-syntax-error "(lambda)"
  155. exception:bad-lambda
  156. (eval '(lambda)
  157. (interaction-environment)))
  158. (pass-if-syntax-error "(lambda . \"foo\")"
  159. exception:bad-lambda
  160. (eval '(lambda . "foo")
  161. (interaction-environment)))
  162. (pass-if-syntax-error "(lambda \"foo\")"
  163. exception:bad-lambda
  164. (eval '(lambda "foo")
  165. (interaction-environment)))
  166. (pass-if-syntax-error "(lambda \"foo\" #f)"
  167. exception:bad-formals
  168. (eval '(lambda "foo" #f)
  169. (interaction-environment)))
  170. (pass-if-syntax-error "(lambda (x 1) 2)"
  171. exception:bad-formals
  172. (eval '(lambda (x 1) 2)
  173. (interaction-environment)))
  174. (pass-if-syntax-error "(lambda (1 x) 2)"
  175. exception:bad-formals
  176. (eval '(lambda (1 x) 2)
  177. (interaction-environment)))
  178. (pass-if-syntax-error "(lambda (x \"a\") 2)"
  179. exception:bad-formals
  180. (eval '(lambda (x "a") 2)
  181. (interaction-environment)))
  182. (pass-if-syntax-error "(lambda (\"a\" x) 2)"
  183. exception:bad-formals
  184. (eval '(lambda ("a" x) 2)
  185. (interaction-environment))))
  186. (with-test-prefix "duplicate formals"
  187. ;; Fixed on 2001-3-3
  188. (pass-if-syntax-error "(lambda (x x) 1)"
  189. exception:duplicate-formals
  190. (eval '(lambda (x x) 1)
  191. (interaction-environment)))
  192. ;; Fixed on 2001-3-3
  193. (pass-if-syntax-error "(lambda (x x x) 1)"
  194. exception:duplicate-formals
  195. (eval '(lambda (x x x) 1)
  196. (interaction-environment))))
  197. (with-test-prefix "bad body"
  198. (pass-if-syntax-error "(lambda ())"
  199. exception:bad-lambda
  200. (eval '(lambda ())
  201. (interaction-environment)))))
  202. (with-test-prefix "let"
  203. (with-test-prefix "bindings"
  204. (pass-if-exception "late binding"
  205. exception:unbound-var
  206. (let ((x 1) (y x)) y)))
  207. (with-test-prefix "bad bindings"
  208. (pass-if-syntax-error "(let)"
  209. exception:bad-let
  210. (eval '(let)
  211. (interaction-environment)))
  212. (pass-if-syntax-error "(let 1)"
  213. exception:bad-let
  214. (eval '(let 1)
  215. (interaction-environment)))
  216. (pass-if-syntax-error "(let (x))"
  217. exception:bad-let
  218. (eval '(let (x))
  219. (interaction-environment)))
  220. (pass-if-syntax-error "(let ((x)))"
  221. exception:bad-let
  222. (eval '(let ((x)))
  223. (interaction-environment)))
  224. (pass-if-syntax-error "(let (x) 1)"
  225. exception:bad-let
  226. (eval '(let (x) 1)
  227. (interaction-environment)))
  228. (pass-if-syntax-error "(let ((x)) 3)"
  229. exception:bad-let
  230. (eval '(let ((x)) 3)
  231. (interaction-environment)))
  232. (pass-if-syntax-error "(let ((x 1) y) x)"
  233. exception:bad-let
  234. (eval '(let ((x 1) y) x)
  235. (interaction-environment)))
  236. (pass-if-syntax-error "(let ((1 2)) 3)"
  237. exception:bad-let
  238. (eval '(let ((1 2)) 3)
  239. (interaction-environment))))
  240. (with-test-prefix "duplicate bindings"
  241. (pass-if-syntax-error "(let ((x 1) (x 2)) x)"
  242. exception:duplicate-binding
  243. (eval '(let ((x 1) (x 2)) x)
  244. (interaction-environment))))
  245. (with-test-prefix "bad body"
  246. (pass-if-syntax-error "(let ())"
  247. exception:bad-let
  248. (eval '(let ())
  249. (interaction-environment)))
  250. (pass-if-syntax-error "(let ((x 1)))"
  251. exception:bad-let
  252. (eval '(let ((x 1)))
  253. (interaction-environment)))))
  254. (with-test-prefix "named let"
  255. (with-test-prefix "initializers"
  256. (pass-if "evaluated in outer environment"
  257. (let ((f -))
  258. (eqv? (let f ((n (f 1))) n) -1))))
  259. (with-test-prefix "bad bindings"
  260. (pass-if-syntax-error "(let x (y))"
  261. exception:bad-let
  262. (eval '(let x (y))
  263. (interaction-environment))))
  264. (with-test-prefix "bad body"
  265. (pass-if-syntax-error "(let x ())"
  266. exception:bad-let
  267. (eval '(let x ())
  268. (interaction-environment)))
  269. (pass-if-syntax-error "(let x ((y 1)))"
  270. exception:bad-let
  271. (eval '(let x ((y 1)))
  272. (interaction-environment)))))
  273. (with-test-prefix "let*"
  274. (with-test-prefix "bindings"
  275. (pass-if "(let* ((x 1) (x 2)) ...)"
  276. (let* ((x 1) (x 2))
  277. (= x 2)))
  278. (pass-if "(let* ((x 1) (x x)) ...)"
  279. (let* ((x 1) (x x))
  280. (= x 1)))
  281. (pass-if "(let ((x 1) (y 2)) (let* () ...))"
  282. (let ((x 1) (y 2))
  283. (let* ()
  284. (and (= x 1) (= y 2))))))
  285. (with-test-prefix "bad bindings"
  286. (pass-if-syntax-error "(let*)"
  287. exception:generic-syncase-error
  288. (eval '(let*)
  289. (interaction-environment)))
  290. (pass-if-syntax-error "(let* 1)"
  291. exception:generic-syncase-error
  292. (eval '(let* 1)
  293. (interaction-environment)))
  294. (pass-if-syntax-error "(let* (x))"
  295. exception:generic-syncase-error
  296. (eval '(let* (x))
  297. (interaction-environment)))
  298. (pass-if-syntax-error "(let* (x) 1)"
  299. exception:generic-syncase-error
  300. (eval '(let* (x) 1)
  301. (interaction-environment)))
  302. (pass-if-syntax-error "(let* ((x)) 3)"
  303. exception:generic-syncase-error
  304. (eval '(let* ((x)) 3)
  305. (interaction-environment)))
  306. (pass-if-syntax-error "(let* ((x 1) y) x)"
  307. exception:generic-syncase-error
  308. (eval '(let* ((x 1) y) x)
  309. (interaction-environment)))
  310. (pass-if-syntax-error "(let* x ())"
  311. exception:generic-syncase-error
  312. (eval '(let* x ())
  313. (interaction-environment)))
  314. (pass-if-syntax-error "(let* x (y))"
  315. exception:generic-syncase-error
  316. (eval '(let* x (y))
  317. (interaction-environment)))
  318. (pass-if-syntax-error "(let* ((1 2)) 3)"
  319. exception:generic-syncase-error
  320. (eval '(let* ((1 2)) 3)
  321. (interaction-environment))))
  322. (with-test-prefix "bad body"
  323. (pass-if-syntax-error "(let* ())"
  324. exception:generic-syncase-error
  325. (eval '(let* ())
  326. (interaction-environment)))
  327. (pass-if-syntax-error "(let* ((x 1)))"
  328. exception:generic-syncase-error
  329. (eval '(let* ((x 1)))
  330. (interaction-environment)))))
  331. (with-test-prefix "letrec"
  332. (with-test-prefix "bindings"
  333. (pass-if-exception "initial bindings are undefined"
  334. exception:variable-ref
  335. (eval '(let ((x 1))
  336. (letrec ((x 1) (y x)) y))
  337. (interaction-environment))))
  338. (with-test-prefix "bad bindings"
  339. (pass-if-syntax-error "(letrec)"
  340. exception:bad-letrec
  341. (eval '(letrec)
  342. (interaction-environment)))
  343. (pass-if-syntax-error "(letrec 1)"
  344. exception:bad-letrec
  345. (eval '(letrec 1)
  346. (interaction-environment)))
  347. (pass-if-syntax-error "(letrec (x))"
  348. exception:bad-letrec
  349. (eval '(letrec (x))
  350. (interaction-environment)))
  351. (pass-if-syntax-error "(letrec (x) 1)"
  352. exception:bad-letrec
  353. (eval '(letrec (x) 1)
  354. (interaction-environment)))
  355. (pass-if-syntax-error "(letrec ((x)) 3)"
  356. exception:bad-letrec
  357. (eval '(letrec ((x)) 3)
  358. (interaction-environment)))
  359. (pass-if-syntax-error "(letrec ((x 1) y) x)"
  360. exception:bad-letrec
  361. (eval '(letrec ((x 1) y) x)
  362. (interaction-environment)))
  363. (pass-if-syntax-error "(letrec x ())"
  364. exception:bad-letrec
  365. (eval '(letrec x ())
  366. (interaction-environment)))
  367. (pass-if-syntax-error "(letrec x (y))"
  368. exception:bad-letrec
  369. (eval '(letrec x (y))
  370. (interaction-environment)))
  371. (pass-if-syntax-error "(letrec ((1 2)) 3)"
  372. exception:bad-letrec
  373. (eval '(letrec ((1 2)) 3)
  374. (interaction-environment))))
  375. (with-test-prefix "duplicate bindings"
  376. (pass-if-syntax-error "(letrec ((x 1) (x 2)) x)"
  377. exception:duplicate-binding
  378. (eval '(letrec ((x 1) (x 2)) x)
  379. (interaction-environment))))
  380. (with-test-prefix "bad body"
  381. (pass-if-syntax-error "(letrec ())"
  382. exception:bad-letrec
  383. (eval '(letrec ())
  384. (interaction-environment)))
  385. (pass-if-syntax-error "(letrec ((x 1)))"
  386. exception:bad-letrec
  387. (eval '(letrec ((x 1)))
  388. (interaction-environment)))))
  389. (with-test-prefix "letrec*"
  390. (with-test-prefix "bindings"
  391. (pass-if-exception "initial bindings are undefined"
  392. exception:variable-ref
  393. (eval '(letrec* ((x y) (y 1)) y)
  394. (interaction-environment))))
  395. (with-test-prefix "bad bindings"
  396. (pass-if-syntax-error "(letrec*)"
  397. exception:bad-letrec*
  398. (eval '(letrec*)
  399. (interaction-environment)))
  400. (pass-if-syntax-error "(letrec* 1)"
  401. exception:bad-letrec*
  402. (eval '(letrec* 1)
  403. (interaction-environment)))
  404. (pass-if-syntax-error "(letrec* (x))"
  405. exception:bad-letrec*
  406. (eval '(letrec* (x))
  407. (interaction-environment)))
  408. (pass-if-syntax-error "(letrec* (x) 1)"
  409. exception:bad-letrec*
  410. (eval '(letrec* (x) 1)
  411. (interaction-environment)))
  412. (pass-if-syntax-error "(letrec* ((x)) 3)"
  413. exception:bad-letrec*
  414. (eval '(letrec* ((x)) 3)
  415. (interaction-environment)))
  416. (pass-if-syntax-error "(letrec* ((x 1) y) x)"
  417. exception:bad-letrec*
  418. (eval '(letrec* ((x 1) y) x)
  419. (interaction-environment)))
  420. (pass-if-syntax-error "(letrec* x ())"
  421. exception:bad-letrec*
  422. (eval '(letrec* x ())
  423. (interaction-environment)))
  424. (pass-if-syntax-error "(letrec* x (y))"
  425. exception:bad-letrec*
  426. (eval '(letrec* x (y))
  427. (interaction-environment)))
  428. (pass-if-syntax-error "(letrec* ((1 2)) 3)"
  429. exception:bad-letrec*
  430. (eval '(letrec* ((1 2)) 3)
  431. (interaction-environment))))
  432. (with-test-prefix "duplicate bindings"
  433. (pass-if-syntax-error "(letrec* ((x 1) (x 2)) x)"
  434. exception:duplicate-binding
  435. (eval '(letrec* ((x 1) (x 2)) x)
  436. (interaction-environment))))
  437. (with-test-prefix "bad body"
  438. (pass-if-syntax-error "(letrec* ())"
  439. exception:bad-letrec*
  440. (eval '(letrec* ())
  441. (interaction-environment)))
  442. (pass-if-syntax-error "(letrec* ((x 1)))"
  443. exception:bad-letrec*
  444. (eval '(letrec* ((x 1)))
  445. (interaction-environment))))
  446. (with-test-prefix "referencing previous values"
  447. (pass-if (equal? (letrec* ((a (cons 'foo 'bar))
  448. (b a))
  449. b)
  450. '(foo . bar)))
  451. (pass-if (equal? (let ()
  452. (define a (cons 'foo 'bar))
  453. (define b a)
  454. b)
  455. '(foo . bar)))))
  456. (with-test-prefix "if"
  457. (with-test-prefix "missing or extra expressions"
  458. (pass-if-syntax-error "(if)"
  459. exception:generic-syncase-error
  460. (eval '(if)
  461. (interaction-environment)))
  462. (pass-if-syntax-error "(if 1 2 3 4)"
  463. exception:generic-syncase-error
  464. (eval '(if 1 2 3 4)
  465. (interaction-environment)))))
  466. (with-test-prefix "cond"
  467. (with-test-prefix "cond is hygienic"
  468. (pass-if "bound 'else is handled correctly"
  469. (eq? (let ((else 'ok)) (cond (else))) 'ok))
  470. (with-test-prefix "bound '=> is handled correctly"
  471. (pass-if "#t => 'ok"
  472. (let ((=> 'foo))
  473. (eq? (cond (#t => 'ok)) 'ok)))
  474. (pass-if "else =>"
  475. (let ((=> 'foo))
  476. (eq? (cond (else =>)) 'foo)))
  477. (pass-if "else => identity"
  478. (let ((=> 'foo))
  479. (eq? (cond (else => identity)) identity)))))
  480. (with-test-prefix "SRFI-61"
  481. (pass-if "always available"
  482. (cond-expand (srfi-61 #t) (else #f)))
  483. (pass-if "single value consequent"
  484. (eq? 'ok (cond (#t identity => (lambda (x) 'ok)) (else #f))))
  485. (pass-if "single value alternate"
  486. (eq? 'ok (cond (#t not => (lambda (x) #f)) (else 'ok))))
  487. (pass-if-exception "doesn't affect standard =>"
  488. exception:wrong-num-args
  489. (cond ((values 1 2) => (lambda (x y) #t))))
  490. (pass-if "multiple values consequent"
  491. (equal? '(2 1) (cond ((values 1 2)
  492. (lambda (one two)
  493. (and (= 1 one) (= 2 two))) =>
  494. (lambda (one two) (list two one)))
  495. (else #f))))
  496. (pass-if "multiple values alternate"
  497. (eq? 'ok (cond ((values 2 3 4)
  498. (lambda args (equal? '(1 2 3) args)) =>
  499. (lambda (x y z) #f))
  500. (else 'ok))))
  501. (pass-if "zero values"
  502. (eq? 'ok (cond ((values) (lambda () #t) => (lambda () 'ok))
  503. (else #f))))
  504. (pass-if "bound => is handled correctly"
  505. (let ((=> 'ok))
  506. (eq? 'ok (cond (#t identity =>) (else #f)))))
  507. (pass-if-syntax-error "missing recipient"
  508. '(cond . "wrong number of receiver expressions")
  509. (eval '(cond (#t identity =>))
  510. (interaction-environment)))
  511. (pass-if-syntax-error "extra recipient"
  512. '(cond . "wrong number of receiver expressions")
  513. (eval '(cond (#t identity => identity identity))
  514. (interaction-environment))))
  515. (with-test-prefix "bad or missing clauses"
  516. (pass-if-syntax-error "(cond)"
  517. exception:generic-syncase-error
  518. (eval '(cond)
  519. (interaction-environment)))
  520. (pass-if-syntax-error "(cond #t)"
  521. '(cond . "invalid clause")
  522. (eval '(cond #t)
  523. (interaction-environment)))
  524. (pass-if-syntax-error "(cond 1)"
  525. '(cond . "invalid clause")
  526. (eval '(cond 1)
  527. (interaction-environment)))
  528. (pass-if-syntax-error "(cond 1 2)"
  529. '(cond . "invalid clause")
  530. (eval '(cond 1 2)
  531. (interaction-environment)))
  532. (pass-if-syntax-error "(cond 1 2 3)"
  533. '(cond . "invalid clause")
  534. (eval '(cond 1 2 3)
  535. (interaction-environment)))
  536. (pass-if-syntax-error "(cond 1 2 3 4)"
  537. '(cond . "invalid clause")
  538. (eval '(cond 1 2 3 4)
  539. (interaction-environment)))
  540. (pass-if-syntax-error "(cond ())"
  541. '(cond . "invalid clause")
  542. (eval '(cond ())
  543. (interaction-environment)))
  544. (pass-if-syntax-error "(cond () 1)"
  545. '(cond . "invalid clause")
  546. (eval '(cond () 1)
  547. (interaction-environment)))
  548. (pass-if-syntax-error "(cond (1) 1)"
  549. '(cond . "invalid clause")
  550. (eval '(cond (1) 1)
  551. (interaction-environment)))
  552. (pass-if-syntax-error "(cond (else #f) (#t #t))"
  553. '(cond . "else must be the last clause")
  554. (eval '(cond (else #f) (#t #t))
  555. (interaction-environment))))
  556. (with-test-prefix "wrong number of arguments"
  557. (pass-if-exception "=> (lambda (x y) #t)"
  558. exception:wrong-num-args
  559. (cond (1 => (lambda (x y) #t))))))
  560. (with-test-prefix "case"
  561. (pass-if "clause with empty labels list"
  562. (case 1 (() #f) (else #t)))
  563. (with-test-prefix "case handles '=> correctly"
  564. (pass-if "(1 2 3) => list"
  565. (equal? (case 1 ((1 2 3) => list))
  566. '(1)))
  567. (pass-if "else => list"
  568. (equal? (case 6
  569. ((1 2 3) 'wrong)
  570. (else => list))
  571. '(6)))
  572. (with-test-prefix "bound '=> is handled correctly"
  573. (pass-if "(1) => 'ok"
  574. (let ((=> 'foo))
  575. (eq? (case 1 ((1) => 'ok)) 'ok)))
  576. (pass-if "else =>"
  577. (let ((=> 'foo))
  578. (eq? (case 1 (else =>)) 'foo)))
  579. (pass-if "else => list"
  580. (let ((=> 'foo))
  581. (eq? (case 1 (else => identity)) identity))))
  582. (pass-if-syntax-error "missing recipient"
  583. '(case . "wrong number of receiver expressions")
  584. (eval '(case 1 ((1) =>))
  585. (interaction-environment)))
  586. (pass-if-syntax-error "extra recipient"
  587. '(case . "wrong number of receiver expressions")
  588. (eval '(case 1 ((1) => identity identity))
  589. (interaction-environment))))
  590. (with-test-prefix "case is hygienic"
  591. (pass-if-syntax-error "bound 'else is handled correctly"
  592. '(case . "invalid clause")
  593. (eval '(let ((else #f)) (case 1 (else #f)))
  594. (interaction-environment))))
  595. (with-test-prefix "bad or missing clauses"
  596. (pass-if-syntax-error "(case)"
  597. exception:generic-syncase-error
  598. (eval '(case)
  599. (interaction-environment)))
  600. (pass-if-syntax-error "(case . \"foo\")"
  601. exception:generic-syncase-error
  602. (eval '(case . "foo")
  603. (interaction-environment)))
  604. (pass-if-syntax-error "(case 1)"
  605. exception:generic-syncase-error
  606. (eval '(case 1)
  607. (interaction-environment)))
  608. (pass-if-syntax-error "(case 1 . \"foo\")"
  609. exception:generic-syncase-error
  610. (eval '(case 1 . "foo")
  611. (interaction-environment)))
  612. (pass-if-syntax-error "(case 1 \"foo\")"
  613. '(case . "invalid clause")
  614. (eval '(case 1 "foo")
  615. (interaction-environment)))
  616. (pass-if-syntax-error "(case 1 ())"
  617. '(case . "invalid clause")
  618. (eval '(case 1 ())
  619. (interaction-environment)))
  620. (pass-if-syntax-error "(case 1 (\"foo\"))"
  621. '(case . "invalid clause")
  622. (eval '(case 1 ("foo"))
  623. (interaction-environment)))
  624. (pass-if-syntax-error "(case 1 (\"foo\" \"bar\"))"
  625. '(case . "invalid clause")
  626. (eval '(case 1 ("foo" "bar"))
  627. (interaction-environment)))
  628. (pass-if-syntax-error "(case 1 ((2) \"bar\") . \"foo\")"
  629. exception:generic-syncase-error
  630. (eval '(case 1 ((2) "bar") . "foo")
  631. (interaction-environment)))
  632. (pass-if-syntax-error "(case 1 ((2) \"bar\") (else))"
  633. '(case . "invalid clause")
  634. (eval '(case 1 ((2) "bar") (else))
  635. (interaction-environment)))
  636. (pass-if-syntax-error "(case 1 (else #f) . \"foo\")"
  637. exception:generic-syncase-error
  638. (eval '(case 1 (else #f) . "foo")
  639. (interaction-environment)))
  640. (pass-if-syntax-error "(case 1 (else #f) ((1) #t))"
  641. '(case . "else must be the last clause")
  642. (eval '(case 1 (else #f) ((1) #t))
  643. (interaction-environment)))))
  644. (with-test-prefix "top-level define"
  645. (pass-if "redefinition"
  646. (let ((m (make-module)))
  647. (beautify-user-module! m)
  648. ;; The previous value of `round' must still be visible at the time the
  649. ;; new `round' is defined. According to R5RS (Section 5.2.1), `define'
  650. ;; should behave like `set!' in this case (except that in the case of
  651. ;; Guile, we respect module boundaries).
  652. (eval '(define round round) m)
  653. (eq? (module-ref m 'round) round)))
  654. (with-test-prefix "missing or extra expressions"
  655. (pass-if-syntax-error "(define)"
  656. exception:generic-syncase-error
  657. (eval '(define)
  658. (interaction-environment))))
  659. (pass-if "module scoping"
  660. (equal?
  661. (eval
  662. '(begin
  663. (define-module (top-level-define/module-scoping-1)
  664. #:export (define-10))
  665. (define-syntax-rule (define-10 name)
  666. (begin
  667. (define t 10)
  668. (define (name) t)))
  669. (define-module (top-level-define/module-scoping-2)
  670. #:use-module (top-level-define/module-scoping-1))
  671. (define-10 foo)
  672. (foo))
  673. (current-module))
  674. 10))
  675. (pass-if "module scoping, same symbolic name"
  676. (equal?
  677. (eval
  678. '(begin
  679. (define-module (top-level-define/module-scoping-3))
  680. (define a 10)
  681. (define-module (top-level-define/module-scoping-4)
  682. #:use-module (top-level-define/module-scoping-3))
  683. (define a (@@ (top-level-define/module-scoping-3) a))
  684. a)
  685. (current-module))
  686. 10))
  687. (pass-if "module scoping, introduced names"
  688. (equal?
  689. (eval
  690. '(begin
  691. (define-module (top-level-define/module-scoping-5)
  692. #:export (define-constant))
  693. (define-syntax-rule (define-constant name val)
  694. (begin
  695. (define t val)
  696. (define (name) t)))
  697. (define-module (top-level-define/module-scoping-6)
  698. #:use-module (top-level-define/module-scoping-5))
  699. (define-constant foo 10)
  700. (define-constant bar 20)
  701. (foo))
  702. (current-module))
  703. 10))
  704. (pass-if "module scoping, duplicate introduced name"
  705. (equal?
  706. (eval
  707. '(begin
  708. (define-module (top-level-define/module-scoping-7)
  709. #:export (define-constant))
  710. (define-syntax-rule (define-constant name val)
  711. (begin
  712. (define t val)
  713. (define (name) t)))
  714. (define-module (top-level-define/module-scoping-8)
  715. #:use-module (top-level-define/module-scoping-7))
  716. (define-constant foo 10)
  717. (define-constant foo 20)
  718. (foo))
  719. (current-module))
  720. 20)))
  721. (with-test-prefix "internal define"
  722. (pass-if "internal defines become letrec"
  723. (eval '(let ((a identity) (b identity) (c identity))
  724. (define (a x) (if (= x 0) 'a (b (- x 1))))
  725. (define (b x) (if (= x 0) 'b (c (- x 1))))
  726. (define (c x) (if (= x 0) 'c (a (- x 1))))
  727. (and (eq? 'a (a 0) (a 3))
  728. (eq? 'b (a 1) (a 4))
  729. (eq? 'c (a 2) (a 5))))
  730. (interaction-environment)))
  731. (pass-if "binding is created before expression is evaluated"
  732. ;; Internal defines are equivalent to `letrec' (R5RS, Section 5.2.2).
  733. (= (eval '(let ()
  734. (define foo
  735. (begin
  736. (set! foo 1)
  737. (+ foo 1)))
  738. foo)
  739. (interaction-environment))
  740. 2))
  741. (pass-if "internal defines with begin"
  742. (false-if-exception
  743. (eval '(let ((a identity) (b identity) (c identity))
  744. (define (a x) (if (= x 0) 'a (b (- x 1))))
  745. (begin
  746. (define (b x) (if (= x 0) 'b (c (- x 1)))))
  747. (define (c x) (if (= x 0) 'c (a (- x 1))))
  748. (and (eq? 'a (a 0) (a 3))
  749. (eq? 'b (a 1) (a 4))
  750. (eq? 'c (a 2) (a 5))))
  751. (interaction-environment))))
  752. (pass-if "internal defines with empty begin"
  753. (false-if-exception
  754. (eval '(let ((a identity) (b identity) (c identity))
  755. (define (a x) (if (= x 0) 'a (b (- x 1))))
  756. (begin)
  757. (define (b x) (if (= x 0) 'b (c (- x 1))))
  758. (define (c x) (if (= x 0) 'c (a (- x 1))))
  759. (and (eq? 'a (a 0) (a 3))
  760. (eq? 'b (a 1) (a 4))
  761. (eq? 'c (a 2) (a 5))))
  762. (interaction-environment))))
  763. (pass-if "internal defines with macro application"
  764. (false-if-exception
  765. (eval '(begin
  766. (defmacro my-define forms
  767. (cons 'define forms))
  768. (let ((a identity) (b identity) (c identity))
  769. (define (a x) (if (= x 0) 'a (b (- x 1))))
  770. (my-define (b x) (if (= x 0) 'b (c (- x 1))))
  771. (define (c x) (if (= x 0) 'c (a (- x 1))))
  772. (and (eq? 'a (a 0) (a 3))
  773. (eq? 'b (a 1) (a 4))
  774. (eq? 'c (a 2) (a 5)))))
  775. (interaction-environment))))
  776. (pass-if-syntax-error "empty body"
  777. exception:empty-body
  778. (eval '(let () (begin))
  779. (interaction-environment)))
  780. (pass-if-syntax-error "body should end with expression"
  781. exception:body-should-end-with-expr
  782. (eval '(let () (define x #t))
  783. (interaction-environment)))
  784. (pass-if-equal "mixed definitions and expressions" 256
  785. ((eval '(lambda (x)
  786. (unless (number? x) (error "not a number" x))
  787. (define (square x) (* x x))
  788. (square (square x)))
  789. (interaction-environment))
  790. 4))
  791. (pass-if-equal "mixed definitions and expressions 2" 42
  792. (eval '(let ()
  793. (define (foo) (bar))
  794. 1
  795. (define (bar) 42)
  796. (foo))
  797. (interaction-environment))))
  798. (with-test-prefix "top-level define-values"
  799. (pass-if "zero values"
  800. (eval '(begin (define-values () (values))
  801. #t)
  802. (interaction-environment)))
  803. (pass-if-equal "one value"
  804. 1
  805. (eval '(begin (define-values (x) 1)
  806. x)
  807. (interaction-environment)))
  808. (pass-if-equal "two values"
  809. '(2 3)
  810. (eval '(begin (define-values (x y) (values 2 3))
  811. (list x y))
  812. (interaction-environment)))
  813. (pass-if-equal "three values"
  814. '(4 5 6)
  815. (eval '(begin (define-values (x y z) (values 4 5 6))
  816. (list x y z))
  817. (interaction-environment)))
  818. (pass-if-equal "one value with tail"
  819. '(a (b c d))
  820. (eval '(begin (define-values (x . y) (values 'a 'b 'c 'd))
  821. (list x y))
  822. (interaction-environment)))
  823. (pass-if-equal "two values with tail"
  824. '(x y (z w))
  825. (eval '(begin (define-values (x y . z) (values 'x 'y 'z 'w))
  826. (list x y z))
  827. (interaction-environment)))
  828. (pass-if-equal "just tail"
  829. '(1 2 3)
  830. (eval '(begin (define-values x (values 1 2 3))
  831. x)
  832. (interaction-environment)))
  833. (pass-if-exception "expected 0 values, got 1"
  834. exception:wrong-number-of-values
  835. (eval '(define-values () 1)
  836. (interaction-environment)))
  837. (pass-if-exception "expected 1 value, got 0"
  838. exception:wrong-number-of-values
  839. (eval '(define-values (x) (values))
  840. (interaction-environment)))
  841. (pass-if-exception "expected 1 value, got 2"
  842. exception:wrong-number-of-values
  843. (eval '(define-values (x) (values 1 2))
  844. (interaction-environment)))
  845. (pass-if-exception "expected 1 value with tail, got 0"
  846. exception:wrong-number-of-values
  847. (eval '(define-values (x . y) (values))
  848. (interaction-environment)))
  849. (pass-if-exception "expected 2 value with tail, got 1"
  850. exception:wrong-number-of-values
  851. (eval '(define-values (x y . z) 1)
  852. (interaction-environment)))
  853. (pass-if "redefinition"
  854. (let ((m (make-module)))
  855. (beautify-user-module! m)
  856. ;; The previous values of `floor' and `round' must still be
  857. ;; visible at the time the new `floor' and `round' are defined.
  858. (eval '(define-values (floor round) (values floor round)) m)
  859. (and (eq? (module-ref m 'floor) floor)
  860. (eq? (module-ref m 'round) round))))
  861. (with-test-prefix "missing expression"
  862. (pass-if-syntax-error "(define-values)"
  863. exception:generic-syncase-error
  864. (eval '(define-values)
  865. (interaction-environment)))))
  866. (with-test-prefix "internal define-values"
  867. (pass-if "zero values"
  868. (let ()
  869. (define-values () (values))
  870. #t))
  871. (pass-if-equal "one value"
  872. 1
  873. (let ()
  874. (define-values (x) 1)
  875. x))
  876. (pass-if-equal "two values"
  877. '(2 3)
  878. (let ()
  879. (define-values (x y) (values 2 3))
  880. (list x y)))
  881. (pass-if-equal "three values"
  882. '(4 5 6)
  883. (let ()
  884. (define-values (x y z) (values 4 5 6))
  885. (list x y z)))
  886. (pass-if-equal "one value with tail"
  887. '(a (b c d))
  888. (let ()
  889. (define-values (x . y) (values 'a 'b 'c 'd))
  890. (list x y)))
  891. (pass-if-equal "two values with tail"
  892. '(x y (z w))
  893. (let ()
  894. (define-values (x y . z) (values 'x 'y 'z 'w))
  895. (list x y z)))
  896. (pass-if-equal "just tail"
  897. '(1 2 3)
  898. (let ()
  899. (define-values x (values 1 2 3))
  900. x))
  901. (pass-if-exception "expected 0 values, got 1"
  902. exception:wrong-number-of-values
  903. (eval '(let ()
  904. (define-values () 1)
  905. #f)
  906. (interaction-environment)))
  907. (pass-if-exception "expected 1 value, got 0"
  908. exception:wrong-number-of-values
  909. (eval '(let ()
  910. (define-values (x) (values))
  911. #f)
  912. (interaction-environment)))
  913. (pass-if-exception "expected 1 value, got 2"
  914. exception:wrong-number-of-values
  915. (eval '(let ()
  916. (define-values (x) (values 1 2))
  917. #f)
  918. (interaction-environment)))
  919. (pass-if-exception "expected 1 value with tail, got 0"
  920. exception:wrong-number-of-values
  921. (eval '(let ()
  922. (define-values (x . y) (values))
  923. #f)
  924. (interaction-environment)))
  925. (pass-if-exception "expected 2 value with tail, got 1"
  926. exception:wrong-number-of-values
  927. (eval '(let ()
  928. (define-values (x y . z) 1)
  929. #f)
  930. (interaction-environment)))
  931. (with-test-prefix "missing expression"
  932. (pass-if-syntax-error "(define-values)"
  933. exception:generic-syncase-error
  934. (eval '(let ()
  935. (define-values)
  936. #f)
  937. (interaction-environment)))))
  938. (with-test-prefix "set!"
  939. (with-test-prefix "missing or extra expressions"
  940. (pass-if-syntax-error "(set!)"
  941. exception:bad-set!
  942. (eval '(set!)
  943. (interaction-environment)))
  944. (pass-if-syntax-error "(set! 1)"
  945. exception:bad-set!
  946. (eval '(set! 1)
  947. (interaction-environment)))
  948. (pass-if-syntax-error "(set! 1 2 3)"
  949. exception:bad-set!
  950. (eval '(set! 1 2 3)
  951. (interaction-environment))))
  952. (with-test-prefix "bad variable"
  953. (pass-if-syntax-error "(set! \"\" #t)"
  954. exception:bad-set!
  955. (eval '(set! "" #t)
  956. (interaction-environment)))
  957. (pass-if-syntax-error "(set! 1 #t)"
  958. exception:bad-set!
  959. (eval '(set! 1 #t)
  960. (interaction-environment)))
  961. (pass-if-syntax-error "(set! #t #f)"
  962. exception:bad-set!
  963. (eval '(set! #t #f)
  964. (interaction-environment)))
  965. (pass-if-syntax-error "(set! #f #t)"
  966. exception:bad-set!
  967. (eval '(set! #f #t)
  968. (interaction-environment)))
  969. (pass-if-syntax-error "(set! #\\space #f)"
  970. exception:bad-set!
  971. (eval '(set! #\space #f)
  972. (interaction-environment)))))
  973. (with-test-prefix "quote"
  974. (with-test-prefix "missing or extra expression"
  975. (pass-if-syntax-error "(quote)"
  976. exception:bad-quote
  977. (eval '(quote)
  978. (interaction-environment)))
  979. (pass-if-syntax-error "(quote a b)"
  980. exception:bad-quote
  981. (eval '(quote a b)
  982. (interaction-environment)))))
  983. (with-test-prefix "while"
  984. (define (unreachable)
  985. (error "unreachable code has been reached!"))
  986. ;; Return a new procedure COND which when called (COND) will return #t the
  987. ;; first N times, then #f, then any further call is an error. N=0 is
  988. ;; allowed, in which case #f is returned by the first call.
  989. (define (make-iterations-cond n)
  990. (lambda ()
  991. (cond ((not n)
  992. (error "oops, condition re-tested after giving false"))
  993. ((= 0 n)
  994. (set! n #f)
  995. #f)
  996. (else
  997. (set! n (1- n))
  998. #t))))
  999. (pass-if-syntax-error "too few args" exception:generic-syncase-error
  1000. (eval '(while) (interaction-environment)))
  1001. (with-test-prefix "empty body"
  1002. (do ((n 0 (1+ n)))
  1003. ((> n 5))
  1004. (pass-if n
  1005. (eval `(letrec ((make-iterations-cond
  1006. (lambda (n)
  1007. (lambda ()
  1008. (cond ((not n)
  1009. (error "oops, condition re-tested after giving false"))
  1010. ((= 0 n)
  1011. (set! n #f)
  1012. #f)
  1013. (else
  1014. (set! n (1- n))
  1015. #t))))))
  1016. (let ((cond (make-iterations-cond ,n)))
  1017. (while (cond))
  1018. #t))
  1019. (interaction-environment)))))
  1020. (pass-if "initially false"
  1021. (while #f
  1022. (unreachable))
  1023. #t)
  1024. (with-test-prefix "iterations"
  1025. (do ((n 0 (1+ n)))
  1026. ((> n 5))
  1027. (pass-if n
  1028. (let ((cond (make-iterations-cond n))
  1029. (i 0))
  1030. (while (cond)
  1031. (set! i (1+ i)))
  1032. (= i n)))))
  1033. (with-test-prefix "break"
  1034. (pass-if "normal return"
  1035. (not (while #f (error "not reached"))))
  1036. (pass-if "no args"
  1037. (while #t (break)))
  1038. (pass-if "multiple values"
  1039. (equal? '(1 2 3)
  1040. (call-with-values
  1041. (lambda () (while #t (break 1 2 3)))
  1042. list)))
  1043. (with-test-prefix "from cond"
  1044. (pass-if "first"
  1045. (while (begin
  1046. (break)
  1047. (unreachable))
  1048. (unreachable))
  1049. #t)
  1050. (do ((n 0 (1+ n)))
  1051. ((> n 5))
  1052. (pass-if n
  1053. (let ((cond (make-iterations-cond n))
  1054. (i 0))
  1055. (while (if (cond)
  1056. #t
  1057. (begin
  1058. (break)
  1059. (unreachable)))
  1060. (set! i (1+ i)))
  1061. (= i n)))))
  1062. (with-test-prefix "from body"
  1063. (pass-if "first"
  1064. (while #t
  1065. (break)
  1066. (unreachable))
  1067. #t)
  1068. (do ((n 0 (1+ n)))
  1069. ((> n 5))
  1070. (pass-if n
  1071. (let ((cond (make-iterations-cond n))
  1072. (i 0))
  1073. (while #t
  1074. (if (not (cond))
  1075. (begin
  1076. (break)
  1077. (unreachable)))
  1078. (set! i (1+ i)))
  1079. (= i n)))))
  1080. (pass-if "from nested"
  1081. (while #t
  1082. (let ((outer-break break))
  1083. (while #t
  1084. (outer-break)
  1085. (unreachable)))
  1086. (unreachable))
  1087. #t)
  1088. (pass-if "from recursive"
  1089. (let ((outer-break #f))
  1090. (define (r n)
  1091. (while #t
  1092. (if (eq? n 'outer)
  1093. (begin
  1094. (set! outer-break break)
  1095. (r 'inner))
  1096. (begin
  1097. (outer-break)
  1098. (unreachable))))
  1099. (if (eq? n 'inner)
  1100. (error "broke only from inner loop")))
  1101. (r 'outer))
  1102. #t))
  1103. (with-test-prefix "continue"
  1104. (pass-if-syntax-error "too many args" exception:too-many-args
  1105. (eval '(while #t
  1106. (continue 1))
  1107. (interaction-environment)))
  1108. (with-test-prefix "from cond"
  1109. (do ((n 0 (1+ n)))
  1110. ((> n 5))
  1111. (pass-if n
  1112. (let ((cond (make-iterations-cond n))
  1113. (i 0))
  1114. (while (if (cond)
  1115. (begin
  1116. (set! i (1+ i))
  1117. (continue)
  1118. (unreachable))
  1119. #f)
  1120. (unreachable))
  1121. (= i n)))))
  1122. (with-test-prefix "from body"
  1123. (do ((n 0 (1+ n)))
  1124. ((> n 5))
  1125. (pass-if n
  1126. (let ((cond (make-iterations-cond n))
  1127. (i 0))
  1128. (while (cond)
  1129. (set! i (1+ i))
  1130. (continue)
  1131. (unreachable))
  1132. (= i n)))))
  1133. (pass-if "from nested"
  1134. (let ((cond (make-iterations-cond 3)))
  1135. (while (cond)
  1136. (let ((outer-continue continue))
  1137. (while #t
  1138. (outer-continue)
  1139. (unreachable)))))
  1140. #t)
  1141. (pass-if "from recursive"
  1142. (let ((outer-continue #f))
  1143. (define (r n)
  1144. (let ((cond (make-iterations-cond 3))
  1145. (first #t))
  1146. (while (begin
  1147. (if (and (not first)
  1148. (eq? n 'inner))
  1149. (error "continued only to inner loop"))
  1150. (cond))
  1151. (set! first #f)
  1152. (if (eq? n 'outer)
  1153. (begin
  1154. (set! outer-continue continue)
  1155. (r 'inner))
  1156. (begin
  1157. (outer-continue)
  1158. (unreachable))))))
  1159. (r 'outer))
  1160. #t)))
  1161. (with-test-prefix "syntax-rules"
  1162. (pass-if-equal "custom ellipsis within normal ellipsis"
  1163. '((((a x) (a y) (a …))
  1164. ((b x) (b y) (b …))
  1165. ((c x) (c y) (c …)))
  1166. (((a x) (b x) (c x))
  1167. ((a y) (b y) (c y))
  1168. ((a …) (b …) (c …))))
  1169. (let ()
  1170. (define-syntax foo
  1171. (syntax-rules ()
  1172. ((_ y ...)
  1173. (syntax-rules … ()
  1174. ((_ x …)
  1175. '((((x y) ...) …)
  1176. (((x y) …) ...)))))))
  1177. (define-syntax bar (foo x y …))
  1178. (bar a b c)))
  1179. (pass-if-equal "normal ellipsis within custom ellipsis"
  1180. '((((a x) (a y) (a z))
  1181. ((b x) (b y) (b z))
  1182. ((c x) (c y) (c z)))
  1183. (((a x) (b x) (c x))
  1184. ((a y) (b y) (c y))
  1185. ((a z) (b z) (c z))))
  1186. (let ()
  1187. (define-syntax foo
  1188. (syntax-rules … ()
  1189. ((_ y …)
  1190. (syntax-rules ()
  1191. ((_ x ...)
  1192. '((((x y) …) ...)
  1193. (((x y) ...) …)))))))
  1194. (define-syntax bar (foo x y z))
  1195. (bar a b c)))
  1196. ;; This test is given in SRFI-46.
  1197. (pass-if-equal "custom ellipsis is handled hygienically"
  1198. '((1) 2 (3) (4))
  1199. (let-syntax
  1200. ((f (syntax-rules ()
  1201. ((f ?e)
  1202. (let-syntax
  1203. ((g (syntax-rules --- ()
  1204. ((g (??x ?e) (??y ---))
  1205. '((??x) ?e (??y) ---)))))
  1206. (g (1 2) (3 4)))))))
  1207. (f ---))))
  1208. (with-test-prefix "syntax-error"
  1209. (pass-if-syntax-error "outside of macro without args"
  1210. "test error"
  1211. (eval '(syntax-error "test error")
  1212. (interaction-environment)))
  1213. (pass-if-syntax-error "outside of macro with args"
  1214. "test error x \\(y z\\)"
  1215. (eval '(syntax-error "test error" x (y z))
  1216. (interaction-environment)))
  1217. (pass-if-equal "within macro"
  1218. '(simple-let
  1219. "expected an identifier but got (z1 z2)"
  1220. (simple-let ((y (* x x))
  1221. ((z1 z2) (values x x)))
  1222. (+ y 1)))
  1223. (catch 'syntax-error
  1224. (lambda ()
  1225. (eval '(let ()
  1226. (define-syntax simple-let
  1227. (syntax-rules ()
  1228. ((_ (head ... ((x . y) val) . tail)
  1229. body1 body2 ...)
  1230. (syntax-error
  1231. "expected an identifier but got"
  1232. (x . y)))
  1233. ((_ ((name val) ...) body1 body2 ...)
  1234. ((lambda (name ...) body1 body2 ...)
  1235. val ...))))
  1236. (define (foo x)
  1237. (simple-let ((y (* x x))
  1238. ((z1 z2) (values x x)))
  1239. (+ y 1)))
  1240. foo)
  1241. (interaction-environment))
  1242. (error "expected syntax-error exception"))
  1243. (lambda (k who what where form . maybe-subform)
  1244. (list who what form)))))
  1245. (with-test-prefix "syntax-case"
  1246. (pass-if-syntax-error "duplicate pattern variable"
  1247. '(syntax-case . "duplicate pattern variable")
  1248. (eval '(lambda (e)
  1249. (syntax-case e ()
  1250. ((a b c d e d f) #f)))
  1251. (interaction-environment)))
  1252. (with-test-prefix "misplaced ellipses"
  1253. (pass-if-syntax-error "bare ellipsis"
  1254. '(syntax-case . "misplaced ellipsis")
  1255. (eval '(lambda (e)
  1256. (syntax-case e ()
  1257. (... #f)))
  1258. (interaction-environment)))
  1259. (pass-if-syntax-error "ellipsis singleton"
  1260. '(syntax-case . "misplaced ellipsis")
  1261. (eval '(lambda (e)
  1262. (syntax-case e ()
  1263. ((...) #f)))
  1264. (interaction-environment)))
  1265. (pass-if-syntax-error "ellipsis in car"
  1266. '(syntax-case . "misplaced ellipsis")
  1267. (eval '(lambda (e)
  1268. (syntax-case e ()
  1269. ((... . _) #f)))
  1270. (interaction-environment)))
  1271. (pass-if-syntax-error "ellipsis in cdr"
  1272. '(syntax-case . "misplaced ellipsis")
  1273. (eval '(lambda (e)
  1274. (syntax-case e ()
  1275. ((_ . ...) #f)))
  1276. (interaction-environment)))
  1277. (pass-if-syntax-error "two ellipses in the same list"
  1278. '(syntax-case . "misplaced ellipsis")
  1279. (eval '(lambda (e)
  1280. (syntax-case e ()
  1281. ((x ... y ...) #f)))
  1282. (interaction-environment)))
  1283. (pass-if-syntax-error "three ellipses in the same list"
  1284. '(syntax-case . "misplaced ellipsis")
  1285. (eval '(lambda (e)
  1286. (syntax-case e ()
  1287. ((x ... y ... z ...) #f)))
  1288. (interaction-environment)))))
  1289. (with-test-prefix "with-ellipsis"
  1290. (pass-if-equal "simple"
  1291. '(a 1 2 3)
  1292. (let ()
  1293. (define-syntax define-quotation-macros
  1294. (lambda (x)
  1295. (syntax-case x ()
  1296. ((_ (macro-name head-symbol) ...)
  1297. #'(begin (define-syntax macro-name
  1298. (lambda (x)
  1299. (with-ellipsis …
  1300. (syntax-case x ()
  1301. ((_ x …)
  1302. #'(quote (head-symbol x …)))))))
  1303. ...)))))
  1304. (define-quotation-macros (quote-a a) (quote-b b))
  1305. (quote-a 1 2 3)))
  1306. (pass-if-equal "disables normal ellipsis"
  1307. '(a ...)
  1308. (let ()
  1309. (define-syntax foo
  1310. (lambda (x)
  1311. (with-ellipsis …
  1312. (syntax-case x ()
  1313. ((_)
  1314. #'(quote (a ...)))))))
  1315. (foo)))
  1316. (pass-if-equal "doesn't affect ellipsis for generated code"
  1317. '(a b c)
  1318. (let ()
  1319. (define-syntax quotation-macro
  1320. (lambda (x)
  1321. (with-ellipsis …
  1322. (syntax-case x ()
  1323. ((_)
  1324. #'(lambda (x)
  1325. (syntax-case x ()
  1326. ((_ x ...)
  1327. #'(quote (x ...))))))))))
  1328. (define-syntax kwote (quotation-macro))
  1329. (kwote a b c)))
  1330. (pass-if-equal "propagates into syntax binders"
  1331. '(a b c)
  1332. (let ()
  1333. (with-ellipsis …
  1334. (define-syntax kwote
  1335. (lambda (x)
  1336. (syntax-case x ()
  1337. ((_ x …)
  1338. #'(quote (x …))))))
  1339. (kwote a b c))))
  1340. (pass-if-equal "works with local-eval"
  1341. 5
  1342. (let ((env (with-ellipsis … (the-environment))))
  1343. (local-eval '(syntax-case #'(a b c d e) ()
  1344. ((x …)
  1345. (length #'(x …))))
  1346. env))))
  1347. (with-test-prefix "syntax objects"
  1348. (let ((interpreted (eval '#'(foo bar baz) (current-module)))
  1349. (interpreted-bis (eval '#'(foo bar baz) (current-module)))
  1350. (compiled ((@ (system base compile) compile) '#'(foo bar baz)
  1351. #:env (current-module))))
  1352. ;; Guile's expander doesn't wrap lists.
  1353. (pass-if "interpreted syntax object?"
  1354. (and (list? interpreted)
  1355. (and-map syntax? interpreted)))
  1356. (pass-if "compiled syntax object?"
  1357. (and (list? compiled)
  1358. (and-map syntax? compiled)))
  1359. (pass-if "interpreted syntax objects are not vectors"
  1360. (not (vector? interpreted)))
  1361. (pass-if "compiled syntax objects are not vectors"
  1362. (not (vector? compiled)))
  1363. (pass-if-equal "syntax objects comparable with equal? (eval/eval)"
  1364. interpreted interpreted-bis)
  1365. (pass-if-equal "syntax objects comparable with equal? (eval/compile)"
  1366. interpreted compiled)
  1367. (pass-if-equal "syntax objects hash the same (eval/eval)"
  1368. (hash interpreted most-positive-fixnum)
  1369. (hash interpreted-bis most-positive-fixnum))
  1370. (pass-if-equal "syntax objects hash the same (eval/compile)"
  1371. (hash interpreted most-positive-fixnum)
  1372. (hash compiled most-positive-fixnum))))
  1373. ;;; Local Variables:
  1374. ;;; eval: (put 'pass-if-syntax-error 'scheme-indent-function 1)
  1375. ;;; eval: (put 'with-ellipsis 'scheme-indent-function 1)
  1376. ;;; End: