module Elaborator where import Data.List (elemIndex) import Expr (Expr) import qualified Expr as E import IR (IRExpr) import qualified IR as I type Binders = [Text] elaborate :: IRExpr -> Expr elaborate ir = evalState (elaborate' ir) [] where elaborate' :: IRExpr -> State Binders Expr elaborate' (I.Var n) = do binders <- get pure $ E.Var n . fromIntegral <$> elemIndex n binders ?: E.Free n elaborate' (I.Level level) = pure $ E.Level level elaborate' (I.App m n) = E.App <$> elaborate' m <*> elaborate' n elaborate' (I.Abs x t b) = do t' <- elaborate' t modify (x :) E.Abs x t' <$> elaborate' b elaborate' (I.Pi x t b) = do t' <- elaborate' t modify (x :) E.Pi x t' <$> elaborate' b elaborate' (I.Let name Nothing val body) = E.Let name Nothing <$> elaborate' val <*> elaborate' body elaborate' (I.Let name (Just t) val body) = E.Let name . Just <$> elaborate' t <*> elaborate' val <*> elaborate' body