@@ -28,13 +28,14 @@ indent = concatMap f
2828 where f '\n' = "\n "
2929 f c = [c]
3030
31−internalImports =
31+internalImports name =
3232 [ ("N" , "Elm.Native"),
3333 ("_N", "N.Utils(elm)"),
3434 ("_L", "N.List(elm)"),
3535 ("_E", "N.Error(elm)"),
3636 ("_J", "N.JavaScript(elm)"),
37− ("_str", "_J.toString")
37+ ("_str", "_J.toString"),
38+ ("$moduleName", quoted name)
3839 ]
3940
4041parens s = "(" ++ s ++ ")"
@@ -78,7 +79,7 @@ jsModule modul =
7879 ]
7980 setup names = concatMap (\n -> globalAssign n $ n ++ " || {}") .
8081 map dotSep . drop 2 . List.inits $ init names
81− usefulFuncs = commaSep (map (uncurry assign') internalImports)
82+ usefulFuncs = commaSep (map (uncurry assign') (internalImports modName)
8283
8384 jsExports = setup ("elm" : names modul) ++
8485 ret (assign' ("elm." ++ modName) (brackets exs))
@@ -194,7 +195,7 @@ instance ToJS (Expr t v) where
194195 Modify e fs -> do fs' <- (mapM (\(x,v) -> (,) x `liftM` toJS' v) fs)
195196 setField fs' `liftM` toJS' e
196197 Record fs -> makeRecord fs
197− Binop op e1 e2 -> binop op `liftM` toJS' e1 `ap` toJS' e2
198+ Binop op e1 e2 -> binop op e1 e2
198199
199200 Lambda p e@(L s _) -> liftM (fastFunc . ret) (toJS' body)
200201 where
@@ -257,7 +258,7 @@ formatMarkdown = concatMap f
257258multiIfToJS span ps =
258259 case last ps of
259260 (L _ (Var "otherwise"), e) -> toJS' e >>= \b -> format b (init ps)
260− _ -> format ("_E.If" ++ parens (quoted (show span))) ps
261+ _ -> format ("_E.If" ++ parens ("$moduleName," ++ quoted (show span))) ps
261262 where
262263 format base ps =
263264 foldr (\c e -> parens $ c ++ " : " ++ e) base `liftM` mapM f ps
@@ -289,7 +290,7 @@ matchToJS span match =
289290 access = if any isLiteral clauses then "" else ".ctor"
290291 return $ concat [ "\nswitch (", name, access, ") {"
291292 , indent cases, "\n}", finally ]
292− Fail -> return ("_E.Case" ++ parens (quoted (show span)))
293+ Fail -> return ("_E.Case" ++ parens ("$moduleName," ++ quoted (show span)))
293294 Break -> return "break;"
294295 Other e -> ret `liftM` toJS' e
295296 Seq ms -> concat `liftM` mapM (matchToJS span) (dropEnd [] ms)
@@ -318,33 +319,50 @@ jsRange e1 e2 = "_L.range" ++ parens (e1 ++ "," ++ e2)
318319jsCompare e1 e2 op = parens ("_N.cmp(" ++ e1 ++ "," ++ e2 ++ ")" ++ op)
319320
320321
321−binop op e1 e2 =
322+binop op e1 e2
323+ | op == "Basics.." =
324+ do ss <- mapM toJS' (e1 : collect [] e2)
325+ return . jsFunc "$" . ret $ apply "$" ss
326+ | op == "Basics.<|" =
327+ do arg <- toJS' e2
328+ funcs <- mapM toJS' (collect [] e1)
329+ return (apply arg funcs)
330+ | otherwise =
331+ binopNormal op `liftM` toJS' e1 `ap` toJS' e2
332+ where
333+ apply = foldr (\f arg-> f ++ parens arg)
334+
335+ collect es e =
336+ case e of
337+ L _ (Binop op e1 e2) | op == "Basics.." -> collect (es ++ [e1]) e2
338+ _ -> es ++ [e]
339+
340+binopNormal op s1 s2 =
322341 case Map.lookup op opDict of
323342 Just e -> e
324− Nothing -> "A2" ++ parens (commaSep [ prefix ++ func, e1, e2 ])
325− where
326− func | isOp op' = "_op['" ++ op' ++ "']"
327− | otherwise = op'
328− (prefix, op') = case List.elemIndices '.' op of
329− [] -> ("", op)
330− xs -> splitAt (last xs + 1) op
343+ Nothing -> "A2" ++ parens (commaSep [ prefix ++ func, s1, s2 ])
331344 where
345+ func | isOp op' = "_op['" ++ op' ++ "']"
346+ | otherwise = op'
347+ (prefix, op') = case List.elemIndices '.' op of
348+ [] -> ("", op)
349+ xs -> splitAt (last xs + 1) op
350+
332351 opDict = Map.fromList $ basics ++
333− [ ("::", jsCons e1 e2)
334− , ("List.++", "_L.append" ++ parens (e1 ++ "," ++ e2)) ]
352+ [ ("::", jsCons s1 s2)
353+ , ("List.++", "_L.append" ++ parens (s1 ++ "," ++ s2)) ]
335354
336− ops = pow : map (\op -> (op, parens (e1 ++ op ++ e2))) ["+","-","*","/","&&","||"]
337− where pow = ("^" , "Math.pow(" ++ e1 ++ "," ++ e2 ++ ")")
355+ ops = pow : map (\op -> (op, parens (s1 ++ op ++ s2))) ["+","-","*","/","&&","||"]
356+ where pow = ("^" , "Math.pow(" ++ s1 ++ "," ++ s2 ++ ")")
338357
339358 basics = ops ++ map (\(op,e) -> ("Basics." ++ op, e))
340− (ops ++ [ ("<|", e1 ++ parens e2)
341− , ("|>", e2 ++ parens e1)
342− , ("." , jsFunc "$" . ret $ e1 ++ parens (e2 ++ parens "$"))
343− , ("==", "_N.eq(" ++ e1 ++ "," ++ e2 ++ ")")
344− , ("/=", "!_N.eq(" ++ e1 ++ "," ++ e2 ++ ")")
345− , ("<" , jsCompare e1 e2 "<0")
346− , (">" , jsCompare e1 e2 ">0")
347− , ("<=", jsCompare e1 e2 "<1")
348− , (">=", jsCompare e1 e2 ">-1")
349− , ("div", parens (e1 ++ "/" ++ e2 ++ "|0"))
359+ (ops ++ [ ("<|", s1 ++ parens s2)
360+ , ("|>", s2 ++ parens s1)
361+ , ("==", "_N.eq(" ++ s1 ++ "," ++ s2 ++ ")")
362+ , ("/=", "!_N.eq(" ++ s1 ++ "," ++ s2 ++ ")")
363+ , ("<" , jsCompare s1 s2 "<0")
364+ , (">" , jsCompare s1 s2 ">0")
365+ , ("<=", jsCompare s1 s2 "<1")
366+ , (">=", jsCompare s1 s2 ">-1")
367+ , ("div", parens (s1 ++ "/" ++ s2 ++ "|0"))
350368 ])