From f3f7694ed10941812d38be0676927450d5ebd237 Mon Sep 17 00:00:00 2001 From: Decio Ferreira Date: Thu, 20 Feb 2025 21:56:57 +0000 Subject: [PATCH] WIP RangeError: Maximum call stack size exceeded error --- src/Compiler/Canonicalize/Expression.elm | 70 +++++++-------- src/Compiler/Canonicalize/Pattern.elm | 18 ++-- src/Compiler/Reporting/Result.elm | 107 +++++++++++++++-------- 3 files changed, 113 insertions(+), 82 deletions(-) diff --git a/src/Compiler/Canonicalize/Expression.elm b/src/Compiler/Canonicalize/Expression.elm index bc5c0586f..89e121233 100644 --- a/src/Compiler/Canonicalize/Expression.elm +++ b/src/Compiler/Canonicalize/Expression.elm @@ -478,7 +478,7 @@ addDefNodes env nodes (A.At _ def) = case canonicalize env body of R.RResult k -> case k Dict.empty ws of - Ok (R.ROk freeLocals warnings cbody) -> + R.ROk freeLocals warnings cbody -> let names : List (A.Located Name) names = @@ -492,15 +492,13 @@ addDefNodes env nodes (A.At _ def) = node = ( Destruct cpattern cbody, name, Dict.keys compare freeLocals ) in - Ok - (R.ROk - (Utils.mapUnionWith identity compare combineUses fs freeLocals) - warnings - (List.foldl (addEdge [ name ]) (node :: nodes) names) - ) + R.ROk + (Utils.mapUnionWith identity compare combineUses fs freeLocals) + warnings + (List.foldl (addEdge [ name ]) (node :: nodes) names) - Err (R.RErr freeLocals warnings errors) -> - Err (R.RErr (Utils.mapUnionWith identity compare combineUses freeLocals fs) warnings errors) + R.RErr freeLocals warnings errors -> + R.RErr (Utils.mapUnionWith identity compare combineUses freeLocals fs) warnings errors ) ) @@ -509,23 +507,21 @@ logLetLocals : List arg -> FreeLocals -> value -> EResult FreeLocals w value logLetLocals args letLocals value = R.RResult (\freeLocals warnings -> - Ok - (R.ROk - (Utils.mapUnionWith identity - compare - combineUses - freeLocals - (case args of - [] -> - letLocals - - _ -> - Dict.map (\_ -> delayUse) letLocals - ) + R.ROk + (Utils.mapUnionWith identity + compare + combineUses + freeLocals + (case args of + [] -> + letLocals + + _ -> + Dict.map (\_ -> delayUse) letLocals ) - warnings - value ) + warnings + value ) @@ -701,7 +697,7 @@ logVar : Name.Name -> a -> EResult FreeLocals w a logVar name value = R.RResult <| \freeLocals warnings -> - Ok (R.ROk (Utils.mapInsertWith identity combineUses name oneDirectUse freeLocals) warnings value) + R.ROk (Utils.mapInsertWith identity combineUses name oneDirectUse freeLocals) warnings value oneDirectUse : Uses @@ -741,7 +737,7 @@ verifyBindings context bindings (R.RResult k) = R.RResult (\info warnings -> case k Dict.empty warnings of - Ok (R.ROk freeLocals warnings1 value) -> + R.ROk freeLocals warnings1 value -> let outerFreeLocals : Dict String Name Uses outerFreeLocals = @@ -758,10 +754,10 @@ verifyBindings context bindings (R.RResult k) = Dict.foldl compare (addUnusedWarning context) warnings1 <| Dict.diff bindings freeLocals in - Ok (R.ROk info warnings2 ( value, outerFreeLocals )) + R.ROk info warnings2 ( value, outerFreeLocals ) - Err (R.RErr _ warnings1 err) -> - Err (R.RErr info warnings1 err) + R.RErr _ warnings1 err -> + R.RErr info warnings1 err ) @@ -775,11 +771,11 @@ directUsage (R.RResult k) = R.RResult (\freeLocals warnings -> case k () warnings of - Ok (R.ROk () ws ( value, newFreeLocals )) -> - Ok (R.ROk (Utils.mapUnionWith identity compare combineUses freeLocals newFreeLocals) ws value) + R.ROk () ws ( value, newFreeLocals ) -> + R.ROk (Utils.mapUnionWith identity compare combineUses freeLocals newFreeLocals) ws value - Err (R.RErr () ws es) -> - Err (R.RErr freeLocals ws es) + R.RErr () ws es -> + R.RErr freeLocals ws es ) @@ -788,16 +784,16 @@ delayedUsage (R.RResult k) = R.RResult (\freeLocals warnings -> case k () warnings of - Ok (R.ROk () ws ( value, newFreeLocals )) -> + R.ROk () ws ( value, newFreeLocals ) -> let delayedLocals : Dict String Name Uses delayedLocals = Dict.map (\_ -> delayUse) newFreeLocals in - Ok (R.ROk (Utils.mapUnionWith identity compare combineUses freeLocals delayedLocals) ws value) + R.ROk (Utils.mapUnionWith identity compare combineUses freeLocals delayedLocals) ws value - Err (R.RErr () ws es) -> - Err (R.RErr freeLocals ws es) + R.RErr () ws es -> + R.RErr freeLocals ws es ) diff --git a/src/Compiler/Canonicalize/Pattern.elm b/src/Compiler/Canonicalize/Pattern.elm index d96011d58..ffa23d680 100644 --- a/src/Compiler/Canonicalize/Pattern.elm +++ b/src/Compiler/Canonicalize/Pattern.elm @@ -41,18 +41,18 @@ verify context (R.RResult k) = R.RResult <| \info warnings -> case k Dups.none warnings of - Err (R.RErr _ warnings1 errors) -> - Err (R.RErr info warnings1 errors) + R.RErr _ warnings1 errors -> + R.RErr info warnings1 errors - Ok (R.ROk bindings warnings1 value) -> + R.ROk bindings warnings1 value -> case Dups.detect (Error.DuplicatePattern context) bindings of R.RResult k1 -> case k1 () () of - Err (R.RErr () () errs) -> - Err (R.RErr info warnings1 errs) + R.RErr () () errs -> + R.RErr info warnings1 errs - Ok (R.ROk () () dict) -> - Ok (R.ROk info warnings1 ( value, dict )) + R.ROk () () dict -> + R.ROk info warnings1 ( value, dict ) @@ -177,7 +177,7 @@ logVar : Name.Name -> A.Region -> a -> PResult DupsDict w a logVar name region value = R.RResult <| \bindings warnings -> - Ok (R.ROk (Dups.insert name region region bindings) warnings value) + R.ROk (Dups.insert name region region bindings) warnings value logFields : List (A.Located Name.Name) -> a -> PResult DupsDict w a @@ -189,4 +189,4 @@ logFields fields value = in R.RResult <| \bindings warnings -> - Ok (R.ROk (List.foldl addField bindings fields) warnings value) + R.ROk (List.foldl addField bindings fields) warnings value diff --git a/src/Compiler/Reporting/Result.elm b/src/Compiler/Reporting/Result.elm index 9d6aa54aa..2742524d4 100644 --- a/src/Compiler/Reporting/Result.elm +++ b/src/Compiler/Reporting/Result.elm @@ -1,11 +1,12 @@ module Compiler.Reporting.Result exposing - ( RErr(..) - , ROk(..) - , RResult(..) + ( RResult(..) + , RStep(..) + , Step(..) , apply , bind , fmap , indexedTraverse + , loop , mapTraverseWithKey , ok , pure @@ -28,32 +29,56 @@ import Data.Map as Dict exposing (Dict) type RResult info warnings error a - = RResult - (info - -> warnings - -> Result (RErr info warnings error) (ROk info warnings a) - ) + = RResult (info -> warnings -> RStep info warnings error a) -type ROk info warnings a +type RStep info warnings error a = ROk info warnings a - - -type RErr info warnings error - = RErr info warnings (OneOrMore.OneOrMore error) + | RErr info warnings (OneOrMore.OneOrMore error) run : RResult () (List w) e a -> ( List w, Result (OneOrMore.OneOrMore e) a ) run (RResult k) = case k () [] of - Ok (ROk () w a) -> + ROk () w a -> ( List.reverse w, Ok a ) - Err (RErr () w e) -> + RErr () w e -> ( List.reverse w, Err e ) +-- LOOP + + +type Step state a + = Loop state + | Done a + + +loop : (state -> RResult i w e (Step state a)) -> state -> RResult i w e a +loop callback state = + RResult <| + \i w -> + loopHelp callback i w state + + +loopHelp : (state -> RResult i w e (Step state a)) -> i -> w -> state -> RStep i w e a +loopHelp callback i w state = + case callback state of + RResult k -> + case k i w of + RErr i1 w1 e -> + RErr i1 w1 e + + ROk i1 w1 (Loop newState) -> + loopHelp callback i1 w1 newState + + ROk i1 w1 (Done a) -> + ROk i1 w1 a + + + -- HELPERS @@ -61,21 +86,21 @@ ok : a -> RResult i w e a ok a = RResult <| \i w -> - Ok (ROk i w a) + ROk i w a warn : Warning.Warning -> RResult i (List Warning.Warning) e () warn warning = RResult <| \i warnings -> - Ok (ROk i (warning :: warnings) ()) + ROk i (warning :: warnings) () throw : e -> RResult i w e a throw e = RResult <| \i w -> - Err (RErr i w (OneOrMore.one e)) + RErr i w (OneOrMore.one e) @@ -86,8 +111,12 @@ fmap : (a -> b) -> RResult i w e a -> RResult i w e b fmap func (RResult k) = RResult <| \i w -> - Result.map (\(ROk i1 w1 value) -> ROk i1 w1 (func value)) - (k i w) + case k i w of + ROk i1 w1 value -> + ROk i1 w1 (func value) + + RErr i1 w1 e -> + RErr i1 w1 e pure : a -> RResult i w e a @@ -100,41 +129,47 @@ apply (RResult kv) (RResult kf) = RResult <| \i w -> case kf i w of - Ok (ROk i1 w1 func) -> - Result.map (\(ROk i2 w2 value) -> ROk i2 w2 (func value)) - (kv i1 w1) + ROk i1 w1 func -> + case kv i1 w1 of + ROk i2 w2 value -> + ROk i2 w2 (func value) + + RErr i2 w2 e2 -> + RErr i2 w2 e2 - Err (RErr i1 w1 e1) -> + RErr i1 w1 e1 -> case kv i1 w1 of - Ok (ROk i2 w2 _) -> - Err (RErr i2 w2 e1) + ROk i2 w2 _ -> + RErr i2 w2 e1 - Err (RErr i2 w2 e2) -> - Err (RErr i2 w2 (OneOrMore.more e1 e2)) + RErr i2 w2 e2 -> + RErr i2 w2 (OneOrMore.more e1 e2) bind : (a -> RResult i w x b) -> RResult i w x a -> RResult i w x b bind callback (RResult ka) = RResult <| \i w -> - Result.andThen - (\(ROk i1 w1 a) -> + case ka i w of + ROk i1 w1 a -> case callback a of RResult kb -> kb i1 w1 - ) - (ka i w) + + RErr i1 w1 e -> + RErr i1 w1 e then_ : RResult i w x a -> RResult i w x b -> RResult i w x b then_ (RResult ka) (RResult kb) = RResult <| \i w -> - Result.andThen - (\(ROk i1 w1 _) -> + case ka i w of + ROk i1 w1 _ -> kb i1 w1 - ) - (ka i w) + + RErr i1 w1 e1 -> + RErr i1 w1 e1 traverse : (a -> RResult i w x b) -> List a -> RResult i w x (List b)