git @ Cat's Eye Technologies ZOWIE / e0c29ab
Improve parser. Chris Pressey 1 year, 18 days ago
2 changed file(s) with 35 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
00 module Language.ZOWIE.Parser where
11
2 import Data.Maybe (catMaybes)
23 import Text.ParserCombinators.Parsec
4 (
5 many, string, satisfy, Parser, (<|>), digit, newline, optional, try, parse
6 )
37
48 import Language.ZOWIE.State
59
1721 -- Comment ::= ";" anything.
1822 --
1923
20 zowieLine = commentLine <|> instrLine
24 zowie = many zowieLine
25
26 zowieLine = (try commentLine) <|> instrLine
27
28 comment = do
29 spaces
30 string ";"
31 many $ satisfy (\x -> x /= '\n')
2132
2233 commentLine :: Parser (Maybe Instruction)
2334 commentLine = do
24 spaces
25 string ";"
26 many $ satisfy (\x -> x /= '\n')
35 optional comment
36 newline
2737 return Nothing
2838
2939 instrLine :: Parser (Maybe Instruction)
3444 spaces
3545 string ","
3646 src <- operand
37 optional commentLine
47 optional comment
48 newline
3849 return $ Just $ Mov dest src
3950
4051 operand = do
5768 n <- number
5869 return $ Immediate n
5970
71 -- ..................................................... --
72
6073 number = do
6174 c <- digit
6275 cs <- many digit
6376 num <- return (read (c:cs) :: Integer)
6477 return num
6578
79 spaces = many $ satisfy (\x -> x `elem` [' ', '\t'])
6680
67 parseLines [] = []
68 parseLines (line:lines) =
69 case parse zowieLine "" line of
70 Left err ->
71 parseLines lines
72 Right result ->
73 case result of
74 Just instr ->
75 (instr:parseLines lines)
76 Nothing ->
77 parseLines lines
81 -- ..................................................... --
7882
7983 parseZOWIE text =
80 let
81 lines = splitLines text []
82 prog = parseLines lines
83 in
84 prog
84 case parse zowie "" (text ++ "\n") of
85 Left err ->
86 Left err
87 Right maybes ->
88 Right (catMaybes maybes)
1111 args <- getArgs
1212 case args of
1313 ["parse", fileName] -> do
14 text <- readFile fileName
15 let prog = Parser.parseZOWIE text
14 prog <- loadSource fileName
1615 putStrLn $ show $ prog
1716 return ()
1817 ["run", fileName] -> do
19 text <- readFile fileName
20 let prog = Parser.parseZOWIE text
18 prog <- loadSource fileName
2119 result <- Machine.loadAndRun prog
2220 -- putStrLn $ show $ result
2321 return ()
2422 _ -> do
2523 abortWith "Usage: zowie (parse|run) <zowie-program-filename>"
2624
25 loadSource fileName = do
26 text <- readFile fileName
27 case Parser.parseZOWIE text of
28 Right prog -> do
29 return prog
30 Left error ->
31 abortWith $ show error
32
2733 abortWith msg = do
2834 hPutStrLn stderr msg
2935 exitWith (ExitFailure 1)