commit 60b84ac
shrub
·
2026-10-09 22:58:34 +0000 UTC
parent 79b33c8
parse basic macro assignments
1 files changed,
+33,
-4
M
main.hs
M
main.hs
+33,
-4
1@@ -3,6 +3,7 @@ import Char (isSpace)
2 import Directory (doesFileExist)
3 import System (system, ExitCode(..))
4 import List (find)
5+import qualified Data.Map as Map
6
7 -- IF YOU USE GHC COMMENT THE ABOVE IMPORTS AND UNCOMMENT THESE
8 -- i dont reccomend to use GHC as it is not bootstrappable which
9@@ -11,13 +12,14 @@ import List (find)
10 -- import System.Directory (doesFileExist)
11 -- import System.Process (system)
12 -- import System.Exit (ExitCode(..))
13+-- import Data.List (find)
14
15 data TypedLine
16 = Blank
17- -- | Comment
18- | Recipe String
19- | Statement String
20- | Unknown String
21+ | Recipe String
22+ | Statement String
23+ | Assignment String
24+ | Unknown String
25 deriving (Show, Eq)
26
27 -- thanks ricardo for suggesting this
28@@ -32,6 +34,7 @@ parseLine ('\t':rest) = Recipe rest
29 parseLine line
30 | null trimmed = Blank
31 | elem ':' stripped = Statement stripped
32+ | elem '=' stripped = Assignment stripped
33 | otherwise = Unknown stripped
34 where
35 stripComment line = takeWhile(/= '#') line
36@@ -50,6 +53,7 @@ parseRules [] = Right []
37 parseRules (Unknown line : rest) = Left "unknown line type"
38 parseRules (Recipe line : rest) = Left "recipe without preceding dependency declaration"
39 parseRules (Blank : rest) = parseRules rest
40+parseRules (Assignment _ : rest) = parseRules rest
41 parseRules (Statement stmt : rest) = -- if you see stmt split into stmt and rest
42 -- split into 1) recipe lines immedtiately following the stmt
43 -- 2) everything else
44@@ -71,6 +75,28 @@ mkRule stmt recipeLines =
45 (lhs, ':':rhs) -> (lhs, words rhs)
46 _ -> error "statement has no colon"
47
48+-- take a string (assignment) and a map of assignments and return new map of assignments
49+parseAssign :: String -> Map.Map String String -> Map.Map String String
50+parseAssign line macros =
51+ let (name, val) = break(== '=') line
52+ trimmedName = trim name
53+ -- drop =
54+ trimmedVal = trim (drop 1 val)
55+ -- insert the pair into new map
56+ in Map.insert trimmedName trimmedVal macros
57+ where
58+ -- trim both sides
59+ trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace
60+
61+
62+collectAssigns :: [TypedLine] -> Map.Map String String
63+collectAssigns [] = Map.empty
64+-- if its an assignment parse it, add it to map, then keep iterating on remaning typed lines
65+collectAssigns (Assignment text : rest) = parseAssign text (collectAssigns rest)
66+-- if not assignment ignore
67+collectAssigns (_ : rest) = collectAssigns rest
68+
69+
70 findRule :: String -> [Rule] -> Maybe Rule
71 findRule name rules = find (\rule -> ruleName rule == name) rules
72
73@@ -115,6 +141,9 @@ main = do
74 mkf <- readFile "Makefile"
75 let rawLines = lines mkf
76 let parsedLines = map parseLine rawLines
77+ let macros = collectAssigns parsedLines
78+ -- xxx dont print em use em!
79+ print macros
80 case parseRules parsedLines of
81 Left message -> putStrLn ("parse error: " ++ message)
82 Right rules -> do