adding ☠ and changing cond behavior
This commit is contained in:
parent
1457d23fe2
commit
124e97acf2
|
@ -5,6 +5,7 @@
|
||||||
racket/generic
|
racket/generic
|
||||||
racket/syntax
|
racket/syntax
|
||||||
syntax/parse)
|
syntax/parse)
|
||||||
|
syntax/quote
|
||||||
syntax/parse/define
|
syntax/parse/define
|
||||||
remix/stx/singleton-struct0
|
remix/stx/singleton-struct0
|
||||||
racket/stxparam)
|
racket/stxparam)
|
||||||
|
@ -286,9 +287,28 @@
|
||||||
(syntax-parameterize ([remix-cut-$ (make-rename-transformer #'x)])
|
(syntax-parameterize ([remix-cut-$ (make-rename-transformer #'x)])
|
||||||
body)))]))
|
body)))]))
|
||||||
|
|
||||||
|
(define-syntax (impossible! stx)
|
||||||
|
(syntax-parse stx
|
||||||
|
[(_ fun msg loc)
|
||||||
|
(quasisyntax/loc stx
|
||||||
|
(raise-syntax-error fun msg
|
||||||
|
(quote-syntax/keep-srcloc #,#'loc)))]
|
||||||
|
[_
|
||||||
|
(quasisyntax/loc stx
|
||||||
|
(raise-syntax-error '☠ "Unreachable code has been reached"
|
||||||
|
(quote-syntax/keep-srcloc #,stx)))]))
|
||||||
|
|
||||||
(define-syntax (remix-cond stx)
|
(define-syntax (remix-cond stx)
|
||||||
(syntax-parse stx
|
(syntax-parse stx
|
||||||
#:literals (#%brackets)
|
#:literals (#%brackets)
|
||||||
|
[(_ . (~and (cond-arg ...)
|
||||||
|
(_ ... (#%brackets (~not #:else) . _))))
|
||||||
|
(quasisyntax/loc stx
|
||||||
|
(remix-cond cond-arg ...
|
||||||
|
(#%brackets
|
||||||
|
#:else (impossible! 'cond
|
||||||
|
"non-existent default case reached"
|
||||||
|
#,stx))))]
|
||||||
[(_ (~and before:expr (~not (#%brackets . any:expr))) ...
|
[(_ (~and before:expr (~not (#%brackets . any:expr))) ...
|
||||||
(#%brackets #:else . answer-body:expr))
|
(#%brackets #:else . answer-body:expr))
|
||||||
(syntax/loc stx
|
(syntax/loc stx
|
||||||
|
@ -296,23 +316,25 @@
|
||||||
[(_ (~and before:expr (~not (#%brackets . any:expr))) ...
|
[(_ (~and before:expr (~not (#%brackets . any:expr))) ...
|
||||||
(#%brackets question:expr . answer-body:expr)
|
(#%brackets question:expr . answer-body:expr)
|
||||||
. more:expr)
|
. more:expr)
|
||||||
(syntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(remix-block before ...
|
(remix-block before ...
|
||||||
(if question
|
(if question
|
||||||
(remix-block . answer-body)
|
(remix-block . answer-body)
|
||||||
(remix-cond . more))))]))
|
#,(syntax/loc #'more (remix-cond . more)))))]))
|
||||||
|
|
||||||
(provide def def*
|
(provide def def*
|
||||||
(for-syntax gen:def-transformer
|
(for-syntax gen:def-transformer
|
||||||
gen:def*-transformer)
|
gen:def*-transformer)
|
||||||
(rename-out [def ≙]
|
(rename-out [def ≙] ;; \defs
|
||||||
[def :=]
|
[def :=]
|
||||||
[def* ≙*]
|
[def* ≙*]
|
||||||
[def* :=*]
|
[def* :=*]
|
||||||
[def* nest])
|
[def* nest])
|
||||||
(rename-out [remix-λ λ]
|
(rename-out [remix-λ λ] ;; \lambda
|
||||||
[remix-cond cond]
|
[remix-cond cond]
|
||||||
[remix-cut-$ $])
|
[remix-cut-$ $])
|
||||||
|
impossible!
|
||||||
|
(rename-out [impossible! ☠])
|
||||||
#%rest
|
#%rest
|
||||||
(rename-out [remix-block block])
|
(rename-out [remix-block block])
|
||||||
#%brackets
|
#%brackets
|
||||||
|
@ -324,7 +346,7 @@
|
||||||
(for-syntax gen:dot-transformer)
|
(for-syntax gen:dot-transformer)
|
||||||
(rename-out [remix-#%app #%app])
|
(rename-out [remix-#%app #%app])
|
||||||
(for-syntax gen:app-dot-transformer)
|
(for-syntax gen:app-dot-transformer)
|
||||||
(rename-out [... …])
|
(rename-out [... …]) ;; \ldots
|
||||||
#%datum
|
#%datum
|
||||||
quote
|
quote
|
||||||
unquote
|
unquote
|
||||||
|
|
|
@ -45,13 +45,7 @@
|
||||||
|
|
||||||
;; cond requires []s for the question-answer pairs. It uses this to
|
;; cond requires []s for the question-answer pairs. It uses this to
|
||||||
;; make any code in between clauses go in between the `if`s that pop
|
;; make any code in between clauses go in between the `if`s that pop
|
||||||
;; out of the cond macro. finally, cond REQUIRES a #:else clause.
|
;; out of the cond macro.
|
||||||
;;
|
|
||||||
;; XXX Robby does not like requiring else, but does want a default
|
|
||||||
;; error.
|
|
||||||
;;
|
|
||||||
;; XXX make an (impossible!) macro that is a useful
|
|
||||||
;; default #:else
|
|
||||||
(def (g x)
|
(def (g x)
|
||||||
(cond
|
(cond
|
||||||
[(< x 100) "100"]
|
[(< x 100) "100"]
|
||||||
|
@ -63,6 +57,25 @@
|
||||||
{(g 199) ≡ "div 100"}
|
{(g 199) ≡ "div 100"}
|
||||||
{(g 200) ≡ 100})
|
{(g 200) ≡ 100})
|
||||||
|
|
||||||
|
;; If cond reaches the end without an else, then a runtime error is
|
||||||
|
;; generated
|
||||||
|
(def (g2 x)
|
||||||
|
(cond
|
||||||
|
[(< x 100) "100"]
|
||||||
|
(def z (/ x 2))
|
||||||
|
[(< z 100) "div 100"]))
|
||||||
|
(module+ test
|
||||||
|
{(g2 50) ≡ "100"}
|
||||||
|
{(g2 199) ≡ "div 100"}
|
||||||
|
;; This is the error test:
|
||||||
|
#;(g2 200))
|
||||||
|
|
||||||
|
;; This functionality is provided by ☠ (aka impossible!)
|
||||||
|
(def (g3)
|
||||||
|
☠)
|
||||||
|
(module+ test
|
||||||
|
#;(g3))
|
||||||
|
|
||||||
;; the @ reader is always on. One fun thing about this is that you can
|
;; the @ reader is always on. One fun thing about this is that you can
|
||||||
;; make non-() macros. I wrote a little helper function to turn the
|
;; make non-() macros. I wrote a little helper function to turn the
|
||||||
;; string arguments that @{} produces into a string port that has
|
;; string arguments that @{} produces into a string port that has
|
||||||
|
|
Loading…
Reference in New Issue
Block a user