git @ Cat's Eye Technologies ZOWIE / cef45db
Beginnings of Parsec parser. Chris Pressey 11 months ago
1 changed file(s) with 65 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
00 module Language.ZOWIE.Parser where
1
2 import Text.ParserCombinators.Parsec
13
24 import Language.ZOWIE.State
35
79 splitLines ('\n':rest) line = [reverse line] ++ (splitLines rest [])
810 splitLines (char:rest) line = splitLines rest (char:line)
911
12 --
13 -- The grammar of a line is
14 --
15 -- Line ::= Comment | "MOV" Operand "," Operand [Comment].
16 -- Operand ::= "R[R" Number "]" | "R" Number | Number.
17 -- Comment ::= ";" anything.
18 --
19
20 zowieLine = commentLine <|> instrLine
21
22 commentLine :: Parser (Maybe Instruction)
23 commentLine = do
24 spaces
25 string ";"
26 many $ satisfy (\x -> x /= '\n')
27 return Nothing
28
29 instrLine :: Parser (Maybe Instruction)
30 instrLine = do
31 spaces
32 string "MOV"
33 dest <- operand
34 spaces
35 string ","
36 src <- operand
37 optional commentLine
38 return $ Just $ Mov dest src
39
40 operand = do
41 spaces
42 r <- indirect <|> direct <|> immediate
43 return r
44
45 indirect = do
46 string "R[R"
47 n <- number
48 string "]"
49 return $ Indirect n
50
51 direct = do
52 string "R"
53 n <- number
54 return $ Direct n
55
56 immediate = do
57 n <- number
58 return $ Direct n
59
60 number = do
61 c <- digit
62 cs <- many digit
63 num <- return (read (c:cs) :: Integer)
64 return num
65
66
1067 parseLines [] = []
1168 parseLines (line:lines) =
12 case parseLine line of
13 Just instr ->
14 (instr:parseLines lines)
15 Nothing ->
69 case parse zowieLine "" line of
70 Left err ->
1671 parseLines lines
17
18 parseLine [] = Nothing
19 parseLine (' ':rest) = parseLine rest
20 parseLine ('M':'O':'V':rest) = Just $ Mov (Direct 0) (Immediate 0)
21
72 Right result ->
73 case result of
74 Just instr ->
75 (instr:parseLines lines)
76 Nothing ->
77 parseLines lines
2278
2379 parseZOWIE text =
2480 let