import Control.Applicative
import Control.Monad
-import Control.Monad.State
-import Control.Monad.Trans
import Data.Either
import Data.GenEq
import Data.Functor
(<:>) infixl 0 :: a (m [a]) -> m [a] | Functor m
(<:>) l r = cons l <$> r
-:: Token = TTSemiColon | TTBrackOpen | TTBrackClose | TTBool Bool | TTInt Int
- | TTOp [Char] | TTIdent [Char]
+:: Token = TTSemiColon | TTBrackOpen | TTBrackClose | TTBool Bool | TTInt Int | TTOp [Char] | TTIdent [Char]
derive gEq Token
derive gPrint Token
where
isOp c = isMember c ['!@#$%^&*=+/?-_|\\\'",<>.:']
-:: Parser a :== StateT ParseState (Either [String]) a
-:: ParseState =
- { tokens :: [Token]
- , ifxs :: [((Parser Expression) -> Parser Expression, Int)]
- }
+:: Parser a = Parser ([Token] IfxInfo -> (Either [String] a, [Token], IfxInfo))
+:: IfxInfo :== [((Parser Expression) -> Parser Expression, Int)]
+runParser (Parser a) = a
+instance Functor Parser where fmap f a = liftM f a
+instance pure Parser where pure a = Parser \ts r->(Right a, ts, r)
+instance <*> Parser where (<*>) a b = ap a b
+instance <* Parser
+instance *> Parser
+instance Monad Parser where
+ bind ma a2mb = Parser \t r->case runParser ma t r of
+ (Left e, ts, r) = (Left e, ts, r)
+ (Right a, ts, r) = runParser (a2mb a) ts r
+instance Alternative Parser where
+ empty = Parser \ts r->(Left [], ts, r)
+ (<|>) p1 p2 = Parser \ts r->case runParser p1 ts r of
+ (Left e, _, _) = runParser p2 ts r
+ a = a
pTop :: Parser Token
-pTop = getState >>= \s->case s.tokens of
- [t:ts] = put {s & tokens=ts} >>| pure t
- [] = liftT (Left ["Fully consumed input"])
+pTop = Parser \ts r->case ts of
+ [t:ts] = (Right t, ts, r)
+ [] = (Left ["Fully consumed input"], ts, r)
pEof :: Parser ()
-pEof = getState >>= \s->case s.tokens of
- [] = pure ()
- [t:ts] = liftT (Left ["Expected EOF but got ":map toString [t:ts]])
+pEof = Parser \ts r->case ts of
+ [] = (Right (), [], r)
+ _ = (Left ["Expected EOF but got ":map toString ts], ts, r)
(?) infixl 9 :: (Parser a) (a -> Bool) -> Parser a
(?) p f = p >>= \v->if (f v) (pure v) empty
pChainr op p = flip ($) <$> p <*> (flip <$> op <*> pChainr op p) <|> p
parse :: [Token] -> Either [String] [Either TypeDef Function]
-parse ts = fst <$> runStateT (reverse <$> pAST <* pEof) {tokens=ts, ifxs=[]}
+parse ts = case runParser (many (Right <$> pFunction <|> Left <$> pTypeDef) <* pEof) ts [] of
+ (Left e, _, _) = Left e
+ (Right a, _, r) = sequence [reparse r a\\a<-a]
where
- pAST :: Parser [Either TypeDef Function]
- pAST = many (Right <$> pFunction <|> Left <$> pTypeDef)
- >>= mapM (either (pure o Left) \(id, args, body)->Right o
- Function id args <$ modify (\t->{t & tokens=body}) <*> pExpression <* pEof)
+ reparse r (Left e) = pure (Left e)
+ reparse r (Right (id, args, body))
+ = Right <$> fst3 (runParser (Function id args <$> pExpression <* pEof) body r)
pTypeDef :: Parser TypeDef
pTypeDef = TypeDef
= TInt <$ pTop ? (\t->t=:(TTIdent ['Int']))
<|> TBool <$ pTop ? (\t->t=:(TTIdent ['Bool']))
<|> TVar <$> pId
-// <|>
+ <|> pBrack pType
pId = (\(TTIdent i)->i) <$> pTop ? (\t->t=:(TTIdent _))
pOp = (\(TTOp i)->i) <$> pTop ? (\t->t=:(TTOp _))
pFunId = pOp
>>= \i->pChainr <$ pId ? ((==) ['ifxr']) <|> pChainl <$ pId ? ((==)['ifxl'])
>>= \p->pInt
- >>= \s->modify (\t->{t & ifxs=[(p (App o App (Var i) <$ pOp ? ((==)i)), s):t.ifxs]})
- >>| pure i
+ >>= \s->addIfx i (p (App o App (Var i) <$ pOp ? ((==)i)), s)
+
+ addIfx a i = Parser \ts r->(Right a, ts, [i:r])
+ getIfx = Parser \ts r->(Right r, ts, r)
pExpression :: Parser Expression
- pExpression = getState >>= \{ifxs}->flip (foldr ($))
+ pExpression = getIfx >>= \ifxs->flip (foldr ($))
(map fst $ sortBy (on (<) snd) ifxs)
$ pChainl (pure App)
$ Lambda <$ pToken (TTOp ['\\']) <*> pId <* pToken (TTOp ['.']) <*> pExpression