+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)