main.rkt
#lang racket
(provide until while
         continue break)

(define-syntax while
  (syntax-rules (and else)
    [(while (and (<sub-condition> else
                                  <result-statement>
                                  ...)
                 ...)
       <body-statement>
       ...)
     (until (or ((not <sub-condition>) then
                                       <result-statement>
                                       ...)
                ...)
       <body-statement>
       ...)]
    [(while <pre-condition>
       <body-statement>
       ...)
     (while (and (<pre-condition> else))
       <body-statement>
       ...)]))


(require racket/stxparam)
;
(define-for-syntax (error-use stx)
  (raise-syntax-error
   #f ; 'false' not in macro environment.
   "can only be used inside 'until' or 'while' body"
   stx))
(define-syntax-parameter break error-use)
(define-syntax-parameter continue error-use)
;
(define-syntax until
  (syntax-rules (or)
    [(until (or <alternative>
                ...)
       <body-statement>
       ...)
     (let/ec brk
       (let loop ()
         (cond [(or-then <alternative> ...)]
               [else (let/ec cntn
                       (syntax-parameterize
                        ([continue (make-rename-transformer #'cntn)]
                         [break (make-rename-transformer #'brk)])
                        <body-statement> ...))
                     (loop)])))]
    [(until <post-condition>
       <body-statement>
       ...)
     (until (or <post-condition>)
       <body-statement>
       ...)]))
;
(define-syntax or-then
  (syntax-rules (then)
    [(or-then (<condition> then
                           <result>
                           ...)
              <clause>
              ...)
     (cond [<condition> <result> ...]
           [else (or-then <clause> ...)])]
    [(or-then <condition>
              <clause>
              ...)
     (or-then (<condition> then)
              <clause>
              ...)]
    [(or-then)
     #f]))