implementation module parse import StdString import StdTuple import StdList from StdFunc import const import Data.Either import Control.Monad import Control.Applicative import Data.Func import yard import lex parse :: LexerOutput -> ParserOutput parse (Left e) = Left $ toString $ LexError e parse (Right r) = case runParser parseProgram r of (Right p, _) = Right p (Left e, _) = Left $ toString e parseProgram :: Parser Token AST parseProgram = parseVar >>= \t.pure $ AST [t] [] parseVar :: Parser Token VarDecl parseVar = parseType >>= \t->parseIdent <* satTok AssignmentToken >>= \i->parseExpr <* satTok SColonToken >>= \e->pure $ VarDecl i t e parseType :: Parser Token Type parseType = trans1 IntTypeToken IntType <|> trans1 VarToken VarType <|> trans1 CharTypeToken CharType <|> trans1 BoolTypeToken BoolType <|> (satTok SquareOpenToken *> parseType <* satTok SquareCloseToken >>= \t.pure $ ListType t) <|> (satTok BraceOpenToken *> parseType <* satTok CommaToken >>= \t1->parseType <* satTok BraceCloseToken >>= \t2->pure $ TupleType t1 t2) <|> (parseIdent >>= \e.pure $ IdType e) <|> empty parseExpr :: Parser Token Expr parseExpr = (satTok BraceOpenToken *> parseExpr <* satTok BraceCloseToken) <|> (satTok BraceOpenToken *> parseExpr <* satTok CommaToken >>= \e1->parseExpr <* satTok BraceCloseToken >>= \e2->pure $ TupleExpr e1 e2) <|> trans1 EmptyListToken EmptyListExpr <|> trans2 TrueToken (const $ BoolExpr True) <|> trans2 FalseToken (const $ BoolExpr True) <|> trans2 (NumberToken zero) (\(NumberToken i)->IntExpr i) <|> trans2 (CharToken zero) (\(CharToken c)->CharExpr c) <|> (parseOp1 >>= \o->parseExpr >>= \e.pure $ Op1Expr o e) <|> (parseIdent >>= \i. parseFieldSelector >>= \f.pure $ VarExpr i f) parseOp1 :: Parser Token Op1 parseOp1 = trans1 DashToken UnMinus <|> trans1 ExclamationToken UnNegation parseOp2 :: Parser Token Op2 parseOp2 = trans1 StarToken BiTimes <|> trans1 SlashToken BiDivide <|> trans1 PercentToken BiMod <|> trans1 EqualsToken BiEquals <|> trans1 LesserToken BiLesser <|> trans1 BiggerToken BiGreater <|> trans1 LesserEqToken BiLesserEq <|> trans1 PlusToken BiPlus <|> trans1 GreaterEqToken BiGreaterEq <|> trans1 DashToken BiMinus <|> trans1 NotEqualToken BiUnEqual <|> trans1 AmpersandsToken BiAnd <|> trans1 PipesToken BiOr <|> trans1 ColonToken BiCons parseFieldSelector :: Parser Token (Maybe FieldSelector) parseFieldSelector = optional (satTok DotToken *> ( (parseIdent >>= (\i.if (i == "hd") (pure FieldHd) empty)) <|> (parseIdent >>= \i.if (i == "tl") (pure FieldTl) empty) <|> (parseIdent >>= \i.if (i == "fst") (pure FieldFst) empty) <|> (parseIdent >>= \i.if (i == "snd") (pure FieldSnd) empty))) trans2 :: TokenValue (TokenValue -> a) -> Parser Token a trans2 t f = satTok t >>= \(_, r).pure (f r) trans1 :: TokenValue a -> Parser Token a trans1 t r = trans2 t $ const r satTok :: TokenValue -> Parser Token Token satTok t = satisfy ((===) t) parseIdent :: Parser Token String parseIdent = trans2 (IdentToken []) (\(IdentToken e).toString e)