Small dependency ordering optimizations
This commit is contained in:
		| @ -62,4 +62,4 @@ jobs: | |||||||
|             ./tricu |             ./tricu | ||||||
|           token: '${{ secrets.RELEASE_TOKEN }}' |           token: '${{ secrets.RELEASE_TOKEN }}' | ||||||
|           body: '${{ gitea.event.head_commit.message }}' |           body: '${{ gitea.event.head_commit.message }}' | ||||||
|           pre_release: true |           prerelease: true | ||||||
|  | |||||||
							
								
								
									
										54
									
								
								src/Eval.hs
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								src/Eval.hs
									
									
									
									
									
								
							| @ -3,7 +3,7 @@ module Eval where | |||||||
| import Parser | import Parser | ||||||
| import Research | import Research | ||||||
|  |  | ||||||
| import Data.List (partition) | import Data.List (partition, (\\)) | ||||||
| import Data.Map  (Map) | import Data.Map  (Map) | ||||||
| import qualified Data.Map as Map | import qualified Data.Map as Map | ||||||
| import qualified Data.Set as Set | import qualified Data.Set as Set | ||||||
| @ -122,17 +122,20 @@ reorderDefs env defs | |||||||
|   | otherwise = orderedDefs ++ others |   | otherwise = orderedDefs ++ others | ||||||
|   where |   where | ||||||
|     (defsOnly, others) = partition isDef defs |     (defsOnly, others) = partition isDef defs | ||||||
|     graph              = buildDepGraph defsOnly |     defNames = [ name | SDef name _ _ <- defsOnly ] | ||||||
|     sortedDefs         = sortDeps graph |  | ||||||
|     defMap             = Map.fromList [(name, def) | def@(SDef name _ _) <- defsOnly] |     defsWithFreeVars = [(def, freeVars body) | def@(SDef _ _ body) <- defsOnly] | ||||||
|     orderedDefs        = map (\name -> defMap Map.! name) sortedDefs |  | ||||||
|     topDefNames        = Set.fromList (Map.keys defMap) |     graph = buildDepGraph defsOnly | ||||||
|     envNames           = Set.fromList (Map.keys env) |     sortedDefs = sortDeps graph | ||||||
|     freeVarsDefs       = foldMap (\(SDef _ _ body) -> freeVars body) defsOnly |     defMap = Map.fromList [(name, def) | def@(SDef name _ _) <- defsOnly] | ||||||
|     freeVarsOthers     = foldMap freeVars others |     orderedDefs = map (\name -> defMap Map.! name) sortedDefs | ||||||
|     allFreeVars        = freeVarsDefs <> freeVarsOthers |  | ||||||
|     validNames         = topDefNames `Set.union` envNames |     freeVarsDefs = foldMap snd defsWithFreeVars | ||||||
|     missingDeps        = Set.toList (allFreeVars `Set.difference` validNames) |     freeVarsOthers = foldMap freeVars others | ||||||
|  |     allFreeVars = freeVarsDefs <> freeVarsOthers | ||||||
|  |     validNames = Set.fromList defNames `Set.union` Set.fromList (Map.keys env) | ||||||
|  |     missingDeps = Set.toList (allFreeVars `Set.difference` validNames) | ||||||
|  |  | ||||||
|     isDef (SDef _ _ _) = True |     isDef (SDef _ _ _) = True | ||||||
|     isDef _            = False |     isDef _            = False | ||||||
| @ -153,20 +156,21 @@ buildDepGraph topDefs | |||||||
|     countOccurrences = foldr (\x -> Map.insertWith (+) x 1) Map.empty |     countOccurrences = foldr (\x -> Map.insertWith (+) x 1) Map.empty | ||||||
|  |  | ||||||
| sortDeps :: Map.Map String (Set.Set String) -> [String] | sortDeps :: Map.Map String (Set.Set String) -> [String] | ||||||
| sortDeps graph = go [] (Map.keys graph) | sortDeps graph = go [] Set.empty (Map.keys graph) | ||||||
|   where |   where | ||||||
|     go sorted [] = sorted |     go sorted sortedSet [] = sorted | ||||||
|     go sorted remaining |     go sorted sortedSet remaining = | ||||||
|       | null ready = |       let ready = [ name | name <- remaining | ||||||
|           errorWithoutStackTrace |                         , let deps = Map.findWithDefault Set.empty name graph | ||||||
|             "ERROR: Top-level cyclic dependency detected and prohibited\n\ |                         , Set.isSubsetOf deps sortedSet ] | ||||||
|            \RESOLVE: Use nested lambdas" |           notReady = remaining \\ ready | ||||||
|       | otherwise = go (sorted ++ ready) notReady |       in if null ready | ||||||
|       where |          then errorWithoutStackTrace | ||||||
|         ready    = [ name | name <- remaining |           "ERROR: Cyclic dependency detected and prohibited.\n\ | ||||||
|                     , all (`elem` sorted) (Set.toList (graph Map.! name))] |           \RESOLVE: Use nested lambdas." | ||||||
|         notReady = |          else go (sorted ++ ready) | ||||||
|           [ name | name <- remaining , name `notElem` ready] |                  (Set.union sortedSet (Set.fromList ready)) | ||||||
|  |                  notReady | ||||||
|  |  | ||||||
| depends :: [TricuAST] -> TricuAST -> Set.Set String | depends :: [TricuAST] -> TricuAST -> Set.Set String | ||||||
| depends topDefs (SDef _ _ body) = | depends topDefs (SDef _ _ body) = | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 James Eversole
						James Eversole