summary refs log tree commit diff
path: root/haskell/app/Lift.hs
diff options
context:
space:
mode:
Diffstat (limited to 'haskell/app/Lift.hs')
-rw-r--r--haskell/app/Lift.hs26
1 files changed, 26 insertions, 0 deletions
diff --git a/haskell/app/Lift.hs b/haskell/app/Lift.hs
new file mode 100644
index 0000000..12f9bc6
--- /dev/null
+++ b/haskell/app/Lift.hs
@@ -0,0 +1,26 @@
+module Lift where
+
+import Data.Functor.Foldable
+import Data.List
+import Types
+
+converge f a = let a' = f a in if a' == a then a else converge f a'
+
+-- | R-Algebra to move external variables to arguments
+liftArgs :: AExpF (AExp, ([String], AExp)) -> ([String], AExp)
+liftArgs = undefined -- paramorphism
+
+-- | F-Algebras to find free variables
+findVars :: CExpF [String] -> [String]
+findVars (LetF ident fc rest) = converge (\\ [ident]) $ rest ++ (cata findVarsFC fc)
+findVars (IfF cond t e) = t ++ e ++ (cata findVarsAExp cond)
+findVars (FCF fc) = cata findVarsFC fc
+
+findVarsFC :: FuncallF [String] -> [String]
+findVarsFC (AtomF aexp) = cata findVarsAExp aexp
+findVarsFC (CallF id args) = id : (args >>= cata findVarsAExp)
+
+findVarsAExp :: AExpF [String] -> [String]
+findVarsAExp (IdentF ns) = [ns]
+findVarsAExp (LamF args cexp) = converge (\\ args) (fold findVars cexp)
+findVarsAExp def = foldMap id def