{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}

import Text.Puggle

data Expr =
  | Lam String Expr
  | App Expr Expr
  | Var String
  | Lit Num
    deriving (Eq, Show)

[puggle|

top :: Expr
  = expr !.

expr :: Expr
  = "\\" var "." expr  { Lam $1 $2 }
  / "let" var[>] "="[>] expr[>] "in"[>] expr[>]
      { App (Lam $1 $3) $2 }
  / var  { Var $1 }
  / num  { Num $1 }

var ::: String
  = [A-Za-z_] [A-Za-z0-9_]*  { $1 : $2 }

num ::: String
  = [1-9] [0-9]*  { read ($1 : $2) }

]

main :: IO ()
main = print . parseString top "<stdin>" =<< getContents
