{- |
    Module      :  $Header$
    Description :  Parser for conditional compiling
    Copyright   :  (c) 2017        Kai-Oliver Prott
                       2017        Finn Teegen
    License     :  BSD-3-clause

    Maintainer  :  fte@informatik.uni-kiel.de
    Stability   :  experimental
    Portability :  portable

    TODO
-}
{-# LANGUAGE CPP #-}
module Curry.CondCompile.Parser where

#if __GLASGOW_HASKELL__ < 710
import Control.Applicative ((<$>), (<*>), (*>), (<*))
#endif

import Text.Parsec

import Curry.CondCompile.Type

type Parser a = Parsec String () a

program :: Parser Program
program :: Parser Program
program = Parser Stmt
statement Parser Stmt -> ParsecT String () Identity () -> Parser Program
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
`sepBy` ParsecT String () Identity ()
eol Parser Program -> ParsecT String () Identity () -> Parser Program
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof

statement :: Parser Stmt
statement :: Parser Stmt
statement =  String
-> Parser Cond
-> (Cond -> Program -> [Elif] -> Else -> Stmt)
-> Parser Stmt
forall a.
String
-> Parser a
-> (a -> Program -> [Elif] -> Else -> Stmt)
-> Parser Stmt
ifElse "if" Parser Cond
condition Cond -> Program -> [Elif] -> Else -> Stmt
If
         Parser Stmt -> Parser Stmt -> Parser Stmt
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String
-> Parser String
-> (String -> Program -> [Elif] -> Else -> Stmt)
-> Parser Stmt
forall a.
String
-> Parser a
-> (a -> Program -> [Elif] -> Else -> Stmt)
-> Parser Stmt
ifElse "ifdef" Parser String
identifier String -> Program -> [Elif] -> Else -> Stmt
IfDef
         Parser Stmt -> Parser Stmt -> Parser Stmt
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String
-> Parser String
-> (String -> Program -> [Elif] -> Else -> Stmt)
-> Parser Stmt
forall a.
String
-> Parser a
-> (a -> Program -> [Elif] -> Else -> Stmt)
-> Parser Stmt
ifElse "ifndef" Parser String
identifier String -> Program -> [Elif] -> Else -> Stmt
IfNDef
         Parser Stmt -> Parser Stmt -> Parser Stmt
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Parser Stmt
define
         Parser Stmt -> Parser Stmt -> Parser Stmt
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Parser Stmt
undef
         Parser Stmt -> Parser Stmt -> Parser Stmt
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Parser Stmt
line

ifElse :: String -> Parser a -> (a -> [Stmt] -> [Elif] -> Else -> Stmt)
       -> Parser Stmt
ifElse :: String
-> Parser a
-> (a -> Program -> [Elif] -> Else -> Stmt)
-> Parser Stmt
ifElse k :: String
k p :: Parser a
p c :: a -> Program -> [Elif] -> Else -> Stmt
c = a -> Program -> [Elif] -> Else -> Stmt
c (a -> Program -> [Elif] -> Else -> Stmt)
-> Parser a
-> ParsecT String () Identity (Program -> [Elif] -> Else -> Stmt)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> String -> Parser String
keyword String
k Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String () Identity Char -> Parser String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String () Identity Char
sp) Parser String -> Parser a -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser a
p Parser a -> Parser String -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp Parser a -> ParsecT String () Identity () -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity ()
eol)
                 ParsecT String () Identity (Program -> [Elif] -> Else -> Stmt)
-> Parser Program
-> ParsecT String () Identity ([Elif] -> Else -> Stmt)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Stmt -> Parser Program
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (Parser Stmt
statement Parser Stmt -> ParsecT String () Identity () -> Parser Stmt
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity ()
eol)
                 ParsecT String () Identity ([Elif] -> Else -> Stmt)
-> ParsecT String () Identity [Elif]
-> ParsecT String () Identity (Else -> Stmt)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String () Identity Elif
-> ParsecT String () Identity [Elif]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ((Cond, Program) -> Elif
Elif ((Cond, Program) -> Elif)
-> ParsecT String () Identity (Cond, Program)
-> ParsecT String () Identity Elif
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((,) (Cond -> Program -> (Cond, Program))
-> Parser Cond
-> ParsecT String () Identity (Program -> (Cond, Program))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> String -> Parser String
keyword "elif" Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String () Identity Char -> Parser String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String () Identity Char
sp) Parser String -> Parser Cond -> Parser Cond
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Cond
condition Parser Cond -> Parser String -> Parser Cond
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp Parser Cond -> ParsecT String () Identity () -> Parser Cond
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity ()
eol)
                                         ParsecT String () Identity (Program -> (Cond, Program))
-> Parser Program -> ParsecT String () Identity (Cond, Program)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Stmt -> Parser Program
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (Parser Stmt
statement Parser Stmt -> ParsecT String () Identity () -> Parser Stmt
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity ()
eol)))
                 ParsecT String () Identity (Else -> Stmt)
-> ParsecT String () Identity Else -> Parser Stmt
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Maybe Program -> Else
Else (Maybe Program -> Else)
-> ParsecT String () Identity (Maybe Program)
-> ParsecT String () Identity Else
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Program -> ParsecT String () Identity (Maybe Program)
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe
                                 (Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> String -> Parser String
keyword "else" Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp) Parser String
-> ParsecT String () Identity () -> ParsecT String () Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String () Identity ()
eol ParsecT String () Identity () -> Parser Program -> Parser Program
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Stmt -> Parser Program
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (Parser Stmt
statement Parser Stmt -> ParsecT String () Identity () -> Parser Stmt
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity ()
eol)))
                 Parser Stmt -> Parser String -> Parser Stmt
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*  Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* String -> Parser String
keyword "endif" Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp)

define :: Parser Stmt
define :: Parser Stmt
define = String -> Int -> Stmt
Define (String -> Int -> Stmt)
-> Parser String -> ParsecT String () Identity (Int -> Stmt)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> String -> Parser String
keyword "define" Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String () Identity Char -> Parser String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String () Identity Char
sp) Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser String
identifier Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity Char -> Parser String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String () Identity Char
sp)
                ParsecT String () Identity (Int -> Stmt)
-> ParsecT String () Identity Int -> Parser Stmt
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String () Identity Int
value Parser Stmt -> Parser String -> Parser Stmt
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp

undef :: Parser Stmt
undef :: Parser Stmt
undef = String -> Stmt
Undef (String -> Stmt) -> Parser String -> Parser Stmt
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> String -> Parser String
keyword "undef" Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String () Identity Char -> Parser String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String () Identity Char
sp) Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser String
identifier Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp)

line :: Parser Stmt
line :: Parser Stmt
line = do
  String
sps <- ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp
  Parser Stmt -> Parser Stmt
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Parser Stmt -> Parser Stmt) -> Parser Stmt -> Parser Stmt
forall a b. (a -> b) -> a -> b
$  ((Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '#' ParsecT String () Identity Char
-> String -> ParsecT String () Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "") ParsecT String () Identity Char -> Parser Stmt -> Parser Stmt
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> String -> Parser Stmt
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "unknown directive")
     Parser Stmt -> Parser Stmt -> Parser Stmt
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ((String -> Stmt
Line (String -> Stmt) -> (String -> String) -> String -> Stmt
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
sps String -> String -> String
forall a. [a] -> [a] -> [a]
++)) (String -> Stmt) -> Parser String -> Parser Stmt
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String () Identity Char
-> ParsecT String () Identity () -> Parser String
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
manyTill ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar (ParsecT String () Identity () -> ParsecT String () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () Identity () -> ParsecT String () Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String () Identity ()
eol ParsecT String () Identity ()
-> ParsecT String () Identity () -> ParsecT String () Identity ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String () Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof))))

keyword :: String -> Parser String
keyword :: String -> Parser String
keyword = String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string (String -> Parser String)
-> (String -> String) -> String -> Parser String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ('#' Char -> String -> String
forall a. a -> [a] -> [a]
:)

condition :: Parser Cond
condition :: Parser Cond
condition =  (String -> Cond
Defined  (String -> Cond) -> Parser String -> Parser Cond
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string  "defined(") Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser String
identifier Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp Parser String -> ParsecT String () Identity Char -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char ')'))
         Parser Cond -> Parser Cond -> Parser Cond
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (String -> Cond
NDefined (String -> Cond) -> Parser String -> Parser Cond
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string "!defined(") Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser String
identifier Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp Parser String -> ParsecT String () Identity Char -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char ')'))
         Parser Cond -> Parser Cond -> Parser Cond
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (String -> Op -> Int -> Cond
Comp (String -> Op -> Int -> Cond)
-> Parser String -> ParsecT String () Identity (Op -> Int -> Cond)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser String
identifier Parser String -> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp) ParsecT String () Identity (Op -> Int -> Cond)
-> ParsecT String () Identity Op
-> ParsecT String () Identity (Int -> Cond)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String () Identity Op
operator ParsecT String () Identity (Int -> Cond)
-> ParsecT String () Identity Int -> Parser Cond
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String () Identity Char
sp Parser String
-> ParsecT String () Identity Int -> ParsecT String () Identity Int
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String () Identity Int
value) Parser Cond -> String -> Parser Cond
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "condition")

identifier :: Parser String
identifier :: Parser String
identifier = (:) (Char -> String -> String)
-> ParsecT String () Identity Char
-> ParsecT String () Identity (String -> String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String () Identity Char
forall u. ParsecT String u Identity Char
firstChar ParsecT String () Identity (String -> String)
-> Parser String -> Parser String
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT String () Identity Char
forall u. ParsecT String u Identity Char
firstChar ParsecT String () Identity Char
-> ParsecT String () Identity Char
-> ParsecT String () Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit) Parser String -> String -> Parser String
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "identifier"
  where firstChar :: ParsecT String u Identity Char
firstChar = ParsecT String u Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter ParsecT String u Identity Char
-> ParsecT String u Identity Char -> ParsecT String u Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '_'

operator :: Parser Op
operator :: ParsecT String () Identity Op
operator = [ParsecT String () Identity Op] -> ParsecT String () Identity Op
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ Op
Leq Op -> Parser String -> ParsecT String () Identity Op
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string "<=")
                  , Op
Lt  Op -> Parser String -> ParsecT String () Identity Op
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string "<")
                  , Op
Geq Op -> Parser String -> ParsecT String () Identity Op
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string ">=")
                  , Op
Gt  Op -> Parser String -> ParsecT String () Identity Op
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string ">")
                  , Op
Neq Op -> Parser String -> ParsecT String () Identity Op
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string "!=")
                  , Op
Eq  Op -> Parser String -> ParsecT String () Identity Op
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string "=="
                  ] ParsecT String () Identity Op
-> String -> ParsecT String () Identity Op
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "operator"

value :: Parser Int
value :: ParsecT String () Identity Int
value = (String -> Int) -> Parser String -> ParsecT String () Identity Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Int
forall a. Read a => String -> a
read (ParsecT String () Identity Char -> Parser String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit)

eol :: Parser ()
eol :: ParsecT String () Identity ()
eol = ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
endOfLine ParsecT String () Identity Char
-> ParsecT String () Identity () -> ParsecT String () Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> () -> ParsecT String () Identity ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

sp :: Parser Char
sp :: ParsecT String () Identity Char
sp = ParsecT String () Identity Char -> ParsecT String () Identity Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () Identity Char
 -> ParsecT String () Identity Char)
-> ParsecT String () Identity Char
-> ParsecT String () Identity Char
forall a b. (a -> b) -> a -> b
$  ParsecT String () Identity Char -> ParsecT String () Identity Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String () Identity ()
eol ParsecT String () Identity ()
-> ParsecT String () Identity Char
-> ParsecT String () Identity Char
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> String -> ParsecT String () Identity Char
forall s (m :: * -> *) t u a.
Stream s m t =>
String -> ParsecT s u m a
unexpected "end of line" ParsecT String () Identity Char
-> String -> ParsecT String () Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "")
        ParsecT String () Identity Char
-> ParsecT String () Identity Char
-> ParsecT String () Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space