3.4 Solution for Exercise 17

The main macro, minimatch1, just evaluates the expression to match and stores it in a private variable. The helper macro, minimatch1*, does all of the work.

(define-syntax-rule (minimatch1 val-expr pattern result-expr)
  (let ([v val-expr])
    (minimatch1* v pattern result-expr)))

We have no way (yet) of writing a pattern that recognizes just identifiers; so we put the variable case last. Otherwise, the “variable” case would match the other two kinds of patterns as well, resulting in syntax errors from let.

(define-syntax minimatch1*
  (syntax-rules (cons quote)
    [(minimatch1* v-pv (quote datum) result-expr)
     (if (equal? v-pv (quote datum))
         result-expr
         (error 'minimatch1 "match failed"))]
    [(minimatch1* v-pv (cons first-pattern rest-pattern) result-expr)
     (if (pair? v-pv)
         (let ([first-var (car v-pv)]
               [rest-var (cdr v-pv)])
           (minimatch1* first-var first-pattern
                        (minimatch1* rest-var rest-pattern result-expr)))
         (error 'minimatch1 "match failed"))]
    [(minimatch1* v-pv variable-id result-expr)
     (let ([variable-id v-pv])
       result-expr)]))