commit c3b34f5
shrub
·
2026-10-26 11:42:08 +0000 UTC
parent 3fbde99
more
1 files changed,
+14,
-40
M
main.hs
M
main.hs
+14,
-40
1@@ -37,8 +37,7 @@ parseLine line
2 | elem '=' stripped = Assignment stripped
3 | otherwise = Unknown stripped
4 where
5- stripComment line = takeWhile(/= '#') line
6- stripped = stripComment line
7+ stripped = takeWhile(/= '#') line
8 trimmed = dropWhile isSpace stripped
9
10 isRecipe :: TypedLine -> Bool
11@@ -52,15 +51,12 @@ parseRules :: [TypedLine] -> Either String [Rule]
12 parseRules [] = Right []
13 parseRules (Unknown line : rest) = Left "unknown line type"
14 parseRules (Recipe line : rest) = Left "recipe without preceding dependency declaration"
15-parseRules (Blank : rest) = parseRules rest
16-parseRules (Assignment _ : rest) = parseRules rest
17 parseRules (Statement stmt : rest) = -- if you see stmt split into stmt and rest
18 -- split into 1) recipe lines immedtiately following the stmt
19 -- 2) everything else
20 let (recipeLines, remaining) = span isRecipe rest
21- -- create a rule with the statement and recipe lines
22- currentRule = mkRule stmt recipeLines
23- in fmap (currentRule :) (parseRules remaining)
24+ in fmap (mkRule stmt recipeLines :) (parseRules remaining)
25+parseRules (_ : rest) = parseRules rest
26
27 -- we take a string and a list of typed lines and produce a rule
28 mkRule :: String -> [TypedLine] -> Rule
29@@ -100,16 +96,8 @@ expandMacro _ [] = []
30 expandMacro macros ('$':'(':rest) =
31 let (name, afterName) = break (== ')') rest
32 in case afterName of
33- ')':after ->
34- -- search for the macro
35- case Map.lookup name macros of
36- Just value ->
37- -- expand the macro's value and the remaining text
38- expandMacro macros value ++ expandMacro macros after
39- Nothing ->
40- -- replace with an empty string and expand the rest
41- expandMacro macros after
42- -- for a case where theres no closing )
43+ ')':after -> maybe "" (expandMacro macros) (Map.lookup name macros)
44+ ++ expandMacro macros after
45 _ -> "$(" ++ rest
46 expandMacro macros (char:rest) = char : expandMacro macros rest
47
48@@ -121,32 +109,18 @@ expandLine _ line = line
49 findRule :: String -> [Rule] -> Maybe Rule
50 findRule name rules = find (\rule -> ruleName rule == name) rules
51
52--- take a list of rules, a target name and return its recipe
53-targetRecipes :: [Rule] -> String -> [String]
54-targetRecipes rules name = maybe [] ruleRecipes(findRule name rules)
55-
56 -- take a list of rules,
57 -- a target name and do DFS, return list of rules in correct order
58 orderTarget :: [Rule] -> String -> [Rule]
59 orderTarget rules wanted =
60- case findRule wanted rules of
61- Nothing -> [Rule wanted [] []]
62- Just rule ->
63- let prereqs = rulePrereqs rule
64- -- run "orderTarget rules" on every prereq in prereqs
65- -- this returns a list of dependency lists so use concat
66- -- to just make it one list
67- in concatMap (orderTarget rules) prereqs ++ [rule]
68- -- xxx handle cycles and duplicates
69+ maybe [Rule wanted [] []] expand (findRule wanted rules)
70+ where expand rule = concatMap (orderTarget rules) (rulePrereqs rule) ++ [rule]
71
72 -- print and run a recipe
73 runRecipe :: String -> IO Bool
74 runRecipe command = do
75 putStrLn command
76- exitCode <- system command
77- case exitCode of
78- ExitSuccess -> return True
79- ExitFailure _ -> return False
80+ fmap (== ExitSuccess) (system command)
81
82 -- this should prob be called isSource or smth as a leaf can have a recipe
83 -- as long as it has no prereqs but whateva
84@@ -157,9 +131,9 @@ main :: IO ()
85 main = do
86 mkf <- readFile "Makefile"
87 let rawLines = lines mkf
88- let parsedLines = map parseLine rawLines
89- let macros = collectAssigns parsedLines
90- let expandedLines = map (expandLine macros) parsedLines
91+ parsedLines = map parseLine rawLines
92+ macros = collectAssigns parsedLines
93+ expandedLines = map (expandLine macros) parsedLines
94 case parseRules expandedLines of
95 Left message -> putStrLn ("parse error: " ++ message)
96 Right rules ->
97@@ -168,9 +142,9 @@ main = do
98 firstRule: _ -> do
99 -- xxx cli option for requested target
100 let wanted = ruleName firstRule
101- let order = (orderTarget rules wanted)
102- let leafs = filter isLeaf order
103- let leafNames = map ruleName leafs
104+ order = (orderTarget rules wanted)
105+ leafs = filter isLeaf order
106+ leafNames = map ruleName leafs
107 exists <- mapM doesFileExist leafNames
108 let recipes = concatMap ruleRecipes order
109 if and exists