{-|
This module contains the main parser of blocks other than the from block.
-}
module Lsql.Csv.Lang.BlockChain (parseBlocks) where

import Text.Parsec
import Text.Parsec.Prim
import Text.Parsec.Combinator
import Text.Parsec.Text
import Text.Parsec.Char

import qualified Data.Text as T

import Lsql.Csv.Core.Symbols
import Lsql.Csv.Lang.Selector

import Lsql.Csv.Core.Functions
import Lsql.Csv.Core.BlockOps

selectBP :: [String] -> Parser Block
selectBP :: [String] -> Parser Block
selectBP [String]
symbol_list = do
  [Arg]
ret <- [String] -> Parser [Arg]
selectorP [String]
symbol_list
  Block -> Parser Block
forall a. a -> ParsecT Text () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return(Block -> Parser Block) -> Block -> Parser Block
forall a b. (a -> b) -> a -> b
$ [Arg] -> Block
Select [Arg]
ret

ifBP :: [String] -> Parser Block
ifBP :: [String] -> Parser Block
ifBP [String]
symbol_list = do
  ParsecT Text () Identity Char -> ParsecT Text () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT Text () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space
  String -> ParsecT Text () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"if"
  ParsecT Text () Identity Char -> ParsecT Text () Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 ParsecT Text () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space
  Arg
ret <- [String] -> Parser Arg
arithmeticExprP [String]
symbol_list
  ParsecT Text () Identity Char -> ParsecT Text () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT Text () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space
  Block -> Parser Block
forall a. a -> ParsecT Text () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return(Block -> Parser Block) -> Block -> Parser Block
forall a b. (a -> b) -> a -> b
$ Arg -> Block
If Arg
ret

sortBP :: [String] -> Parser Block
sortBP :: [String] -> Parser Block
sortBP [String]
symbol_list = do
  ParsecT Text () Identity Char -> ParsecT Text () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT Text () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space
  String -> ParsecT Text () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"sort"
  ParsecT Text () Identity Char -> ParsecT Text () Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 ParsecT Text () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space
  [Arg]
ret <- [String] -> Parser [Arg]
selectorP [String]
symbol_list
  ParsecT Text () Identity Char -> ParsecT Text () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT Text () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space
  Block -> Parser Block
forall a. a -> ParsecT Text () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return(Block -> Parser Block) -> Block -> Parser Block
forall a b. (a -> b) -> a -> b
$ [Arg] -> Block
Sort [Arg]
ret

byBP :: [String] -> Parser Block
byBP :: [String] -> Parser Block
byBP [String]
symbol_list = do
  ParsecT Text () Identity Char -> ParsecT Text () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT Text () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space
  String -> ParsecT Text () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"by"
  ParsecT Text () Identity Char -> ParsecT Text () Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 ParsecT Text () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space
  [Arg]
ret <- [String] -> Parser [Arg]
selectorP [String]
symbol_list
  ParsecT Text () Identity Char -> ParsecT Text () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT Text () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space
  Block -> Parser Block
forall a. a -> ParsecT Text () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return(Block -> Parser Block) -> Block -> Parser Block
forall a b. (a -> b) -> a -> b
$ [Arg] -> Block
By [Arg]
ret

blockP :: [String] -> Parser Block
blockP :: [String] -> Parser Block
blockP [String]
symbol_list = 
  (Parser Block -> Parser Block
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try(Parser Block -> Parser Block) -> Parser Block -> Parser Block
forall a b. (a -> b) -> a -> b
$ [String] -> Parser Block
sortBP [String]
symbol_list) Parser Block -> Parser Block -> Parser Block
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> 
  (Parser Block -> Parser Block
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try(Parser Block -> Parser Block) -> Parser Block -> Parser Block
forall a b. (a -> b) -> a -> b
$ [String] -> Parser Block
byBP [String]
symbol_list) Parser Block -> Parser Block -> Parser Block
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> 
  (Parser Block -> Parser Block
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try(Parser Block -> Parser Block) -> Parser Block -> Parser Block
forall a b. (a -> b) -> a -> b
$ [String] -> Parser Block
ifBP [String]
symbol_list) Parser Block -> Parser Block -> Parser Block
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> 
  ([String] -> Parser Block
selectBP [String]
symbol_list)

-- | A function for parsing blocks other than the from block.
parseBlocks :: [String] -- ^ The blocks to parse
            -> [String] -- ^ The list of all symbol names
            -> [Block] -- ^ The parsed blocks

parseBlocks :: [String] -> [String] -> [Block]
parseBlocks [] [String]
_ = []
parseBlocks (String
input : [String]
rest) [String]
symbol_list =
  case Parser Block -> String -> Text -> Either ParseError Block
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
parse ([String] -> Parser Block
blockP [String]
symbol_list) (String
"'" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
input String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" block")(Text -> Either ParseError Block)
-> Text -> Either ParseError Block
forall a b. (a -> b) -> a -> b
$ 
      String -> Text
T.pack String
input of
    Left ParseError
err -> String -> [Block]
forall a. HasCallStack => String -> a
error(String -> [Block]) -> String -> [Block]
forall a b. (a -> b) -> a -> b
$ ParseError -> String
forall a. Show a => a -> String
show ParseError
err
    Right Block
parsed -> Block
parsed Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [String] -> [String] -> [Block]
parseBlocks [String]
rest [String]
symbol_list