]> git.unchartedbackwaters.co.uk Git - francis/lta.git/commitdiff
Inital work on pretty printing.
authorFrancis Russell <francis@unchartedbackwaters.co.uk>
Thu, 18 Apr 2013 10:40:17 +0000 (11:40 +0100)
committerFrancis Russell <francis@unchartedbackwaters.co.uk>
Thu, 18 Apr 2013 10:40:17 +0000 (11:40 +0100)
LTA/Common.hs [new file with mode: 0644]
LTA/Precedence.hs [new file with mode: 0644]
LTA/Symbolic.hs
lta.cabal
src/Main.hs

diff --git a/LTA/Common.hs b/LTA/Common.hs
new file mode 100644 (file)
index 0000000..e2038ba
--- /dev/null
@@ -0,0 +1,23 @@
+module LTA.Common
+  ( PrettyPrintable(..)
+  ) where
+
+import Text.PrettyPrint
+  (Doc, renderStyle, Style(..), Mode(..), double, float , integer, int)
+
+class PrettyPrintable a where
+  toDoc :: a -> Doc
+  prettyPrint :: a -> String
+  prettyPrint = renderStyle Style {mode = PageMode, lineLength=72, ribbonsPerLine=1.5 } . toDoc
+
+instance PrettyPrintable Double where
+  toDoc = double
+
+instance PrettyPrintable Float where
+  toDoc = float
+
+instance PrettyPrintable Integer where
+  toDoc = integer
+
+instance PrettyPrintable Int where
+  toDoc = int
diff --git a/LTA/Precedence.hs b/LTA/Precedence.hs
new file mode 100644 (file)
index 0000000..9d0ce27
--- /dev/null
@@ -0,0 +1,52 @@
+module LTA.Precedence
+  ( Assoc(..)
+  , PrecExpr(..)
+  , buildAtom
+  , buildFunction
+  , buildInfix
+  ) where
+
+import Control.Applicative ((<$>))
+import Text.PrettyPrint (Doc, comma, hcat, parens, punctuate, text)
+
+data Assoc
+  = AssocLeft
+  | AssocRight
+  | AssocNone
+  deriving Eq
+
+data PrecExpr
+  = PrecExpr Assoc Integer Doc
+
+precedence :: PrecExpr -> Integer
+precedence (PrecExpr _ p _) = p
+
+associativity :: PrecExpr -> Assoc
+associativity (PrecExpr a _ _) = a
+
+value :: PrecExpr -> Doc
+value (PrecExpr _ _ v) = v
+
+buildAtom :: Doc -> PrecExpr
+buildAtom = PrecExpr AssocNone 9
+
+buildFunction :: String -> [PrecExpr] -> PrecExpr
+buildFunction name params = PrecExpr AssocNone 9 call where
+  call = hcat [text name, parens flatParams]
+  flatParams = hcat . punctuate comma $ value <$> params
+
+buildInfix :: String -> Assoc -> Integer -> PrecExpr -> PrecExpr -> PrecExpr
+buildInfix name assoc prec left right = PrecExpr assoc prec val where
+  valueLeft = bracket bracketLeft $ value left
+  valueRight = bracket bracketRight $ value right
+  val = hcat [valueLeft, text " ", text name, text " ", valueRight]
+  bracketLeft =
+    prec > (precedence left) ||
+    (prec == precedence left && assoc /= associativity left)
+  bracketRight =
+    prec > (precedence right) ||
+    (prec == precedence right && assoc /= associativity right)
+
+bracket :: Bool -> Doc -> Doc
+bracket True = parens
+bracket False = id
index 80939eecce99080ae5f93d185152a4f10552528a..deecffab504417d9cb142c655917627fe05a0dbe 100644 (file)
@@ -24,6 +24,9 @@ import Data.Ratio (numerator, denominator)
 import Data.List (foldl')
 import Data.Map (Map)
 import Data.Set (Set)
+import LTA.Common (PrettyPrintable(..))
+import LTA.Precedence (PrecExpr(..), buildAtom, buildFunction, buildInfix)
+import Text.PrettyPrint (text)
 import qualified Data.Map as Map
 import qualified Data.Set as Set
 
@@ -162,6 +165,18 @@ buildConditional base ((cond, expr) : cases) =
 (~>) :: Expr -> Expr -> Cond
 (~>) = Compare GreaterThan
 
+instance PrettyPrintable Expr where
+  toDoc expr = case buildPrecedence expr of
+    (PrecExpr _ _ doc) -> doc
+    where
+    buildPrecedence e = case e of
+      IntegerSymbol s -> buildAtom $ text s
+      FloatSymbol s -> buildAtom $ text s
+      Constant c -> buildAtom . text $ show c
+      Summation var low high summand -> buildFunction "sum" params where
+        params = buildPrecedence <$> [summand, IntegerSymbol var, low, high]
+      v -> error $ "Unimplemented: " ++ show v
+
 instance ContainsSymbols Expr where
   rename from to e = case e of
     IntegerSymbol name -> if name == from
@@ -225,7 +240,7 @@ instance ContainsSymbols Cond where
     Not e -> findSymbols e
 
 findUniqueSymbol :: (ContainsSymbols e) => String -> e -> String
-findUniqueSymbol prefix expr = 
+findUniqueSymbol prefix expr =
   head [n | n <- generateNames, Set.notMember n syms ] where
     syms = findSymbols expr
     generateNames = [prefix ++ "_" ++ show n | n <- [0::Integer ..]]
index 93a4fe8115517ad7560afa37579cd4104d9d334f..972641e53a81d6dc2442567d6e15aa4ca94bd3a6 100644 (file)
--- a/lta.cabal
+++ b/lta.cabal
@@ -9,11 +9,13 @@ Cabal-Version:       >=1.8.0.2
 Library
   Hs-Source-Dirs:    .
   GHC-Options:       -Wall
-  Build-Depends:     base, containers
-  Exposed-Modules:   LTA.Symbolic
+  Build-Depends:     base, containers, pretty
+  Exposed-Modules:   LTA.Common
+                     LTA.Precedence
+                     LTA.Symbolic
 
 Executable lta
   Main-is:           Main.hs
   Hs-Source-Dirs:    src
   GHC-Options:       -Wall
-  Build-Depends:     base, lta
+  Build-Depends:     base, lta, pretty
index b39cd82ab9965bc5227ddf0912c7d149b82c437f..920082436a69687c96c69278d9308a0b1d099a85 100644 (file)
@@ -1,20 +1,27 @@
 module Main (main) where
 
 import LTA.Symbolic
+import LTA.Common
+import Text.PrettyPrint (comma, hcat, parens, punctuate, text)
 
-data Matrix 
+data Matrix
  = Matrix Expr Expr Expr
  deriving(Eq, Ord, Show)
 
+instance PrettyPrintable Matrix where
+  toDoc (Matrix rows cols expr) =
+    hcat $ [text "matrix", parens . hcat . punctuate comma $ params] where
+      params = [toDoc rows, toDoc cols, toDoc expr]
+
 multiply :: Matrix -> Matrix -> Matrix
-multiply (Matrix aRows aCols aExpr) (Matrix bRows bCols bExpr) = 
+multiply (Matrix aRows aCols aExpr) (Matrix bRows bCols bExpr) =
   Matrix aRows bCols $ Summation sumVar 0 aCols (aExpr' * bExpr') where
     sumVar = findUniqueSymbol "sum" (aExpr * bExpr)
     aExpr' = rename "col" sumVar aExpr
     bExpr' = rename "row" sumVar bExpr
 
 main :: IO()
-main = putStrLn . show $ (pad size) `multiply` (dft size) where
+main = putStrLn . prettyPrint $ (pad size) `multiply` (dft size) where
   size = IntegerSymbol "N"
 
 row :: Expr
@@ -39,7 +46,7 @@ isEven :: Expr -> Cond
 isEven n = (n `Mod` 2) ~== 0
 
 pad :: Expr -> Matrix
-pad size = 
+pad size =
   Matrix (2*size) size $ Conditional (isEven size) (evenPad size) (oddPad size)
 
 evenPad :: Expr -> Expr