commit 60b84ac

shrub  ·  2026-10-09 22:58:34 +0000 UTC
parent 79b33c8
parse basic macro assignments
1 files changed,  +33, -4
+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