355ed6a002df0657b8e1628017574490bfd7d7c6
[cc1516.git] / src / parse.icl
1 implementation module parse
2
3 import StdString
4 import StdTuple
5 import StdList
6 from StdFunc import const
7 import Data.Either
8 import Data.Functor
9 import Data.Maybe
10 import Control.Monad
11 import Control.Applicative
12 import Data.Func
13 from Text import class Text(concat), instance Text String
14
15 import yard
16 import lex
17
18 parser :: LexerOutput -> ParserOutput
19 parser (Left e) = Left $ toString $ LexError e
20 parser (Right r) = case runParser parseProgram r of
21 (Right p, _) = Right p
22 (Left e, _) = Left $ toString e
23
24 parseProgram :: Parser Token AST
25 parseProgram = parseVarDecl >>= \t.pure $ AST [t] []
26
27 parseVarDecl :: Parser Token VarDecl
28 parseVarDecl =
29 (parseType <|> trans1 VarToken VarType )
30 >>= \t->parseIdent <* satTok AssignmentToken
31 >>= \i->parseExpr <* satTok SColonToken
32 >>= \e->pure $ VarDecl i t e
33
34 parseType :: Parser Token Type
35 parseType =
36 trans1 IntTypeToken IntType <|>
37 trans1 CharTypeToken CharType <|>
38 trans1 BoolTypeToken BoolType <|>
39 (satTok SquareOpenToken *> parseType <* satTok SquareCloseToken
40 >>= \t.pure $ ListType t) <|>
41 (satTok BraceOpenToken *> parseType <* satTok CommaToken
42 >>= \t1->parseType <* satTok BraceCloseToken
43 >>= \t2->pure $ TupleType t1 t2) <|>
44 (parseIdent >>= \e.pure $ IdType e) <|>
45 empty
46
47 parseExpr :: Parser Token Expr
48 parseExpr = parseOps (trans1 ColonToken BiCons) parseBinOrExpr
49 where
50 //Dit generaliseert het onderstaande, ik moet het nog even in elkaar
51 //sleutelen. Dan werkt bindingssterkte, associativiteit moet nog
52 // Wat je hier boven ziet wordt dan een cascade van operators met op
53 // het einde de parseBasicExpr. In volgorde van bindingssterkte, de
54 // zwaktste eerst...
55 parseOps :: (Parser Token Op2) (Parser Token Expr) -> Parser Token Expr
56 parseOps ops prev = prev >>= \e1->optional (
57 ops >>= \op->parseOps ops prev >>= \e->pure (op, e)
58 ) >>= \moe-> pure case moe of
59 Nothing = e1
60 (Just (op, e2)) = Op2Expr e1 op e2
61
62 parseBinOrExpr :: Parser Token Expr
63 parseBinOrExpr =
64 parseBinAndExpr >>= \e1-> optional (
65 trans1 PipesToken BiOr
66 >>= \op->parseBinOrExpr >>= \e->pure (op, e))
67 >>= \moe->pure case moe of
68 Nothing = e1
69 (Just (op, e2)) = Op2Expr e1 op e2
70
71 parseBinAndExpr :: Parser Token Expr
72 parseBinAndExpr =
73 parseCompareExpr >>= \e1-> optional (
74 trans1 AmpersandsToken BiAnd
75 >>= \op->parseBinAndExpr >>= \e->pure (op, e))
76 >>= \moe->pure case moe of
77 Nothing = e1
78 (Just (op, e2)) = Op2Expr e1 op e2
79
80 parseCompareExpr :: Parser Token Expr
81 parseCompareExpr =
82 parsePlusMinusExpr >>= \e1-> optional (
83 ( trans1 EqualsToken BiEquals <|>
84 trans1 LesserToken BiLesser <|>
85 trans1 BiggerToken BiGreater <|>
86 trans1 LesserEqToken BiLesserEq <|>
87 trans1 GreaterEqToken BiGreaterEq <|>
88 trans1 NotEqualToken BiUnEqual
89 ) >>= \op->parseCompareExpr >>= \e->pure (op, e))
90 >>= \moe->pure case moe of
91 Nothing = e1
92 (Just (op, e2)) = Op2Expr e1 op e2
93
94 parsePlusMinusExpr :: Parser Token Expr
95 parsePlusMinusExpr =
96 parseTimesDivExpr >>= \e1-> optional (
97 ( trans1 PlusToken BiPlus <|>
98 trans1 DashToken BiMinus
99 ) >>= \op->parsePlusMinusExpr >>= \e->pure (op, e))
100 >>= \moe->pure case moe of
101 Nothing = e1
102 (Just (op, e2)) = Op2Expr e1 op e2
103
104 parseTimesDivExpr :: Parser Token Expr
105 parseTimesDivExpr =
106 parseBasicExpr >>= \e1->optional (
107 ( trans1 StarToken BiTimes <|>
108 trans1 SlashToken BiDivide <|>
109 trans1 PercentToken BiMod
110 ) >>= \op->parseTimesDivExpr >>= \e->pure (op, e))
111 >>= \moe-> pure case moe of
112 Nothing = e1
113 (Just (op, e2)) = Op2Expr e1 op e2
114
115 parseBasicExpr :: Parser Token Expr
116 parseBasicExpr =
117 (satTok BraceOpenToken *> parseExpr <* satTok BraceCloseToken) <|>
118 (satTok BraceOpenToken *> parseExpr <* satTok CommaToken
119 >>= \e1->parseExpr <* satTok BraceCloseToken
120 >>= \e2->pure $ TupleExpr e1 e2) <|>
121 trans1 EmptyListToken EmptyListExpr <|>
122 trans2 TrueToken (const $ BoolExpr True) <|>
123 trans2 FalseToken (const $ BoolExpr True) <|>
124 trans2 (NumberToken zero) (\(NumberToken i)->IntExpr i) <|>
125 trans2 (CharToken zero) (\(CharToken c)->CharExpr c) <|>
126 (parseOp1 >>= \o->parseExpr >>= \e.pure $ Op1Expr o e) <|>
127 (parseIdent <* satTok BraceOpenToken
128 >>= \i->parseActArgs <* satTok BraceCloseToken
129 >>= \es->pure $ FunExpr i es) <|>
130 (parseIdent >>= \i. parseFieldSelector >>= \f.pure $ VarExpr i f)
131
132 parseActArgs :: Parser Token [Expr]
133 parseActArgs =
134 (some (parseExpr <* satTok CommaToken) >>= \es->parseExpr
135 >>= \e.pure [e:es]) <|>
136 (parseExpr >>= \e->pure [e]) <|>
137 empty
138
139 parseOp1 :: Parser Token Op1
140 parseOp1 = trans1 DashToken UnMinus <|>
141 trans1 ExclamationToken UnNegation
142
143 parseFieldSelector :: Parser Token (Maybe FieldSelector)
144 parseFieldSelector = optional (satTok DotToken *> (
145 (parseIdent >>= (\i.if (i == "hd") (pure FieldHd) empty)) <|>
146 (parseIdent >>= \i.if (i == "tl") (pure FieldTl) empty) <|>
147 (parseIdent >>= \i.if (i == "fst") (pure FieldFst) empty) <|>
148 (parseIdent >>= \i.if (i == "snd") (pure FieldSnd) empty)))
149
150 trans2 :: TokenValue (TokenValue -> a) -> Parser Token a
151 trans2 t f = satTok t >>= \(_, r).pure (f r)
152
153 trans1 :: TokenValue a -> Parser Token a
154 trans1 t r = trans2 t $ const r
155
156 satTok :: TokenValue -> Parser Token Token
157 satTok t = satisfy ((===) t)
158
159 parseIdent :: Parser Token String
160 parseIdent = trans2 (IdentToken []) (\(IdentToken e).toString e)
161
162 instance toString AST where
163 toString (AST v f) = concat (print v ++ ["\n":print f])
164
165 class print a :: a -> [String]
166
167 instance print [a] | print a where
168 print [] = ["\n"]
169 print [v:vs] = print v ++ ["\n":print vs]
170
171 instance print VarDecl where
172 print (VarDecl i t e) = print t ++ [" ":i:"=":print e] ++ [";"]
173 instance print FunDecl where
174 print _ = ["Function printing not yet implemented"]
175
176 instance print Type where
177 print (TupleType t1 t2) = ["(":print t1] ++ [", ":print t2] ++ [")"]
178 print (ListType t) = ["[":print t] ++ ["]"]
179 print (IdType s) = [s]
180 print IntType = ["Int"]
181 print BoolType = ["Bool"]
182 print CharType = ["Char"]
183 print VarType = ["var"]
184
185 instance print Expr where
186 print (VarExpr i Nothing) = [i]
187 print (VarExpr i (Just mf)) = [i, case mf of
188 FieldHd = ".hd"; FieldTl = ".tl"
189 FieldSnd = ".snd"; FieldFst = ".fst"]
190 print (Op2Expr e1 o e2) = print e1 ++ [case o of
191 BiPlus = "+"; BiMinus = "-"; BiTimes = "*"; BiDivide = "/"
192 BiMod = "%"; BiEquals = "="; BiLesser = "<"; BiGreater = ">"
193 BiLesserEq = "<="; BiGreaterEq = ">="; BiUnEqual = "!=";
194 BiAnd = "&&"; BiOr = "||"; BiCons = ":"
195 :print e2]
196 print (Op1Expr o e) = [case o of
197 UnNegation = "!"; UnMinus = "-"
198 :print e]
199 print (IntExpr i) = [toString i]
200 print (CharExpr c) = ["\'", case c of
201 '\b' = "\\b"; '\f' = "\\f"; '\n' = "\\n"
202 '\r' = "\\r"; '\t' = "\\t"; '\v' = "\\v"
203 c = if (c == toChar 7) "\\a" (toString c)
204 ,"\'"]
205 print (BoolExpr b) = [toString b]
206 print (FunExpr i es) = pe ++ flatten [[",":x]\\x<-tl pes]
207 where [pe:pes] = map print es
208 print EmptyListExpr = ["[]"]
209 print (TupleExpr e1 e2) = ["(":print e1] ++ [",":print e2] ++ [")"]