
macro ( ('let x y) )
      ( (λ x . ()) y );

macro ('match t ps) (tail(
   (let (uuid term) (maybe-deref t))
   (match-pats( (uuid term) ps (fail PatternMatchFailure_s) ))
));

macro ('match-pats( term () remainder )) (
   remainder
);

macro ('match-pats( term (ps (lhs rhs)) remainder )) (
   (match-pats(
      term
      ps
      (match-pats-arm( term lhs rhs remainder ))
   ))
);

macro ('match-pats-arm( term (:Variable: v) rhs remainder )) (
   if (tail( (let v (maybe-deref term)) (branchtrue()) ))
      rhs
      remainder
);

macro ('match-pats-arm( term (:Literal: l) rhs remainder )) (
   if (tail( (let (uuid v) (maybe-deref term)) (==( (uuid v) l )) ))
      rhs
      remainder
);

macro ('match-pats-arm( term (:Tag: l lt) rhs remainder )) (
   if (tail( (let (uuid v) (maybe-deref term)) (==( (.0( (uuid v) )) l )) ))
      rhs
      remainder
);

macro ('match-pats-arm( term ((:Tag: l lt) ( x1 )) rhs remainder )) (tail(
   (let (uuid v) (maybe-deref term) )
   (if (==( (.0( (uuid v) )) l )) (
      (match-pats-arm( (.1( (as (uuid v) lt) )) x1 rhs remainder )) 
   ) remainder)
));

macro ('match-pats-arm( term ((:Tag: l lt) ( x2 x1 )) rhs remainder )) (tail(
   (let (uuid v) (maybe-deref term) )
   (if (==( (.0( (uuid v) )) l )) (
      (match-pats-arm( (.1( (as (uuid v) lt) )) x1 (
         (match-pats-arm( (.2( (as (uuid v) lt) )) x2 rhs remainder ))
      ) remainder )) 
   ) remainder)
));

