Skip to content

Commit 685a6d0

Browse files
authored
Merge pull request #44 from Janiczek/janiczek/make-it-stop-crashing
Direct fn calls: disable for cyclic calls
2 parents 5c2a0ce + c00896a commit 685a6d0

File tree

8 files changed

+227
-1
lines changed

8 files changed

+227
-1
lines changed

compiler/src/Generate/JavaScript.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,10 @@ makeArgLookup graph home name =
652652
Just (length args)
653653

654654
_ ->
655-
error (show names)
655+
-- This disables direct function calls eg. for mutually recursive
656+
-- functions (with or without partial application). These are
657+
-- technically possible but not implemented here.
658+
Nothing
656659

657660
_ ->
658661
Nothing

test/Test/JsOutput.hs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,101 @@ suite =
100100
expectTextContains jsOutput "n1 = 0"
101101
expectTextContains jsOutput "n2 = $author$project$Main$N2$(0, 0)"
102102

103+
Nothing ->
104+
crash "JS output could not be read."
105+
, scope "direct function calls - mutual recursion" $ do
106+
project <- io $ Lamdera.Relative.requireDir "test/direct-fn-calls-mutual-recursion"
107+
let
108+
elmHome = project ++ "/elm-home"
109+
elmStuff = project ++ "/elm-stuff"
110+
111+
maybeJsOutput <- io $ do
112+
rmdir elmHome
113+
rmdir elmStuff
114+
115+
Test.Helpers.withElmHome elmHome $
116+
Ext.Common.withProjectRoot project $
117+
Make.run ["src/Main.elm"] $
118+
Make.Flags
119+
{ _debug = False
120+
, _optimize = True
121+
, _output = Just (Make.JS "elm-stuff/tmp.js")
122+
, _report = Nothing
123+
, _docs = Nothing
124+
, _noWire = True
125+
, _optimizeLegible = False
126+
}
127+
128+
fileContents <- readUtf8Text $ elmStuff ++ "/tmp.js"
129+
130+
rmdir elmHome
131+
rmdir elmStuff
132+
133+
pure fileContents
134+
135+
case maybeJsOutput of
136+
Just jsOutput ->
137+
do
138+
expectTextContains jsOutput "$Main$a2 = function (n) {"
139+
expectTextContains jsOutput "$Main$cyclic$a1() {"
140+
expectTextContains jsOutput "$Main$a1 ="
141+
expectTextContains jsOutput "$Main$cyclic$a1 = function () {"
142+
expectTextContains jsOutput "$Main$a1(1)"
143+
expectTextContains jsOutput "$Main$a2(1)"
144+
145+
expectTextContains jsOutput "$Main$b2$ = function (m, n) {"
146+
expectTextContains jsOutput "$Main$cyclic$b1()"
147+
expectTextContains jsOutput "$Main$b2 = F2("
148+
expectTextContains jsOutput "$Main$cyclic$b1 = "
149+
expectTextContains jsOutput "$Main$b1 ="
150+
expectTextContains jsOutput "$Main$cyclic$b1 = function () {"
151+
expectTextContains jsOutput "$Main$b1, 1, 1)" -- A2
152+
expectTextContains jsOutput "$Main$b2$(1, 1)"
153+
154+
Nothing ->
155+
crash "JS output could not be read."
156+
, scope "direct function calls - mutual recursion with partial application" $ do
157+
project <- io $ Lamdera.Relative.requireDir "test/direct-fn-calls-mutual-recursion-partial-application"
158+
let
159+
elmHome = project ++ "/elm-home"
160+
elmStuff = project ++ "/elm-stuff"
161+
162+
maybeJsOutput <- io $ do
163+
rmdir elmHome
164+
rmdir elmStuff
165+
166+
Test.Helpers.withElmHome elmHome $
167+
Ext.Common.withProjectRoot project $
168+
Make.run ["src/Main.elm"] $
169+
Make.Flags
170+
{ _debug = False
171+
, _optimize = True
172+
, _output = Just (Make.JS "elm-stuff/tmp.js")
173+
, _report = Nothing
174+
, _docs = Nothing
175+
, _noWire = True
176+
, _optimizeLegible = False
177+
}
178+
179+
fileContents <- readUtf8Text $ elmStuff ++ "/tmp.js"
180+
181+
rmdir elmHome
182+
rmdir elmStuff
183+
184+
pure fileContents
185+
186+
case maybeJsOutput of
187+
Just jsOutput ->
188+
do
189+
expectTextContains jsOutput "$Main$a2$ = function (x1, x2, x3, x4, x5) {"
190+
expectTextContains jsOutput "$Main$a2 = F5"
191+
expectTextContains jsOutput "$Main$cyclic$a1() {"
192+
expectTextContains jsOutput "$Main$a2, 1, 2);"
193+
expectTextContains jsOutput "$Main$a1 ="
194+
expectTextContains jsOutput "$Main$cyclic$a1 = function () {"
195+
expectTextContains jsOutput "$Main$a1, 3, 4, 5)" -- A3
196+
expectTextContains jsOutput "$Main$a2$(1, 2, 3, 4, 5)"
197+
103198
Nothing ->
104199
crash "JS output could not be read."
105200
]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
elm-stuff
2+
*.js
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"type": "application",
3+
"source-directories": [
4+
"src"
5+
],
6+
"elm-version": "0.19.1",
7+
"dependencies": {
8+
"direct": {
9+
"elm/browser": "1.0.2",
10+
"elm/core": "1.0.5",
11+
"elm/html": "1.0.0",
12+
"elm/http": "2.0.0",
13+
"elm/json": "1.1.3",
14+
"elm/url": "1.0.0",
15+
"lamdera/codecs": "1.0.0",
16+
"lamdera/core": "1.0.0"
17+
},
18+
"indirect": {
19+
"elm/bytes": "1.0.8",
20+
"elm/file": "1.0.5",
21+
"elm/time": "1.0.0",
22+
"elm/virtual-dom": "1.0.3"
23+
}
24+
},
25+
"test-dependencies": {
26+
"direct": {},
27+
"indirect": {}
28+
}
29+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module Main exposing (main)
2+
3+
import Html exposing (Html)
4+
5+
6+
main : Html msg
7+
main =
8+
Html.div []
9+
[ Html.text (a1 3 4 5)
10+
, Html.text (a2 1 2 3 4 5)
11+
]
12+
13+
14+
a1 : Int -> Int -> Int -> String
15+
a1 =
16+
a2 1 2
17+
18+
19+
a2 : Int -> Int -> Int -> Int -> Int -> String
20+
a2 x1 x2 x3 x4 x5 =
21+
if True then
22+
"done"
23+
24+
else
25+
a1 3 4 5
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
elm-stuff
2+
*.js
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"type": "application",
3+
"source-directories": [
4+
"src"
5+
],
6+
"elm-version": "0.19.1",
7+
"dependencies": {
8+
"direct": {
9+
"elm/browser": "1.0.2",
10+
"elm/core": "1.0.5",
11+
"elm/html": "1.0.0",
12+
"elm/http": "2.0.0",
13+
"elm/json": "1.1.3",
14+
"elm/url": "1.0.0",
15+
"lamdera/codecs": "1.0.0",
16+
"lamdera/core": "1.0.0"
17+
},
18+
"indirect": {
19+
"elm/bytes": "1.0.8",
20+
"elm/file": "1.0.5",
21+
"elm/time": "1.0.0",
22+
"elm/virtual-dom": "1.0.3"
23+
}
24+
},
25+
"test-dependencies": {
26+
"direct": {},
27+
"indirect": {}
28+
}
29+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module Main exposing (main)
2+
3+
import Html exposing (Html)
4+
5+
6+
main : Html msg
7+
main =
8+
Html.div []
9+
[ Html.text (a1 1)
10+
, Html.text (a2 1)
11+
, Html.text (b1 1 1)
12+
, Html.text (b2 1 1)
13+
]
14+
15+
16+
a1 : Int -> String
17+
a1 =
18+
a2
19+
20+
21+
a2 : Int -> String
22+
a2 n =
23+
if n > 0 then
24+
a1 (n - 1)
25+
26+
else
27+
"done"
28+
29+
30+
b1 : Int -> Int -> String
31+
b1 =
32+
b2
33+
34+
35+
b2 : Int -> Int -> String
36+
b2 m n =
37+
if n > 0 then
38+
b1 (m - 1) (n - 1)
39+
40+
else
41+
"done"

0 commit comments

Comments
 (0)