srfi-105.test 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. ;;;; srfi-105.test --- Test suite for Guile's SRFI-105 reader. -*- scheme -*-
  2. ;;;;
  3. ;;;; Copyright (C) 2012, 2013 Free Software Foundation, Inc.
  4. ;;;;
  5. ;;;; This library is free software; you can redistribute it and/or
  6. ;;;; modify it under the terms of the GNU Lesser General Public
  7. ;;;; License as published by the Free Software Foundation; either
  8. ;;;; version 3 of the License, or (at your option) any later version.
  9. ;;;;
  10. ;;;; This library is distributed in the hope that it will be useful,
  11. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. ;;;; Lesser General Public License for more details.
  14. ;;;;
  15. ;;;; You should have received a copy of the GNU Lesser General Public
  16. ;;;; License along with this library; if not, write to the Free Software
  17. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. (define-module (test-srfi-105)
  19. #:use-module (test-suite lib)
  20. #:use-module (srfi srfi-1))
  21. (define (read-string s)
  22. (with-input-from-string s read))
  23. (define (with-read-options opts thunk)
  24. (let ((saved-options (read-options)))
  25. (dynamic-wind
  26. (lambda ()
  27. (read-options opts))
  28. thunk
  29. (lambda ()
  30. (read-options saved-options)))))
  31. ;; Verify that curly braces are allowed in identifiers and that neoteric
  32. ;; expressions are not recognized by default.
  33. (with-test-prefix "no-curly-infix"
  34. (pass-if (equal? '({f(x) + g[y] + h{z} + [a]})
  35. `(,(string->symbol "{f")
  36. (x) + g [y] +
  37. ,(string->symbol "h{z}")
  38. + [a]
  39. ,(string->symbol "}")))))
  40. #!curly-infix
  41. (with-test-prefix "curly-infix"
  42. (pass-if (equal? '{n <= 5} '(<= n 5)))
  43. (pass-if (equal? '{x + 1} '(+ x 1)))
  44. (pass-if (equal? '{a + b + c} '(+ a b c)))
  45. (pass-if (equal? '{x ,op y ,op z} '(,op x y z)))
  46. (pass-if (equal? '{x eqv? `a} '(eqv? x `a)))
  47. (pass-if (equal? '{'a eq? b} '(eq? 'a b)))
  48. (pass-if (equal? '{n-1 + n-2} '(+ n-1 n-2)))
  49. (pass-if (equal? '{a * {b + c}} '(* a (+ b c))))
  50. (pass-if (equal? '{a + {b - c}} '(+ a (- b c))))
  51. (pass-if (equal? '{{a + b} - c} '(- (+ a b) c)))
  52. (pass-if (equal? '{{a > 0} and {b >= 1}} '(and (> a 0) (>= b 1))))
  53. (pass-if (equal? '{} '()))
  54. (pass-if (equal? '{5} '5))
  55. (pass-if (equal? '{- x} '(- x)))
  56. (pass-if (equal? '{length(x) >= 6} '(>= (length x) 6)))
  57. (pass-if (equal? '{f(x) + g(y) + h(z)} '(+ (f x) (g y) (h z))))
  58. (pass-if (equal? '{(f a b) + (g h)} '(+ (f a b) (g h))))
  59. (pass-if (equal? '{f(a b) + g(h)} '(+ (f a b) (g h))))
  60. (pass-if (equal? ''{a + f(b) + x} ''(+ a (f b) x)))
  61. (pass-if (equal? '{(- a) / b} '(/ (- a) b)))
  62. (pass-if (equal? '{-(a) / b} '(/ (- a) b)))
  63. (pass-if (equal? '{cos(q)} '(cos q)))
  64. (pass-if (equal? '{e{}} '(e)))
  65. (pass-if (equal? '{pi{}} '(pi)))
  66. (pass-if (equal? '{'f(x)} '(quote (f x))))
  67. (pass-if (equal? '{ (f (g h(x))) } '(f (g (h x)))))
  68. (pass-if (equal? '{#(1 2 f(a) 4)} '#(1 2 (f a) 4)))
  69. (pass-if (equal? '{ (f #;g(x) h(x)) } '(f (h x))))
  70. (pass-if (equal? '{ (f #; g(x)[y] h(x)) } '(f (h x))))
  71. (pass-if (equal? '{ (f #; g[x]{y} h(x)) } '(f (h x))))
  72. (pass-if (equal? '{ (f #(g h(x))) } '(f #(g (h x)))))
  73. (pass-if (equal? '{ (f '(g h(x))) } '(f '(g (h x)))))
  74. (pass-if (equal? '{ (f `(g h(x))) } '(f `(g (h x)))))
  75. (pass-if (equal? '{ (f #'(g h(x))) } '(f #'(g (h x)))))
  76. (pass-if (equal? '{ (f #2((g) (h(x)))) } '(f #2((g) ((h x))))))
  77. (pass-if (equal? '{(map - ns)} '(map - ns)))
  78. (pass-if (equal? '{map(- ns)} '(map - ns)))
  79. (pass-if (equal? '{n * factorial{n - 1}} '(* n (factorial (- n 1)))))
  80. (pass-if (equal? '{2 * sin{- x}} '(* 2 (sin (- x)))))
  81. (pass-if (equal? '{3 + 4 +} '($nfx$ 3 + 4 +)))
  82. (pass-if (equal? '{3 + 4 + 5 +} '($nfx$ 3 + 4 + 5 +)))
  83. (pass-if (equal? '{a . z} '($nfx$ a . z)))
  84. (pass-if (equal? '{a + b - c} '($nfx$ a + b - c)))
  85. (pass-if (equal? '{read(. options)} '(read . options)))
  86. (pass-if (equal? '{a(x)(y)} '((a x) y)))
  87. (pass-if (equal? '{x[a]} '($bracket-apply$ x a)))
  88. (pass-if (equal? '{y[a b]} '($bracket-apply$ y a b)))
  89. (pass-if (equal? '{f(g(x))} '(f (g x))))
  90. (pass-if (equal? '{f(g(x) h(x))} '(f (g x) (h x))))
  91. (pass-if (equal? '{} '()))
  92. (pass-if (equal? '{e} 'e))
  93. (pass-if (equal? '{e1 e2} '(e1 e2)))
  94. (pass-if (equal? '{a . t} '($nfx$ a . t)))
  95. (pass-if (equal? '{a b . t} '($nfx$ a b . t)))
  96. (pass-if (equal? '{a b c . t} '($nfx$ a b c . t)))
  97. (pass-if (equal? '{a b c d . t} '($nfx$ a b c d . t)))
  98. (pass-if (equal? '{a + b +} '($nfx$ a + b +)))
  99. (pass-if (equal? '{a + b + c +} '($nfx$ a + b + c +)))
  100. (pass-if (equal? '{q + r * s} '($nfx$ q + r * s)))
  101. ;; The following two tests will become relevant when Guile's reader
  102. ;; supports datum labels, specified in SRFI-38 (External
  103. ;; Representation for Data With Shared Structure).
  104. ;;(pass-if (equal? '{#1=f(#1#)} '#1=(f #1#)))
  105. ;;(pass-if (equal? '#1={a + . #1#} '($nfx$ . #1=(a + . #1#))))
  106. (pass-if (equal? '{e()} '(e)))
  107. (pass-if (equal? '{e{}} '(e)))
  108. (pass-if (equal? '{e(1)} '(e 1)))
  109. (pass-if (equal? '{e{1}} '(e 1)))
  110. (pass-if (equal? '{e(1 2)} '(e 1 2)))
  111. (pass-if (equal? '{e{1 2}} '(e (1 2))))
  112. (pass-if (equal? '{f{n - 1}} '(f (- n 1))))
  113. (pass-if (equal? '{f{n - 1}(x)} '((f (- n 1)) x)))
  114. (pass-if (equal? '{f{n - 1}{y - 1}} '((f (- n 1)) (- y 1))))
  115. (pass-if (equal? '{f{- x}[y]} '($bracket-apply$ (f (- x)) y)))
  116. (pass-if (equal? '{g{- x}} '(g (- x))))
  117. (pass-if (equal? '{( . e)} 'e))
  118. (pass-if (equal? '{e[]} '($bracket-apply$ e)))
  119. (pass-if (equal? '{e[1 2]} '($bracket-apply$ e 1 2)))
  120. (pass-if (equal? '{e[1 . 2]} '($bracket-apply$ e 1 . 2)))
  121. ;; Verify that source position information is not recorded if not
  122. ;; asked for.
  123. (with-test-prefix "no positions"
  124. (pass-if "simple curly-infix list"
  125. (let ((sexp (with-read-options '(curly-infix)
  126. (lambda ()
  127. (read-string " {1 + 2 + 3}")))))
  128. (and (not (source-property sexp 'line))
  129. (not (source-property sexp 'column)))))
  130. (pass-if "mixed curly-infix list"
  131. (let ((sexp (with-read-options '(curly-infix)
  132. (lambda ()
  133. (read-string " {1 + 2 * 3}")))))
  134. (and (not (source-property sexp 'line))
  135. (not (source-property sexp 'column)))))
  136. (pass-if "singleton curly-infix list"
  137. (let ((sexp (with-read-options '(curly-infix)
  138. (lambda ()
  139. (read-string " { 1.0 }")))))
  140. (and (not (source-property sexp 'line))
  141. (not (source-property sexp 'column)))))
  142. (pass-if "neoteric expression"
  143. (let ((sexp (with-read-options '(curly-infix)
  144. (lambda ()
  145. (read-string " { f(x) }")))))
  146. (and (not (source-property sexp 'line))
  147. (not (source-property sexp 'column))))))
  148. ;; Verify that source position information is properly recorded.
  149. (with-test-prefix "positions"
  150. (pass-if "simple curly-infix list"
  151. (let ((sexp (with-read-options '(curly-infix positions)
  152. (lambda ()
  153. (read-string " {1 + 2 + 3}")))))
  154. (and (equal? (source-property sexp 'line) 0)
  155. (equal? (source-property sexp 'column) 1))))
  156. (pass-if "mixed curly-infix list"
  157. (let ((sexp (with-read-options '(curly-infix positions)
  158. (lambda ()
  159. (read-string " {1 + 2 * 3}")))))
  160. (and (equal? (source-property sexp 'line) 0)
  161. (equal? (source-property sexp 'column) 1))))
  162. (pass-if "singleton curly-infix list"
  163. (let ((sexp (with-read-options '(curly-infix positions)
  164. (lambda ()
  165. (read-string " { 1.0 }")))))
  166. (and (equal? (source-property sexp 'line) 0)
  167. (case (source-property sexp 'column)
  168. ((1) (throw 'unresolved))
  169. ((3) #t)
  170. (else #f)))))
  171. (pass-if "neoteric expression"
  172. (let ((sexp (with-read-options '(curly-infix positions)
  173. (lambda ()
  174. (read-string " { f(x) }")))))
  175. (and (equal? (source-property sexp 'line) 0)
  176. (case (source-property sexp 'column)
  177. ((1) (throw 'unresolved))
  178. ((3) #t)
  179. (else #f))))))
  180. ;; Verify that neoteric expressions are recognized only within curly braces.
  181. (pass-if (equal? '(a(x)(y)) '(a (x) (y))))
  182. (pass-if (equal? '(x[a]) '(x [a])))
  183. (pass-if (equal? '(y[a b]) '(y [a b])))
  184. (pass-if (equal? '(a f{n - 1}) '(a f (- n 1))))
  185. (pass-if (equal? '(a f{n - 1}(x)) '(a f (- n 1) (x))))
  186. (pass-if (equal? '(a f{n - 1}[x]) '(a f (- n 1) [x])))
  187. (pass-if (equal? '(a f{n - 1}{y - 1}) '(a f (- n 1) (- y 1))))
  188. ;; Verify that bracket lists are not recognized by default.
  189. (pass-if (equal? '{[]} '()))
  190. (pass-if (equal? '{[a]} '(a)))
  191. (pass-if (equal? '{[a b]} '(a b)))
  192. (pass-if (equal? '{[a . b]} '(a . b)))
  193. (pass-if (equal? '[] '()))
  194. (pass-if (equal? '[a] '(a)))
  195. (pass-if (equal? '[a b] '(a b)))
  196. (pass-if (equal? '[a . b] '(a . b))))
  197. #!curly-infix-and-bracket-lists
  198. (with-test-prefix "curly-infix-and-bracket-lists"
  199. ;; Verify that these neoteric expressions still work properly
  200. ;; when the 'square-brackets' read option is unset (which is done by
  201. ;; the '#!curly-infix-and-bracket-lists' reader directive above).
  202. (pass-if (equal? '{e[]} '($bracket-apply$ e)))
  203. (pass-if (equal? '{e[1 2]} '($bracket-apply$ e 1 2)))
  204. (pass-if (equal? '{e[1 . 2]} '($bracket-apply$ e 1 . 2)))
  205. ;; The following expressions are not actually part of SRFI-105, but
  206. ;; they are handled when the 'curly-infix' read option is set and the
  207. ;; 'square-brackets' read option is unset. This is a non-standard
  208. ;; extension of SRFI-105, and follows the convention of GNU Kawa.
  209. (pass-if (equal? '{[]} '($bracket-list$)))
  210. (pass-if (equal? '{[a]} '($bracket-list$ a)))
  211. (pass-if (equal? '{[a b]} '($bracket-list$ a b)))
  212. (pass-if (equal? '{[a . b]} '($bracket-list$ a . b)))
  213. (pass-if (equal? '[] '($bracket-list$)))
  214. (pass-if (equal? '[a] '($bracket-list$ a)))
  215. (pass-if (equal? '[a b] '($bracket-list$ a b)))
  216. (pass-if (equal? '[a . b] '($bracket-list$ a . b))))