shithub: MicroHs

Download patch

ref: eea5c5c8e74312b821a51bbd49c3f18edd05e2f5
parent: 772600423d69a6f98c1219690223368ddf0ba46d
author: Lennart Augustsson <lennart@augustsson.net>
date: Mon Dec 25 06:42:45 EST 2023

Add missing file.

--- a/MicroHs.cabal
+++ b/MicroHs.cabal
@@ -43,6 +43,7 @@
   other-modules:       MicroHs.Abstract
                        MicroHs.Compile
                        MicroHs.CompileCache
+                       MicroHs.Deriving
                        MicroHs.Desugar
                        MicroHs.EncodeData
                        MicroHs.Exp
--- /dev/null
+++ b/src/MicroHs/Deriving.hs
@@ -1,0 +1,57 @@
+module MicroHs.Deriving(expandField) where
+import Prelude
+import Data.Function
+import Data.List
+import MicroHs.Expr
+import MicroHs.Ident
+import MicroHs.TCMonad
+
+expandField :: EDef -> T [EDef]
+expandField def@(Data lhs cs) = (def:) <$> genHasFields lhs cs
+expandField def = return [def]
+
+genHasFields :: LHS -> [Constr] -> T [EDef]
+genHasFields lhs cs = do
+  let fldtys = nubBy ((==) `on` fst) [ (fld, ty) | Constr _ _ _ (Right fs) <- cs, (fld, (_, ty)) <- fs ]
+--      flds = map fst fldtys
+  mapM (genHasField lhs cs) fldtys
+
+genHasField :: LHS -> [Constr] -> (Ident, EType) -> T EDef
+genHasField (tycon, iks) cs (fld, fldty) = do
+  mn <- gets moduleName
+  let loc = getSLoc tycon
+      qtycon = qualIdent mn tycon
+      dum = EVar dummyIdent
+      eFld = EVar fld
+      undef = EVar $ mkIdentSLoc loc "undefined"  -- XXX could be nicer
+      iHasField = mkIdentSLoc loc nameHasField
+      ihasField = mkIdentSLoc loc namehasField
+      hdr = eForall iks $ eApp3 (EVar iHasField)
+                                  (ELit loc (LStr (unIdent fld)))
+                                  (eApps (EVar qtycon) (map (EVar . idKindIdent) iks))
+                                  fldty
+      conEqn (Constr _ _ c (Left ts))   = eEqn [dum, eApps (EVar c) (map (const dum) ts)] $ undef
+      conEqn (Constr _ _ c (Right fts)) = eEqn [dum, conApp] $ if fld `elem` fs then rhs else undef
+        where fs = map fst fts
+              conApp = eApps (EVar c) (map EVar fs)
+              rhs = ETuple [eFld, eLam [eFld] conApp]
+  pure $ Instance hdr [BFcn ihasField $ map conEqn cs]
+
+eApp2 :: Expr -> Expr -> Expr -> Expr
+eApp2 a b c = EApp (EApp a b) c
+
+eApp3 :: Expr -> Expr -> Expr -> Expr -> Expr
+eApp3 a b c d = EApp (eApp2 a b c) d
+
+eApps :: Expr -> [Expr] -> Expr
+eApps = foldl EApp
+
+eForall :: [IdKind] -> EType -> EType
+eForall [] t = t
+eForall vs t = EForall vs t
+
+nameHasField :: String
+nameHasField = "Data.Record.HasField"
+
+namehasField :: String
+namehasField = "hasField"
--