;; reader macro (rune) #.(begin (def $10 'nothing) (assert (not (get-reader-macro #\$))) (assert (not (get-reader-macro #\€))) (assert (not (get-reader-macro #\!))) (def (capital s m) (when (equal? m "!") (return (void (read s)))) `(cons ',(case m ("$" 'usd) ("€" 'eur)) ,(read s))) (assert (void? (set-reader-macro! #\$ capital))) (assert (void? (set-reader-macro! #\€ capital))) (assert (void? (set-reader-macro! #\! capital))) (assert (eq? (get-reader-macro #\$) capital)) (assert (eq? (get-reader-macro #\€) capital)) (assert (eq? (get-reader-macro #\!) capital))) #.(begin (assert (equal? $10 '(usd . 10))) (assert (equal? €20 '(eur . 20))) (assert (equal? (list $10 !10) '((usd . 10)))) (assert (not (list !10))) (assert (void? (set-reader-macro! "$" NIL)))) ; the fall of the US empire #.(begin (assert (equal? $10 'nothing))) ;; reader macro (string) #.(begin (def (to-path s m) (let* {[next (io-peek s 'rune)] [path (if (or (rune-whitespace? next) (eq? next #\))) (subseq m 1) (str (subseq m 1) (read s)))]} `(cons 'path ,path))) (assert (void? (set-reader-macro! "@." to-path))) (assert (void? (set-reader-macro! "@/" to-path))) (assert (eq? (get-reader-macro "@.") to-path)) (assert (eq? (get-reader-macro "@/") to-path))) #.(begin (assert (equal? '(path . ".") @.)) (assert (equal? '(path . "../a") @../a)) (assert (equal? '(path . "./test/blah.txt") @./test/blah.txt)) (assert (equal? '(path . "/absolute/path.txt") @/absolute/path.txt))) ;; read-list-until #.(begin (def s (buffer ">11 >22 >33>>44 55>>66")) (assert (equal? (read-list-until ">>" s) '(>11 >22 >33))) (assert (equal? (read s) 44))) ;; read-list-until and reader macros #.(begin (assert (void? (set-reader-macro! "<<" (λ (s m) `(list ,@(read-list-until ">>" s)))))) (def s (buffer "<<€1 €2 €3>>1 2")) (assert (equal? (eval (read s)) '((eur . 1) (eur . 2) (eur . 3)))) (assert (equal? (read s) 1))) ;; two reader macros with read-list-until within each other #.(begin (assert (void? (set-reader-macro! "%%" (λ (s r) `(list ,@(read-list-until "$$" s)))))) (def s (buffer "<<%%1$$>>")) (assert (equal? (eval (read s)) '((1)))) (def s (buffer "<<%% 1 >> $$")) (assert-fail (read s) parse-error))