File: While.hs

package info (click to toggle)
ghc-cvs 20040725-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 68,484 kB
  • ctags: 19,658
  • sloc: haskell: 251,945; ansic: 109,709; asm: 24,961; sh: 12,825; perl: 5,786; makefile: 5,334; xml: 3,884; python: 682; yacc: 650; lisp: 477; cpp: 337; ml: 76; fortran: 24; csh: 18
file content (179 lines) | stat: -rw-r--r-- 5,966 bytes parent folder | download | duplicates (11)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
-------------------------------------------------------------
-- Parser for WHILE from Nielson, Nielson and Hankin
-- and various other sources.
-------------------------------------------------------------

module While( prettyWhileFromFile ) where

import WhileAS
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Expr
import qualified Text.ParserCombinators.Parsec.Token as P
import Text.ParserCombinators.Parsec.Language( javaStyle )


prettyWhileFromFile fname
  = do{ input <- readFile fname
      ; putStr input
      ; case parse program fname input of
           Left err -> do{ putStr "parse error at "
                           ; print err
                           }
           Right x  -> print x
      }

--renum :: Prog -> Prog
--renum p = rn (1,p)
--rn :: (Int, Stat) -> (Int, Stat)
--rn (x,s) = case s of
--            Assign vi ae _  -> (x+1,Assign vi ae x)
--            Skip _          -> (x+1, Skip x)
--            Seq [Stat]      -> 
--            If be _ s1 s2   -> do{ (newx, newthen) <- rn (x+1,s1)
--                                 ; (newerx, newelse) <- rn (newx,s2)
--                                 ; return (newerx, If be x newthen newelse)
--                                 }
--            While be _ s    -> do{ (newx, news) <- rn (x+1,s)
--                                 ; return (newx, While be x+1 news)
--                                 }

-----------------------------------------------------------
-- A program is simply an expression.
-----------------------------------------------------------
program 
    = do{ stats <- semiSep1 stat
        ; return (if length stats < 2 then head stats else Seq stats)
        }
        
stat :: Parser Stat
stat = choice 
       [ do { reserved "skip";
              return (Skip 0)
            }
       , ifStat
       , whileStat
       , sequenceStat
       , try assignStat
       ]


assignStat :: Parser Stat
assignStat = do{ id <- identifier
               ; symbol ":="
               ; s <- aritExpr
               ; return (Assign id s 0)
               }

ifStat :: Parser Stat
ifStat = do{ reserved "if"
             ; cond <- boolExpr
             ; reserved "then"
             ; thenpart <- stat
             ; reserved "else"
             ; elsepart <- stat
             ; return (If cond 0 thenpart elsepart)
             }
             
whileStat :: Parser Stat
whileStat = do{ reserved "while"
              ; cond <- boolExpr
              ; reserved "do"
              ; body <- stat
              ; return (While cond 0 body)
              }

sequenceStat :: Parser Stat
sequenceStat = do{ stats <- parens (semiSep1 stat)
                 ; return (if length stats < 2 then head stats else Seq stats)
                 }

boolExpr:: Parser BExp
boolExpr = buildExpressionParser boolOperators relExpr

relExpr :: Parser BExp
relExpr = do{ arg1 <- aritExpr
            ; op <- choice [string "=", try (string "<>"), try (string "<="), string "<", try (string ">="), string ">"]
            ; arg2 <- aritExpr
            ; return (RelOp op arg1 arg2)
            }

aritExpr :: Parser AExp
aritExpr = buildExpressionParser aritOperators simpleArit

-- Everything mapping bools to bools
boolOperators =
    [ [ prefix "not"]
    , [ opbb "and" AssocRight ] -- right for shortcircuit
    , [ opbb "or" AssocRight ] -- right for shortcircuit
    ]
    where
      opbb name assoc   = Infix (do{ reservedOp name
                                   ; return (\x y -> BOp name x y) 
                                   }) assoc
      prefix name       = Prefix  (do{ reservedOp name
                                  ; return (\x -> BUnOp name x)
                                  })                                      

-- Everything mapping pairs of ints to ints
aritOperators =
    [ [ op "*"  AssocLeft, op "/"  AssocLeft ]
    , [ op "+"  AssocLeft, op "-"  AssocLeft ]
    , [ op "&" AssocRight ] -- bitwise and delivering an int
    , [ op "|" AssocRight ] -- bitwise or delivering an int
    ]
    where
      op name assoc   = Infix (do{ reservedOp name
                                  ; return (\x y -> AOp name x y) 
                                  }) assoc


simpleArit = choice [ intLiteral
                    , parens aritExpr
                    , variable
                    ]

simpleBool = choice [ boolLiteral
                    , parens boolExpr
                    ]

boolLiteral = do{ reserved "false"
               ; return (BoolLit True)
               }
             <|>  
             do{ reserved "true"
               ; return (BoolLit False)
               }

intLiteral = do{ i <- integer; return (IntLit i) }
variable = do{ id <- identifier
             ; return (Var id)
             }
             

-----------------------------------------------------------
-- The lexer
-----------------------------------------------------------
lexer     = P.makeTokenParser whileDef

whileDef  = javaStyle
          { -- Kept the Java single line comments, but officially the language has no comments
            P.reservedNames  = [ "true", "false", "do", "else", "not",
                               "if", "then", "while", "skip"
                               -- , "begin", "proc", "is", "end", "val", "res", "malloc" 
                              ]
          , P.reservedOpNames= [ "and", "or", "not", "<", "<=", ">", ">=", ":=", "+", "&", "-", "/"]
          , P.opLetter       = oneOf (concat (P.reservedOpNames whileDef))
          , P.caseSensitive  = False
          }

parens          = P.parens lexer    
braces          = P.braces lexer    
semiSep1        = P.semiSep1 lexer    
whiteSpace      = P.whiteSpace lexer    
symbol          = P.symbol lexer    
identifier      = P.identifier lexer    
reserved        = P.reserved lexer    
reservedOp      = P.reservedOp lexer
integer         = P.integer lexer    
charLiteral     = P.charLiteral lexer    
stringLiteral   = P.stringLiteral lexer