24b860badabe32eb74d4590df96623033b895ab8
[cc1516.git] / parse.icl
1 implementation module parse
2
3 import StdString
4 import StdTuple
5 import StdList
6 from StdFunc import const, o
7 import Data.Either
8 import Data.Maybe
9 import Control.Monad
10 import Control.Applicative
11 import Data.Func
12 from Data.List import intercalate, replicate, instance Functor []
13 from Text import class Text(concat), instance Text String
14 import GenPrint
15
16 import yard
17 import lex
18 import AST
19
20 parser :: LexerOutput -> ParserOutput
21 parser (Left e) = Left e
22 parser (Right r) = fst $ runParser parseProgram r
23
24 parseProgram :: Parser Token AST
25 parseProgram = liftM2 AST (many parseVarDecl) (some parseFunDecl)
26
27 parseFunDecl :: Parser Token FunDecl
28 parseFunDecl = liftM5 FunDecl
29 (parseIdent <* satTok BraceOpenToken)
30 (parseSepList CommaToken parseIdent <* satTok BraceCloseToken)
31 (optional parseFunType <* satTok CBraceOpenToken)
32 (many parseVarDecl)
33 (many parseStmt <* satTok CBraceCloseToken)
34
35 parseStmt :: Parser Token Stmt
36 parseStmt = parseIfStmt <|> parseWhileStmt <|>
37 parseSColon parseAssStmt <|> parseSColon parseReturnStmt <|>
38 (liftM FunStmt (parseSColon parseFunCall))
39 where
40 parseSColon :: (Parser Token a) -> Parser Token a
41 parseSColon p = p <* satTok SColonToken
42
43 parseReturnStmt :: Parser Token Stmt
44 parseReturnStmt =
45 satTok ReturnToken *> liftM ReturnStmt (optional parseExpr)
46
47 parseAssStmt :: Parser Token Stmt
48 parseAssStmt =
49 liftM2 AssStmt (parseVarDef <* satTok AssignmentToken) parseExpr
50
51 parseIfStmt :: Parser Token Stmt
52 parseIfStmt = liftM3 IfStmt
53 (satTok IfToken *> parseBBraces parseExpr)
54 (parseBlock <|> parseOneLine)
55 (liftM (fromMaybe [])
56 (optional (satTok ElseToken *> (parseBlock<|> parseOneLine))))
57
58 parseWhileStmt :: Parser Token Stmt
59 parseWhileStmt = satTok WhileToken *>
60 liftM2 WhileStmt (parseBBraces parseExpr) parseBlock
61
62 parseBlock :: Parser Token [Stmt]
63 parseBlock = parseBCBraces (many parseStmt)
64
65 parseOneLine :: Parser Token [Stmt]
66 //first pure makes singleton list from the statement
67 parseOneLine = liftM pure parseStmt
68
69 parseFunType :: Parser Token FunType
70 parseFunType = satTok DoubleColonToken *>
71 (parseInOutType <|> (liftM (FunType []) parseVoidOrType))
72 where
73 parseInOutType :: Parser Token FunType
74 parseInOutType = liftM2 FunType
75 (some parseType <* satTok ArrowToken) parseVoidOrType
76
77 parseVoidOrType :: Parser Token (Maybe Type)
78 parseVoidOrType = (satTok VoidToken *> pure Nothing) <|>
79 (liftM Just parseType) <|> pure Nothing
80
81 parseVarDecl :: Parser Token VarDecl
82 parseVarDecl = liftM3 VarDecl
83 (parseType <|> trans1 VarToken VarType )
84 (parseIdent <* satTok AssignmentToken)
85 (parseExpr <* satTok SColonToken)
86
87 parseType :: Parser Token Type
88 parseType =
89 trans1 IntTypeToken IntType <|>
90 trans1 CharTypeToken CharType <|>
91 trans1 BoolTypeToken BoolType <|>
92 (liftM ListType (parseBSqBraces parseType)) <|>
93 (liftM TupleType (parseTuple parseType)) <|>
94 (liftM IdType parseIdent)
95
96 parseExpr :: Parser Token Expr
97 parseExpr = //Operators in order of binding strength
98 parseOpR (trans1 ColonToken BiCons) $
99 parseOpR (trans1 PipesToken BiOr) $
100 parseOpR (trans1 AmpersandsToken BiAnd) $
101 parseOpR (trans1 EqualsToken BiEquals <|>
102 trans1 LesserToken BiLesser <|>
103 trans1 BiggerToken BiGreater <|>
104 trans1 LesserEqToken BiLesserEq <|>
105 trans1 GreaterEqToken BiGreaterEq <|>
106 trans1 NotEqualToken BiUnEqual) $
107 parseOpL (trans1 PlusToken BiPlus <|>
108 trans1 DashToken BiMinus) $
109 parseOpL (trans1 StarToken BiTimes <|>
110 trans1 SlashToken BiDivide <|>
111 trans1 PercentToken BiMod) $ parseBasicExpr
112 where
113 parseOpR :: (Parser Token Op2) (Parser Token Expr) -> Parser Token Expr
114 parseOpR ops prev = prev >>= \e1->optional (
115 ops >>= \op->parseOpR ops prev >>= \e->pure (op, e)
116 ) >>= \moe->pure $ maybe e1 (\(op,e2)->Op2Expr e1 op e2) moe
117
118 parseOpL :: (Parser Token Op2) (Parser Token Expr) -> Parser Token Expr
119 parseOpL ops prev = prev >>= \e1->many (
120 ops >>= \op->prev >>= \e->pure (op, e)
121 ) >>= \moe->foldM (\e->(\(op,e2)->pure $ Op2Expr e op e2)) e1 moe
122
123 parseBasicExpr :: Parser Token Expr
124 parseBasicExpr =
125 (liftM TupleExpr (parseTuple parseExpr)) <|>
126 (liftM FunExpr parseFunCall) <|>
127 parseBBraces parseExpr <|>
128 trans1 EmptyListToken EmptyListExpr <|>
129 trans1 TrueToken (BoolExpr True) <|>
130 trans1 FalseToken (BoolExpr False) <|>
131 trans2 (NumberToken zero) (\(NumberToken i)->IntExpr i) <|>
132 trans2 (CharToken zero) (\(CharToken c)->CharExpr c) <|>
133 (liftM2 Op1Expr parseOp1 parseExpr) <|>
134 (liftM VarExpr parseVarDef)
135
136 parseFunCall :: Parser Token FunCall
137 parseFunCall = liftM2 FunCall
138 parseIdent (parseBBraces $ parseSepList CommaToken parseExpr)
139
140 parseVarDef :: Parser Token VarDef
141 parseVarDef = liftM2 VarDef
142 parseIdent
143 (many (satTok DotToken *> (
144 (parseIdent >>= (\i.if (i == "hd") (pure FieldHd) empty)) <|>
145 (parseIdent >>= \i.if (i == "tl") (pure FieldTl) empty) <|>
146 (parseIdent >>= \i.if (i == "fst") (pure FieldFst) empty) <|>
147 (parseIdent >>= \i.if (i == "snd") (pure FieldSnd) empty))))
148
149 parseOp1 :: Parser Token Op1
150 parseOp1 = trans1 DashToken UnMinus <|> trans1 ExclamationToken UnNegation
151
152 parseBBraces :: (Parser Token a) -> Parser Token a
153 parseBBraces p = satTok BraceOpenToken *> p <* satTok BraceCloseToken
154
155 parseBCBraces :: (Parser Token a) -> Parser Token a
156 parseBCBraces p = satTok CBraceOpenToken *> p <* satTok CBraceCloseToken
157
158 parseBSqBraces :: (Parser Token a) -> Parser Token a
159 parseBSqBraces p = satTok SquareOpenToken *> p <* satTok SquareCloseToken
160
161 parseTuple :: (Parser Token a) -> Parser Token (a, a)
162 parseTuple p = satTok BraceOpenToken *>
163 (liftM2 (\a->(\b->(a,b))) (p <* satTok CommaToken) p)
164 <* satTok BraceCloseToken
165
166 trans2 :: TokenValue (TokenValue -> a) -> Parser Token a
167 trans2 t f = liftM (\(_,token)->f token) $ satTok t
168
169 trans1 :: TokenValue a -> Parser Token a
170 trans1 t r = trans2 t $ const r
171
172 derive gPrint TokenValue
173 derive gEq TokenValue
174 satTok :: TokenValue -> Parser Token Token
175 satTok t = top >>= \tok=:({line,col},token) -> if (eq t token)
176 (pure tok) (fail <?> PositionalError line col
177 ("ParseError: Unexpected token: " +++ printToString token))
178 where
179 eq (IdentToken _) (IdentToken _) = True
180 eq (NumberToken _) (NumberToken _) = True
181 eq (CharToken _) (CharToken _) = True
182 eq x y = gEq {|*|} x y
183
184 parseSepList :: TokenValue (Parser Token a) -> Parser Token [a]
185 parseSepList sep p =
186 (liftM2 (\es->(\e->reverse [e:es])) (some (p <* satTok sep)) p) <|>
187 (liftM pure p) <|> pure empty
188
189 parseIdent :: Parser Token String
190 parseIdent = trans2 (IdentToken "") (\(IdentToken e).toString e)