module Internal.Quasi.Matrix.Parser where

import Internal.Quasi.Parser
import Language.Haskell.TH.Syntax

matrix :: Parser [[Exp]]
matrix :: Parser [[Exp]]
matrix = (Parser [Exp]
line Parser [Exp] -> ParsecT String () Identity Char -> Parser [[Exp]]
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` Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char ';') Parser [[Exp]] -> ParsecT String () Identity () -> Parser [[Exp]]
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

vector :: Parser [[Exp]]
vector :: Parser [[Exp]]
vector = (Exp -> [Exp]) -> [Exp] -> [[Exp]]
forall a b. (a -> b) -> [a] -> [b]
map Exp -> [Exp]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Exp] -> [[Exp]]) -> Parser [Exp] -> Parser [[Exp]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser [Exp]
line Parser [Exp] -> ParsecT String () Identity () -> Parser [Exp]
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)

line :: Parser [Exp]
line :: Parser [Exp]
line = ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces ParsecT String () Identity () -> Parser [Exp] -> Parser [Exp]
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser Exp
unit Parser Exp -> ParsecT String () Identity () -> Parser [Exp]
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]
`endBy1` ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces

unit :: Parser Exp
unit :: Parser Exp
unit = (Parser String
var Parser String -> Parser String -> Parser String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Parser String
num Parser String -> Parser String -> Parser String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Parser String
inBrackets) Parser String -> (String -> Parser Exp) -> Parser Exp
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Parser Exp
expr

num :: Parser String
num :: Parser String
num = do
  String
neg <- (Char -> Parser String
char' '-') Parser String -> Parser String -> Parser String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> Parser String
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
  String
beforeDot <- ((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 u. ParsecT String u Identity Char
outer Parser String -> Parser String -> Parser String
forall a. Semigroup a => a -> a -> 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
forall u. ParsecT String u Identity Char
inner) Parser String -> Parser String -> Parser String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> Parser String
char' '0')
  String
afterDot <- Char -> Parser String
char' '.' Parser String -> Parser String -> Parser String
forall a. Semigroup a => a -> a -> 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
forall u. ParsecT String u Identity Char
inner Parser String -> Parser String -> Parser String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Parser String
forall a. Monoid a => a
mempty
  String -> Parser String
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Parser String) -> String -> Parser String
forall a b. (a -> b) -> a -> b
$ String
neg String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
beforeDot String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
afterDot
  where
    outer :: ParsecT String u Identity Char
outer = String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf ['1' .. '9']
    inner :: ParsecT String u Identity Char
inner = Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '0' 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
<|> ParsecT String u Identity Char
forall u. ParsecT String u Identity Char
outer

inBrackets :: Parser String
inBrackets :: Parser String
inBrackets = Char -> Char -> Parser String
nested '(' ')'

nested :: Char -> Char -> Parser String
nested :: Char -> Char -> Parser String
nested open :: Char
open close :: Char
close = Char -> Parser String
char' Char
open Parser String -> Parser String -> Parser String
forall a. Semigroup a => a -> a -> a
<> Integer -> Parser String
scan 1
  where
    scan :: Integer -> Parser String
scan 0 = String -> Parser String
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
forall a. Monoid a => a
mempty
    scan n :: Integer
n = ParsecT String () Identity Char -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (String -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf [Char
open, Char
close]) Parser String -> Parser String -> Parser String
forall a. Semigroup a => a -> a -> a
<> (Char -> Parser String
char' Char
open Parser String -> Parser String -> Parser String
forall a. Semigroup a => a -> a -> a
<> Integer -> Parser String
inc Integer
n Parser String -> Parser String -> Parser String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> Parser String
char' Char
close Parser String -> Parser String -> Parser String
forall a. Semigroup a => a -> a -> a
<> Integer -> Parser String
dec Integer
n)
    inc :: Integer -> Parser String
inc = Integer -> Parser String
scan (Integer -> Parser String)
-> (Integer -> Integer) -> Integer -> Parser String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ 1)
    dec :: Integer -> Parser String
dec = Integer -> Parser String
scan (Integer -> Parser String)
-> (Integer -> Integer) -> Integer -> Parser String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\n :: Integer
n -> Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- 1)