-- -*- Mode: Haskell; -*- -- -- Here we describe how to build textual representation of syntax trees and -- principles. -- -- Copyright © 2014, 2015 Mark Karpov -- -- MIDA is free software: you can redistribute it and/or modify it under the -- terms of the GNU General Public License as published by the Free Software -- Foundation, either version 3 of the License, or (at your option) any -- later version. -- -- MIDA is distributed in the hope that it will be useful, but WITHOUT ANY -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -- details. -- -- You should have received a copy of the GNU General Public License along -- with this program. If not, see . module Mida.Representation.Show ( showStatement , showDefinition , showSyntaxTree , showPrinciple ) where import Control.Arrow ((***), (>>>)) import Data.List (intersperse) import Data.Monoid ((<>)) import qualified Data.Text.Lazy as T import qualified Data.Text.Lazy.Builder as T (Builder, fromString, toLazyText) import qualified Data.Text.Lazy.Builder.Int as T (decimal) import Mida.Language.Element import Mida.Language.SyntaxTree import Mida.Representation.Parser (Statement (..)) import qualified Mida.Representation.Base as B showStatement :: Statement -> T.Text showStatement (Definition n t) = showDefinition n t showStatement (Exposition t) = showSyntaxTree t showDefinition :: String -> SyntaxTree -> T.Text showDefinition n = T.toLazyText . showDefinition' n showSyntaxTree :: SyntaxTree -> T.Text showSyntaxTree = T.toLazyText . showSyntaxTree' showPrinciple :: Principle -> T.Text showPrinciple = showSyntaxTree . toSyntaxTree showDefinition' :: String -> SyntaxTree -> T.Builder showDefinition' n t = T.fromString n <> pad B.defOp <> showSyntaxTree' t showSyntaxTree' :: SyntaxTree -> T.Builder showSyntaxTree' t = cm f t <> "\n" where cm g xs = mconcat . intersperse " " $ g <$> xs p x@(Value _) = f x p x@(Section _) = f x p x@(Multi _) = f x p x@(CMulti _) = f x p x@(Reference _) = f x p x@(Range _ _) = f x p x = "(" <> f x <> ")" f (Value x) = T.decimal x f (Section x) = "[" <> cm f x <> "]" f (Multi x) = "{" <> cm f x <> "}" f (CMulti x) = "{" <> cm (c *** cm f >>> uncurry (<>)) x <> "}" f (Reference x) = T.fromString x f (Range x y) = T.decimal x <> T.fromString B.rangeOp <> T.decimal y f (Product x y) = f x <> pad B.productOp <> p y f (Division x y) = f x <> pad B.divisionOp <> p y f (Sum x y) = f x <> pad B.sumOp <> p y f (Diff x y) = f x <> pad B.diffOp <> p y f (Loop x y) = f x <> pad B.loopOp <> p y f (Rotation x y) = f x <> pad B.rotationOp <> p y f (Reverse x) = T.fromString B.reverseOp <> p x c xs = "<" <> cm f xs <> "> " toSyntaxTree :: Principle -> SyntaxTree toSyntaxTree = (f <$>) where f (Val x) = Value x f (Sec x) = Section $ f <$> x f (Mul x) = Multi $ f <$> x f (CMul x) = CMulti $ (toSyntaxTree *** toSyntaxTree) <$> x pad :: String -> T.Builder pad op = " " <> T.fromString op <> " "