Added η-expander module and removed EAdd from grammar.

This commit is contained in:
sebastianselander 2023-05-12 16:25:03 +02:00
parent c3bcdfa81b
commit 8b92dd9194
8 changed files with 113 additions and 18 deletions

64
src/Expander.hs Normal file
View file

@ -0,0 +1,64 @@
module Expander where
import TypeChecker.TypeCheckerIr
import Control.Monad.State
type TExp = T' Exp' Type
type M = State Int
expand :: Program -> Program
expand (Program defs) = Program (map expandDef defs)
expandDef :: Def -> Def
expandDef (DBind bind) = DBind $ expandBind bind
expandDef d = d
initialState = 0
expandBind :: Bind' Type -> Bind' Type
expandBind (Bind name args e)
= Bind name args $ evalState (expandExp e) initialState
expandExp :: TExp -> M TExp
expandExp e = do
case e of
(EApp e1@(e_, _) e2@(_, _), t) -> do
let sizeType = arrows t
let sizeExp = apps e_
let diff = sizeType - sizeExp
e1' <- expandExp e1
e2' <- expandExp e2
apply diff (EApp e1' e2', t)
(EVar _, t) -> do
let sizeType = arrows t
apply sizeType e
e -> pure e
apply :: Int -> TExp -> M TExp
apply n (e, t)
| n < 1 = pure (e, t)
| otherwise = do
fr <- fresh
let (TFun t1 t2) = t
e' <- apply (n - 1) (EApp (e,t) (EVar fr, t1), t2)
pure (EAbs fr e', t)
-- Eerily similar functions
apps :: Exp -> Int
apps (EApp _ (e2, _)) = 1 + apps e2
apps _ = 0
arrows :: Type -> Int
arrows (TFun _ t2) = 1 + arrows t2
arrows _ = 0
fresh :: M Ident
fresh = do
n <- get
put (n + 1)
return (letters !! n)
where
letters :: [Ident]
letters =
map (Ident . ("eta$" ++)) $ [1 ..] >>= flip replicateM ['a' .. 'z']