@@ -42,6 +42,7 @@ import Language.PureScript.CodeGen.Cpp.File
4242import Language.PureScript.CodeGen.Cpp.Optimizer
4343import Language.PureScript.CodeGen.Cpp.Optimizer.TCO
4444import Language.PureScript.CodeGen.Cpp.Types
45+import Language.PureScript.Comments
4546import Language.PureScript.CoreFn
4647import Language.PureScript.Names
4748import Language.PureScript.Options
@@ -118,8 +119,10 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
118119 -------------------------------------------------------------------------------------------------
119120 declToCpp :: [CppValueQual] -> (Ann, Ident) -> Expr Ann -> m Cpp
120121 -------------------------------------------------------------------------------------------------
121− declToCpp _ _ (Abs (_, _, _, Just IsTypeClassConstructor) _ _) =
122− return CppNoOp
122+ declToCpp _ (_, ident) e@(Abs (_, _, _, Just IsTypeClassConstructor) _ _) =
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)]
123126
124127 declToCpp _ (_, Op _) (Var (_, _, Nothing, _) _) =
125128 return CppNoOp -- skip operator aliases
@@ -144,7 +147,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
144147 (arg' : args' ++ args'')
145148 rty
146149 (vqs ++ if isAccessor (snd abs') then [CppInline] else [])
147− (convertNestedLambdas block)
150+ (convertNestedLambdas $ convertDictIndexers block)
148151 , CppFunction
149152 (curriedName name)
150153 [arg']
@@ -163,12 +166,13 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
163166 [arg']
164167 rty
165168 (vqs ++ if isIndexer block then [CppInline] else [])
166− (convertNestedLambdas $ asReturnBlock block)
169+ (convertNestedLambdas . asReturnBlock $ convertDictIndexers block)
167170 return (CppComment com fn)
168171 where
169− argcnt | Just t <- ty = countArgs t
170− | Just (t, _, _) <- M.lookup (mn, ident) (E.names env) = countArgs t
171− | otherwise = 0
172+ ty' | Just t <- ty = Just t
173+ | Just (t, _, _) <- M.lookup (mn, ident) (E.names env) = Just t
174+ | otherwise = Nothing
175+ argcnt = maybe 0 countArgs ty'
172176 name = identToCpp ident
173177 aty = Just $ CppAny [CppConst, CppRef]
174178 rty = Just $ CppAny []
@@ -181,6 +185,10 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
181185 isIndexer :: Cpp -> Bool
182186 isIndexer (CppIndexer (CppStringLiteral _) (CppVar _)) = True
183187 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)
184192
185193 declToCpp _ (_, ident) (Constructor _ _ (ProperName _) []) =
186194 return $
@@ -427,10 +435,6 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
427435 [(identToCpp arg, Just $ CppAny [CppConst, CppRef])]
428436 (Just $ CppAny [])
429437 (asReturnBlock cpp')
430−
431− -- valueToCpp (App _ e (Var _ (Qualified (Just (ModuleName [ProperName "Prim"])) (Ident "undefined")))) =
432− -- valueToCpp e
433−
434438 valueToCpp e@App{} = do
435439 let (f, args) = unApp e []
436440 args' <- mapM valueToCpp args
@@ -838,6 +842,28 @@ countArgs = go 0
838842 go argcnt (T.ConstrainedType ts t) = go (argcnt + length ts) t
839843 go argcnt _ = argcnt
840844
845+---------------------------------------------------------------------------------------------------
846+extractConstraints :: T.Type -> [T.Constraint]
847+---------------------------------------------------------------------------------------------------
848+extractConstraints = go []
849+ where
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
853+ go cs _ = cs
854+
855+---------------------------------------------------------------------------------------------------
856+dictIndexerToEnum :: [(Cpp,Cpp)] -> Cpp -> Cpp
857+---------------------------------------------------------------------------------------------------
858+dictIndexerToEnum repls (CppIndexer (CppStringLiteral prop) dict)
859+ | Just cls <- lookup dict repls =
860+ CppBinary Dot
861+ (CppIndexer
862+ (CppAccessor (CppVar . identToCpp $ Ident prop) cls)
863+ (CppCast mapType dict))
864+ (CppVar "second")
865+dictIndexerToEnum _ cpp = cpp
866+
841867---------------------------------------------------------------------------------------------------
842868curriedName :: String -> String
843869---------------------------------------------------------------------------------------------------