Skip to content

Commit 2fdecf8

Browse files
committed
Make many stack safe
1 parent c931480 commit 2fdecf8

File tree

2 files changed

+20
-38
lines changed

2 files changed

+20
-38
lines changed

bench/BenchFile.purs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import PureScript.CST (parseModule)
1717

1818
main :: Effect Unit
1919
main = launchAff_ do
20-
args <- Array.drop 2 <$> liftEffect Process.argv
20+
args <- Array.drop 1 <$> liftEffect Process.argv
2121
case Array.head args of
2222
Just fileName -> do
2323
contents <- liftEffect <<< Buffer.toString UTF8 =<< readFile fileName

src/PureScript/CST/Parser/Monad.purs

+19-37
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,11 @@ import Prelude
2121

2222
import Control.Alt (class Alt, (<|>))
2323
import Control.Lazy (class Lazy)
24-
import Control.Monad.ST as ST
25-
import Control.Monad.ST.Internal as STRef
2624
import Data.Array as Array
27-
import Data.Array.ST as STArray
2825
import Data.Either (Either(..))
2926
import Data.Function.Uncurried (Fn2, Fn4, mkFn2, mkFn4, runFn2, runFn4)
3027
import Data.Lazy as Lazy
28+
import Data.List as List
3129
import Data.Maybe (Maybe(..))
3230
import Data.Tuple (Tuple(..))
3331
import PureScript.CST.Errors (ParseError(..))
@@ -208,41 +206,25 @@ lookAhead (Parser p) = Parser
208206
)
209207

210208
many :: forall a. Parser a -> Parser (Array a)
211-
many parser = Parser
212-
( mkFn4 \state1 _ resume done -> do
209+
many (Parser p) = Parser
210+
( mkFn4 \state1 more resume done -> do
213211
let
214-
result = ST.run do
215-
valuesRef <- STArray.new
216-
stateRef <- STRef.new state1
217-
contRef <- STRef.new true
218-
resRef <- STRef.new (ParseSucc [] state1)
219-
ST.while (STRef.read contRef) do
220-
state2 <- STRef.read stateRef
221-
let
222-
state2' =
223-
if state2.consumed then state2 { consumed = false }
224-
else state2
225-
case runParser' state2' parser of
226-
ParseFail error state3 ->
227-
if state3.consumed then do
228-
_ <- STRef.write (ParseFail error state3) resRef
229-
_ <- STRef.write false contRef
230-
pure unit
231-
else do
232-
values <- STArray.unsafeFreeze valuesRef
233-
_ <- STRef.write (ParseSucc values state2) resRef
234-
_ <- STRef.write false contRef
235-
pure unit
236-
ParseSucc value state3 -> do
237-
_ <- STArray.push value valuesRef
238-
_ <- STRef.write state3 stateRef
239-
pure unit
240-
STRef.read resRef
241-
case result of
242-
ParseFail error state2 ->
243-
runFn2 resume state2 error
244-
ParseSucc values state2 ->
245-
runFn2 done state2 values
212+
go = mkFn2 \acc state2 -> do
213+
let
214+
state2' =
215+
if state2.consumed then state2 { consumed = false }
216+
else state2
217+
runFn4 p state2' more
218+
( mkFn2 \state3 error ->
219+
if state3.consumed then
220+
runFn2 resume state3 error
221+
else
222+
runFn2 done state3 (Array.reverse (List.toUnfoldable acc))
223+
)
224+
( mkFn2 \state3 value ->
225+
runFn2 go (List.Cons value acc) state3
226+
)
227+
runFn2 go List.Nil state1
246228
)
247229

248230
optional :: forall a. Parser a -> Parser (Maybe a)

0 commit comments

Comments
 (0)