on master help sign in
Add nice error message for bad cyclic definitions
4878192Evan Czaplicki
src/Generate/JavaScript.hs+25−2
@@ -28,6 +28,7 @@ import qualified Elm.Name as N
28import qualified Generate.JavaScript.Builder as JS
28import qualified Generate.JavaScript.Builder as JS
29import qualified Generate.JavaScript.Expression as Expr
29import qualified Generate.JavaScript.Expression as Expr
30import qualified Generate.JavaScript.Name as Name
30import qualified Generate.JavaScript.Name as Name
31+import qualified Reporting.Helpers as H
31
32
32
33
33
34
@@ -224,9 +225,19 @@ generateCycle mode (Opt.Global home _) cycle =
224 let
225 let
225 safeDefs = map (generateSafeCycle mode home) cycle
226 safeDefs = map (generateSafeCycle mode home) cycle
226 realDefs = map (generateRealCycle home) cycle
227 realDefs = map (generateRealCycle home) cycle
227− -- TODO add `try` in debug mode nice infinite recursion reports
228+ block = JS.Block (safeDefs ++ realDefs)
228 in
229 in
229− JS.Block (safeDefs ++ realDefs)
230+ case mode of
231+ Name.Prod _ _ ->
232+ block
233+
234+ Name.Debug _ ->
235+ JS.Try block Name.dollar $ JS.Throw $ JS.String $
236+ "The following top-level definitions are causing infinite recursion:\\n"
237+ <> drawCycle (map fst cycle)
238+ <> "\\n\\nThese errors are very tricky, so read "
239+ <> B.stringUtf8 (H.makeLink "halting-problem")
240+ <> " to learn how to fix it!"
230
241
231
242
232generateSafeCycle :: Name.Mode -> ModuleName.Canonical -> (N.Name, Opt.Expr) -> JS.Stmt
243generateSafeCycle :: Name.Mode -> ModuleName.Canonical -> (N.Name, Opt.Expr) -> JS.Stmt
@@ -248,6 +259,18 @@ generateRealCycle home (name, _) =
248 ]
259 ]
249
260
250
261
262+drawCycle :: [N.Name] -> B.Builder
263+drawCycle names =
264+ let
265+ topLine = "\\n ┌─────┐"
266+ nameLine name = "\\n │ " <> N.toBuilder name
267+ midLine = "\\n │ ↓"
268+ bottomLine = "\\n └─────┘"
269+ in
270+ mconcat (topLine : List.intersperse midLine (map nameLine names) ++ [ bottomLine ])
271+
272+
273+
251
274
252-- GENERATE KERNEL
275-- GENERATE KERNEL
253
276
src/Generate/JavaScript/Builder.hs+14
@@ -67,6 +67,8 @@ data Stmt
67 | Break (Maybe Name) -- break lab;
67 | Break (Maybe Name) -- break lab;
68 | Continue (Maybe Name) -- continue lab;
68 | Continue (Maybe Name) -- continue lab;
69 | Labelled Name Stmt -- lab: stmt
69 | Labelled Name Stmt -- lab: stmt
70+ | Try Stmt Name Stmt -- try stmt catch (x) stmt
71+ | Throw Expr -- throw expr;
70 | Return (Maybe Expr) -- return expr;
72 | Return (Maybe Expr) -- return expr;
71 | Var [(Name, Maybe Expr)] -- var x, y=42;
73 | Var [(Name, Maybe Expr)] -- var x, y=42;
72 | FunctionStmt Name [Name] [Stmt] -- function f(x, y, z) {...}
74 | FunctionStmt Name [Name] [Stmt] -- function f(x, y, z) {...}
@@ -210,6 +212,18 @@ fromStmt indent statement =
210 , fromStmt indent stmt
212 , fromStmt indent stmt
211 ]
213 ]
212
214
215+ Try tryStmt errorName catchStmt ->
216+ mconcat
217+ [ indent, "try {\n"
218+ , fromStmt (deeper indent) tryStmt
219+ , indent, "} catch (", Name.toBuilder errorName, ") {\n"
220+ , fromStmt (deeper indent) catchStmt
221+ , indent, "}\n"
222+ ]
223+
224+ Throw expr ->
225+ "throw " <> snd (fromExpr indent Whatever expr) <> ";"
226+
213 Return Nothing ->
227 Return Nothing ->
214 indent <> "return;\n"
228 indent <> "return;\n"
215
229