@@ -69,7 +69,9 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
70 let cppImports' = "PureScript" : cppImports
70 let cppImports' = "PureScript" : cppImports
71 cppDecls <- concat <$> mapM (bindToCpp [CppTopLevel]) decls
71 cppDecls <- concat <$> mapM (bindToCpp [CppTopLevel]) decls
72− optimized <- traverse optimize cppDecls
72+ cppDecls' <- traverse optimize cppDecls
73+ foreignWrappers <- curriedForeigns
74+ let optimized = cppDecls' ++ foreignWrappers
73 let moduleHeader =
75 let moduleHeader =
74 fileBegin mn "HH" ++
76 fileBegin mn "HH" ++
75 P.linebreak ++
77 P.linebreak ++
@@ -115,6 +117,9 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
115 declToCpp _ _ (Abs (_, _, _, Just IsTypeClassConstructor) _ _) =
117 declToCpp _ _ (Abs (_, _, _, Just IsTypeClassConstructor) _ _) =
116 return CppNoOp
118 return CppNoOp
120+ declToCpp _ (Op _) (Var (_, _, Nothing, _) _) =
121+ return CppNoOp -- skip operator aliases
118 declToCpp _ ident (Abs _ arg@(Ident "dict")
123 declToCpp _ ident (Abs _ arg@(Ident "dict")
119 body@(Accessor _ _ (Var _ (Qualified Nothing arg'))))
124 body@(Accessor _ _ (Var _ (Qualified Nothing arg'))))
120 | arg' == arg = do
125 | arg' == arg = do
@@ -127,16 +132,51 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
128 return fn'
133 return fn'
130− declToCpp vqs ident (Abs (_, com, _, _) arg body) = do
135+ declToCpp vqs ident (Abs (_, com, ty, _) arg body) = do
136+ fn <- if argcnt > 0 && CppTopLevel `elem` vqs
138+ argNames <- replicateM (argcnt - length args' - 1) freshName
139+ let args'' = zip argNames (repeat aty)
131− block <- asReturnBlock <$> valueToCpp body
140+ block <- asReturnBlock <$> valueToCpp
148+ (Var nullAnn . Qualified Nothing . Ident $ head argNames)))
132− let block' = convertNestedLambdas block
149+ let block' = convertNestedLambdas block
150+ return $ CppNamespace ""
153+ (arg' : args' ++ args'')
133− fn' = CppFunction
157+ , CppFunction
134− (identToCpp ident)
158+ (curriedName name)
164+ (fst <$> args' ++ args'')
165+ (CppApp (CppVar name)
166+ (CppVar . fst <$> (arg' : args' ++ args''))))
169+ block <- asReturnBlock <$> valueToCpp body
170+ return $ CppFunction name [arg'] rty vqs (convertNestedLambdas block)
171+ return (CppComment com fn)
173+ argcnt = maybe 0 countArgs ty
174+ name = identToCpp ident
135− [(identToCpp arg, Just $ CppAny [CppConst, CppRef])]
175+ aty = Just $ CppAny [CppConst, CppRef]
136− (Just $ CppAny [])
176+ rty = Just $ CppAny []
137− vqs
177+ arg' = (identToCpp arg, aty)
138− block'
178+ args' = (\i -> (identToCpp i, aty)) <$> fst abs'
139− return (CppComment com fn')
179+ abs' = unAbs body []
141 declToCpp _ ident (Constructor _ _ (ProperName _) []) =
181 declToCpp _ ident (Constructor _ _ (ProperName _) []) =
@@ -145,22 +185,28 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
146 (Just $ CppAny [])
186 (Just $ CppAny [])
147 [CppInline]
187 [CppInline]
148− (CppBlock [CppReturn (CppDataLiteral [CppStringLiteral (identToCpp ident)])])
188+ (asReturnBlock (CppDataLiteral [CppStringLiteral (identToCpp ident)]))
150− declToCpp _ ident (Constructor _ _ (ProperName _) fields) = return . CppNamespace [] $
190+ declToCpp _ ident (Constructor _ _ (ProperName _) fields) =
191+ return . CppNamespace "" $
151 [ CppFunction
192 [ CppFunction
152− ('$' : identToCpp ident)
193+ name
153 (farg <$> fields')
194 (farg <$> fields')
154 (Just $ CppAny [])
195 (Just $ CppAny [])
155 [CppInline]
196 [CppInline]
156− (CppBlock fullyConstructed)
197+ (asReturnBlock (CppDataLiteral (CppStringLiteral name : (CppVar <$> fields'))))
199+ if length fields > 1
157− , CppFunction
201+ [ CppFunction
158− (identToCpp ident)
202+ (curriedName name)
159− (farg <$> f)
203+ (farg <$> f)
160− (Just $ CppAny [])
204+ (Just $ CppAny [])
162− (CppBlock (fieldLambdas fs))
206+ (CppBlock (fieldLambdas fs))
165 name = identToCpp ident
211 name = identToCpp ident
166 fields' = identToCpp <$> fields
212 fields' = identToCpp <$> fields
@@ -174,35 +220,44 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
174 (farg <$> [f'])
220 (farg <$> [f'])
175 (Just $ CppAny [])
221 (Just $ CppAny [])
176 (CppBlock $ fieldLambdas fs') ]
222 (CppBlock $ fieldLambdas fs') ]
177− | otherwise = fullyConstructed
178− fullyConstructed = [CppReturn (CppDataLiteral (CppStringLiteral name : (CppVar <$> fields')))]
223+ | otherwise = [CppReturn $ CppApp (CppVar name) (CppVar <$> fields')]
180− declToCpp qs ident e@(App (_, _, Just ty, _) _ _)
225+ declToCpp qs ident e
226+ | Just ty <- exprType e,
181− | CppTopLevel `elem` qs,
227+ CppTopLevel `elem` qs,
182− count <- countArgs ty,
228+ argcnt <- countArgs ty,
183− count > 0 = do
229+ argcnt > 0 = do
184− argNames <- replicateM count freshName
230+ argNames <- replicateM argcnt freshName
185− block <- flip (foldl (\fn a -> CppApp fn [a])) (CppVar <$> argNames) <$> valueToCpp e
231+ block <- valueToCpp $
235+ (Nothing, [], Just ty, Nothing)
237+ (Var nullAnn . Qualified Nothing . Ident $ head argNames))
186− return $ CppFunction
238+ let fn' = CppFunction
187− (identToCpp ident)
239+ (curriedName name)
188 [(head argNames, Just $ CppAny [CppConst, CppRef])]
240 [(head argNames, Just $ CppAny [CppConst, CppRef])]
189− (Just $ CppAny [])
241+ rty
191− (asReturnBlock $ curried (tail argNames) block)
243+ (asReturnBlock $
246+ (CppApp (CppVar name)
247+ (CppVar <$> argNames)))
248+ return $ CppNamespace ""
251+ (zip argNames $ repeat aty)
254+ (asReturnBlock block)
193− curried :: [String] -> Cpp -> Cpp
258+ name = identToCpp ident
194− curried args vals = foldl (\val arg -> CppLambda
196− [(arg, Just $ CppAny [CppConst, CppRef])]
259+ aty = Just $ CppAny [CppConst, CppRef]
197− (Just $ CppAny [])
260+ rty = Just $ CppAny []
200− countArgs :: T.Type -> Int
203− go argcnt (T.ForAll _ t _) = go argcnt t
204− go argcnt (T.TypeApp (T.TypeApp fn _) t) | fn == E.tyFunction = go (argcnt + 1) t
205− go argcnt _ = argcnt
207 declToCpp _ ident val = do
262 declToCpp _ ident val = do
208 val' <- valueToCpp val
263 val' <- valueToCpp val
@@ -212,6 +267,15 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
213 (Just val')
268 (Just val')
270+ -------------------------------------------------------------------------------------------------
271+ exprType :: Expr Ann -> Maybe T.Type
272+ -------------------------------------------------------------------------------------------------
273+ exprType (Var (_, _, Just ty, _) _) = Just ty
274+ exprType (App (_, _, Just ty, _) _ _) = Just ty
275+ exprType (Case (_, _, Just ty, _) _ _) = Just ty
276+ exprType (Let (_, _, Just ty, _) _ _) = Just ty
277+ exprType _ = Nothing
215 -------------------------------------------------------------------------------------------------
279 -------------------------------------------------------------------------------------------------
216 fnToLambda :: Cpp -> Cpp
280 fnToLambda :: Cpp -> Cpp
217 -------------------------------------------------------------------------------------------------
281 -------------------------------------------------------------------------------------------------
@@ -226,11 +290,6 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
226 fnToLambda (CppComment com cpp) = CppComment com (fnToLambda cpp)
290 fnToLambda (CppComment com cpp) = CppComment com (fnToLambda cpp)
227 fnToLambda _ = error "Not a function!"
291 fnToLambda _ = error "Not a function!"
229− -------------------------------------------------------------------------------------------------
230− asReturnBlock :: Cpp -> Cpp
231− -------------------------------------------------------------------------------------------------
232− asReturnBlock cpp = CppBlock [CppReturn cpp]
234 -------------------------------------------------------------------------------------------------
293 -------------------------------------------------------------------------------------------------
235 convertNestedLambdas :: Cpp -> Cpp
294 convertNestedLambdas :: Cpp -> Cpp
236 -------------------------------------------------------------------------------------------------
295 -------------------------------------------------------------------------------------------------
@@ -288,7 +347,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
288 [CppCaptureAll]
347 [CppCaptureAll]
289 [(localdict, Just $ CppAny [CppConst, CppRef])]
348 [(localdict, Just $ CppAny [CppConst, CppRef])]
290 (Just $ CppAny [])
349 (Just $ CppAny [])
291− (CppBlock [CppReturn cpp'])
350+ (asReturnBlock cpp')
292 topdict :: String
351 topdict :: String
293 topdict = "__dict__"
352 topdict = "__dict__"
294 localdict :: String
353 localdict :: String
@@ -305,9 +364,16 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
305 valueToCpp (Var (_, _, _, Just (IsConstructor _ [])) ident) =
364 valueToCpp (Var (_, _, _, Just (IsConstructor _ [])) ident) =
306 return $ CppApp (CppVar $ qualifiedToStr' id ident) []
365 return $ CppApp (CppVar $ qualifiedToStr' id ident) []
308− valueToCpp (Var (_, _, _, Just (IsConstructor _ _)) ident) =
367+ valueToCpp (Var (_, _, _, Just (IsConstructor _ [_])) ident) =
309 return . CppVar $ qualifiedToStr' id ident
368 return . CppVar $ qualifiedToStr' id ident
370+ valueToCpp (Var (_, _, _, Just (IsConstructor _ _)) ident) =
371+ return . curriedName' $ varToCpp ident
373+ valueToCpp (Var (_, _, Just ty, _) ident@(Qualified (Just _) _))
374+ | countArgs ty > 1 =
375+ return . curriedName' $ varToCpp ident
311 valueToCpp (Var _ ident) =
377 valueToCpp (Var _ ident) =
312 return $ varToCpp ident
378 return $ varToCpp ident
@@ -365,11 +431,20 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
365 args' <- mapM valueToCpp args
431 args' <- mapM valueToCpp args
366 case f of
432 case f of
367 Var (_, _, _, Just IsNewtype) _ -> return (head args')
433 Var (_, _, _, Just IsNewtype) _ -> return (head args')
368− Var (_, _, _, Just (IsConstructor _ fields)) (Qualified qual (Ident name)) | length args == length fields ->
434+ Var (_, _, _, Just (IsConstructor _ fields)) ident
435+ | length args == length fields ->
369− return $ CppApp (qualifiedToCpp id . Qualified qual . Ident $ '$' : name) args'
436+ return $ CppApp (uncurried' $ qualifiedToCpp id ident) args'
370 Var (_, _, _, Just IsTypeClassConstructor) (Qualified mn' (Ident classname)) ->
437 Var (_, _, _, Just IsTypeClassConstructor) (Qualified mn' (Ident classname)) ->
371 let Just (_, constraints, fns) = findClass (Qualified mn' (ProperName classname)) in
438 let Just (_, constraints, fns) = findClass (Qualified mn' (ProperName classname)) in
372 return . CppObjectLiteral $ zip ((sort $ superClassDictionaryNames constraints) ++ (fst <$> fns)) args'
439 return . CppObjectLiteral $ zip ((sort $ superClassDictionaryNames constraints) ++ (fst <$> fns)) args'
440+ Var (_, _, Just ty, _) (Qualified (Just _) _)
441+ | argcnt <- countArgs ty,
443+ length args >= argcnt -> do
445+ let (uncurArgs, curArgs) = splitAt argcnt args'
446+ uncurApp = CppApp (uncurried' f') uncurArgs
447+ return $ foldl (\fn a -> CppApp fn [a]) uncurApp curArgs
374 flip (foldl (\fn a -> CppApp fn [a])) args' <$> valueToCpp f
449 flip (foldl (\fn a -> CppApp fn [a])) args' <$> valueToCpp f
@@ -625,6 +700,12 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
625 unApp (App _ val arg) args = unApp val (arg : args)
700 unApp (App _ val arg) args = unApp val (arg : args)
626 unApp other args = (other, args)
701 unApp other args = (other, args)
703+ -------------------------------------------------------------------------------------------------
704+ unAbs :: Expr Ann -> [Ident] -> ([Ident], Expr Ann)
705+ -------------------------------------------------------------------------------------------------
706+ unAbs (Abs _ arg val) args = unAbs val (args ++ [arg])
707+ unAbs other args = (args, other)
628 -------------------------------------------------------------------------------------------------
709 -------------------------------------------------------------------------------------------------
629 qualifiedToCpp :: (a -> Ident) -> Qualified a -> Cpp
710 qualifiedToCpp :: (a -> Ident) -> Qualified a -> Cpp
630 -------------------------------------------------------------------------------------------------
711 -------------------------------------------------------------------------------------------------
@@ -650,3 +731,87 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
650 fns' <- (\(i,t) -> (runIdent i, t)) <$> fns
731 fns' <- (\(i,t) -> (runIdent i, t)) <$> fns
651 = Just (fst <$> params, constraints, (sortBy (compare `on` normalizedName . fst) fns'))
732 = Just (fst <$> params, constraints, (sortBy (compare `on` normalizedName . fst) fns'))
652 findClass _ = Nothing
733 findClass _ = Nothing
735+ -------------------------------------------------------------------------------------------------
736+ curriedForeigns :: m [Cpp]
737+ -------------------------------------------------------------------------------------------------
738+ curriedForeigns = concat <$> mapM go allForeigns
741+ | argcnt <- countArgs ty,
743+ let name = identToCpp ident
744+ argNames <- replicateM argcnt freshName
748+ [(head argNames, Just $ CppAny [CppConst, CppRef])]
754+ (CppApp (CppVar name)
755+ (CppVar <$> argNames)))
759+ allForeigns :: [(Ident, T.Type)]
760+ allForeigns = map (\((_, ident), (ty, _, _)) -> (ident, ty)) .
761+ filter (\((mn', _), (_, kind, _)) -> mn' == mn && kind == E.External) .
762+ M.toList $ E.names env
764+---------------------------------------------------------------------------------------------------
765+asReturnBlock :: Cpp -> Cpp
766+---------------------------------------------------------------------------------------------------
767+asReturnBlock cpp = CppBlock [CppReturn cpp]
769+---------------------------------------------------------------------------------------------------
770+curriedLambda :: [String] -> Cpp -> Cpp
771+---------------------------------------------------------------------------------------------------
772+curriedLambda args ret = foldr (\arg ret' -> CppLambda
774+ [(arg, Just $ CppAny [CppConst, CppRef])]
776+ (asReturnBlock ret')
779+---------------------------------------------------------------------------------------------------
780+curriedApp :: [String] -> Expr Ann -> Expr Ann
781+---------------------------------------------------------------------------------------------------
782+curriedApp args vals = foldl (\val arg -> App
785+ (Var nullAnn . Qualified Nothing $ Ident arg))
788+---------------------------------------------------------------------------------------------------
789+countArgs :: T.Type -> Int
790+---------------------------------------------------------------------------------------------------
791+countArgs = go 0 . T.everywhereOnTypes rmForAll
793+ go argcnt (T.TypeApp (T.TypeApp fn _) (T.ConstrainedType _ _)) | fn == E.tyFunction = argcnt
794+ go argcnt (T.TypeApp (T.TypeApp fn _) t) | fn == E.tyFunction = go (argcnt + 1) t
795+ go argcnt _ = argcnt
796+ rmForAll :: T.Type -> T.Type
797+ rmForAll (T.ForAll _ t _) = t
800+---------------------------------------------------------------------------------------------------
801+curriedName :: String -> String
802+---------------------------------------------------------------------------------------------------
803+curriedName name = '$' : name
805+---------------------------------------------------------------------------------------------------
806+uncurried' :: Cpp -> Cpp
807+---------------------------------------------------------------------------------------------------
808+uncurried' (CppVar ('$':name)) = CppVar name
809+uncurried' (CppAccessor a b) = CppAccessor (uncurried' a) b
812+---------------------------------------------------------------------------------------------------
813+curriedName' :: Cpp -> Cpp
814+---------------------------------------------------------------------------------------------------
815+curriedName' (CppVar name) = CppVar (curriedName name)
816+curriedName' (CppAccessor a b) = CppAccessor (curriedName' a) b
817+curriedName' cpp = cpp