@@ -42,6 +42,7 @@ import Language.PureScript.CodeGen.Cpp.File
42import Language.PureScript.CodeGen.Cpp.Optimizer
42import Language.PureScript.CodeGen.Cpp.Optimizer
43import Language.PureScript.CodeGen.Cpp.Optimizer.TCO
43import Language.PureScript.CodeGen.Cpp.Optimizer.TCO
44import Language.PureScript.CodeGen.Cpp.Types
44import Language.PureScript.CodeGen.Cpp.Types
45+import Language.PureScript.Comments
45import Language.PureScript.CoreFn
46import Language.PureScript.CoreFn
46import Language.PureScript.Names
47import Language.PureScript.Names
47import Language.PureScript.Options
48import Language.PureScript.Options
@@ -118,8 +119,10 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
118 -------------------------------------------------------------------------------------------------
119 -------------------------------------------------------------------------------------------------
119 declToCpp :: [CppValueQual] -> (Ann, Ident) -> Expr Ann -> m Cpp
120 declToCpp :: [CppValueQual] -> (Ann, Ident) -> Expr Ann -> m Cpp
120 -------------------------------------------------------------------------------------------------
121 -------------------------------------------------------------------------------------------------
121− declToCpp _ _ (Abs (_, _, _, Just IsTypeClassConstructor) _ _) =
122+ declToCpp _ (_, ident) e@(Abs (_, _, _, Just IsTypeClassConstructor) _ _) =
122− return CppNoOp
123+ let className = identToCpp ident
124+ (supers, members) = span (C.__superclass_ `isPrefixOf`) (identToCpp <$> (fst $ unAbs e []))
125+ in return $ CppStruct className [CppEnum Nothing Nothing (sort supers ++ members)]
124 declToCpp _ (_, Op _) (Var (_, _, Nothing, _) _) =
127 declToCpp _ (_, Op _) (Var (_, _, Nothing, _) _) =
125 return CppNoOp -- skip operator aliases
128 return CppNoOp -- skip operator aliases
@@ -144,7 +147,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
144 (arg' : args' ++ args'')
147 (arg' : args' ++ args'')
146 (vqs ++ if isAccessor (snd abs') then [CppInline] else [])
149 (vqs ++ if isAccessor (snd abs') then [CppInline] else [])
147− (convertNestedLambdas block)
150+ (convertNestedLambdas $ convertDictIndexers block)
148 , CppFunction
151 , CppFunction
149 (curriedName name)
152 (curriedName name)
@@ -163,12 +166,13 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
165 (vqs ++ if isIndexer block then [CppInline] else [])
168 (vqs ++ if isIndexer block then [CppInline] else [])
166− (convertNestedLambdas $ asReturnBlock block)
169+ (convertNestedLambdas . asReturnBlock $ convertDictIndexers block)
167 return (CppComment com fn)
170 return (CppComment com fn)
169− argcnt | Just t <- ty = countArgs t
172+ ty' | Just t <- ty = Just t
170− | Just (t, _, _) <- M.lookup (mn, ident) (E.names env) = countArgs t
173+ | Just (t, _, _) <- M.lookup (mn, ident) (E.names env) = Just t
171− | otherwise = 0
174+ | otherwise = Nothing
175+ argcnt = maybe 0 countArgs ty'
172 name = identToCpp ident
176 name = identToCpp ident
173 aty = Just $ CppAny [CppConst, CppRef]
177 aty = Just $ CppAny [CppConst, CppRef]
174 rty = Just $ CppAny []
178 rty = Just $ CppAny []
@@ -181,6 +185,10 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
181 isIndexer :: Cpp -> Bool
185 isIndexer :: Cpp -> Bool
182 isIndexer (CppIndexer (CppStringLiteral _) (CppVar _)) = True
186 isIndexer (CppIndexer (CppStringLiteral _) (CppVar _)) = True
183 isIndexer _ = False
187 isIndexer _ = False
188+ classes = qualifiedToCpp (Ident . runProperName) . fst <$>
189+ maybe [] extractConstraints ty'
190+ dictClasses = zip (CppVar . fst <$> arg' : args') classes
191+ convertDictIndexers = everywhereOnCpp (dictIndexerToEnum dictClasses)
185 declToCpp _ (_, ident) (Constructor _ _ (ProperName _) []) =
193 declToCpp _ (_, ident) (Constructor _ _ (ProperName _) []) =
@@ -427,10 +435,6 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
427 [(identToCpp arg, Just $ CppAny [CppConst, CppRef])]
435 [(identToCpp arg, Just $ CppAny [CppConst, CppRef])]
428 (Just $ CppAny [])
436 (Just $ CppAny [])
429 (asReturnBlock cpp')
437 (asReturnBlock cpp')
431− -- valueToCpp (App _ e (Var _ (Qualified (Just (ModuleName [ProperName "Prim"])) (Ident "undefined")))) =
434 valueToCpp e@App{} = do
438 valueToCpp e@App{} = do
435 let (f, args) = unApp e []
439 let (f, args) = unApp e []
436 args' <- mapM valueToCpp args
440 args' <- mapM valueToCpp args
@@ -838,6 +842,28 @@ countArgs = go 0
838 go argcnt (T.ConstrainedType ts t) = go (argcnt + length ts) t
842 go argcnt (T.ConstrainedType ts t) = go (argcnt + length ts) t
839 go argcnt _ = argcnt
843 go argcnt _ = argcnt
845+---------------------------------------------------------------------------------------------------
846+extractConstraints :: T.Type -> [T.Constraint]
847+---------------------------------------------------------------------------------------------------
848+extractConstraints = go []
850+ go cs (T.ForAll _ t _) = go cs t
851+ go cs (T.TypeApp (T.TypeApp fn _) t) | fn == E.tyFunction = go cs t
852+ go cs (T.ConstrainedType ts t) = go (cs ++ ts) t
855+---------------------------------------------------------------------------------------------------
856+dictIndexerToEnum :: [(Cpp,Cpp)] -> Cpp -> Cpp
857+---------------------------------------------------------------------------------------------------
858+dictIndexerToEnum repls (CppIndexer (CppStringLiteral prop) dict)
859+ | Just cls <- lookup dict repls =
862+ (CppAccessor (CppVar . identToCpp $ Ident prop) cls)
863+ (CppCast mapType dict))
865+dictIndexerToEnum _ cpp = cpp
841---------------------------------------------------------------------------------------------------
867---------------------------------------------------------------------------------------------------
842curriedName :: String -> String
868curriedName :: String -> String
843---------------------------------------------------------------------------------------------------
869---------------------------------------------------------------------------------------------------