(Left e, _) = Left $ toString e
parseProgram :: Parser Token AST
-parseProgram = liftM2 AST (many parseVarDecl) (some parseFunDecl)
+parseProgram = liftM2 AST (many parseVarDecl) (some parseFunDecl)
+ <* satTok EndOfFileToken
parseFunDecl :: Parser Token FunDecl
parseFunDecl = liftM5 FunDecl
(parseIdent <* satTok BraceOpenToken)
(parseSepList CommaToken parseIdent <* satTok BraceCloseToken)
- (parseFunType <* satTok CBraceOpenToken)
+ (optional parseFunType <* satTok CBraceOpenToken)
(many parseVarDecl)
(many parseStmt <* satTok CBraceCloseToken)
parseIfStmt :: Parser Token Stmt
parseIfStmt = liftM3 IfStmt
- (satTok IfToken *> parseBBraces parseExpr)
- (parseBlock <|> parseOneLine)
- (liftM (fromMaybe [])
- (optional (satTok ElseToken *> (parseBlock<|> parseOneLine))))
+ (satTok IfToken *> parseBBraces parseExpr)
+ (parseBlock <|> parseOneLine)
+ (liftM (fromMaybe [])
+ (optional (satTok ElseToken *> (parseBlock<|> parseOneLine))))
+
parseWhileStmt :: Parser Token Stmt
parseWhileStmt = satTok WhileToken *>
parseOneLine = liftM pure parseStmt
parseFunType :: Parser Token FunType
-parseFunType = satTok DoubleColonToken *>
+parseFunType = satTok DoubleColonToken *>
(parseInOutType <|> (liftM (FunType []) parseVoidOrType))
where
parseInOutType :: Parser Token FunType
parseVoidOrType :: Parser Token (Maybe Type)
parseVoidOrType = (satTok VoidToken *> pure Nothing) <|>
- (liftM Just parseType)
+ (liftM Just parseType) <|> pure Nothing
parseVarDecl :: Parser Token VarDecl
parseVarDecl = liftM3 VarDecl
(parseIdent >>= \i.if (i == "snd") (pure FieldSnd) empty))))
parseOp1 :: Parser Token Op1
-parseOp1 = trans1 DashToken UnMinus <|>
- trans1 ExclamationToken UnNegation
+parseOp1 = trans1 DashToken UnMinus <|> trans1 ExclamationToken UnNegation
parseBBraces :: (Parser Token a) -> Parser Token a
parseBBraces p = satTok BraceOpenToken *> p <* satTok BraceCloseToken
<* satTok BraceCloseToken
trans2 :: TokenValue (TokenValue -> a) -> Parser Token a
-trans2 t f = satTok t >>= \(_, r).pure (f r)
+trans2 t f = liftM (f o thd3) $ satTok t
trans1 :: TokenValue a -> Parser Token a
trans1 t r = trans2 t $ const r
derive gPrint TokenValue
derive gEq TokenValue
satTok :: TokenValue -> Parser Token Token
-satTok t = top >>= \tok=:(pos, tv) -> if (eq t tok) (return tok) (fail <?> (printToString t, pos))
+satTok t = top >>= \tok=:(pos1, pos2, tv) -> if (eq t tok)
+ (return tok)
+ (fail <?> (printToString tv+++printToString t, pos1))
where
- eq (IdentToken _) (_, IdentToken _) = True
- eq (NumberToken _) (_, NumberToken _) = True
- eq (CharToken _) (_, CharToken _) = True
- eq x (_, y) = gEq {|*|} x y
+ eq (IdentToken _) (_, _, IdentToken _) = True
+ eq (NumberToken _) (_, _, NumberToken _) = True
+ eq (CharToken _) (_, _, CharToken _) = True
+ eq x (_, _, y) = gEq {|*|} x y
parseSepList :: TokenValue (Parser Token a) -> Parser Token [a]
parseSepList sep p =
- (some (p <* satTok sep) >>= \es->p >>= \e.pure $ reverse [e:es]) <|>
+ (liftM2 (\es->(\e->reverse [e:es])) (some (p <* satTok sep)) p) <|>
(liftM pure p) <|> pure empty
parseIdent :: Parser Token String
-parseIdent = trans2 (IdentToken []) (\(IdentToken e).toString e)
+parseIdent = trans2 (IdentToken "") (\(IdentToken e).toString e)
instance toString AST where
toString (AST v f) = concat (
instance print FunDecl where
print (FunDecl i as t vs ss) =
["\n", i, " (":printersperse "," as] ++
- [") :: ":print t] ++
- ["{":printersperse "\n\t" vs] ++
- ["\n":printStatements ss 1] ++ ["}"]
+ [")"] ++ maybe [] (\tt->[" :: ":print tt]) t ++
+ ["{\n\t":printersperse "\n\t" vs] ++
+ ["\n":printStatements ss 1] ++ ["}\n"]
printStatements :: [Stmt] Int -> [String]
printStatements [] i = []
) ++ printStatements ss i
where
printCodeBlock :: [Stmt] Int -> [String]
- printCodeBlock [] _ = ["{}"]
+ printCodeBlock [] _ = ["{}\n"]
printCodeBlock [x] i = ["\n":printStatements [x] (i+1)]
printCodeBlock x i =
["{\n":printStatements x (i+1)] ++ indent i ["}\n"]