#lang racket
(require syntax/parse
(for-syntax syntax/parse))
(provide bcond)
(define-syntax (bcond stx)
(define-syntax-class distinct-identifiers
#:description "sequence of distinct identifiers"
(pattern (x:identifier ...)
#:fail-when (check-duplicate-identifier
(syntax->list #'(x ...)))
"duplicate variable name"
#:with (var ...) #'(x ...)))
(syntax-parse stx #:literals (else => let let-values)
[(bcond)
#'(void)]
[(bcond [let ~! x:identifier e:expr] clause ...)
#'(let ([x e]) (bcond clause ...))]
[(bcond [let-values ~! xs:distinct-identifiers e:expr] clause ...)
#'(let-values ([(xs.var ...) e]) (bcond clause ...))]
[(bcond [else ~! body:expr ...+] . _)
#'(begin body ...)]
[(bcond [e1:expr => ~! e2:expr] clause ...)
#'(let ([tmp e1])
(if tmp (e2 tmp) (bcond clause ...)))]
[(bcond [e:expr] clause ...)
#'(let ([tmp e])
(if tmp tmp (bcond clause ...)))]
[(bcond [e1:expr body:expr ...+] clause ...)
#'(if e1 (begin body ...) (bcond clause ...))]))