packages feed

cpsa-2.0.0: src/CPSA/Lib/Printer.hs

-- A CPSA specific pretty printer

-- Copyright (c) 2009 The MITRE Corporation
--
-- This program is free software: you can redistribute it and/or
-- modify it under the terms of the BSD License as published by the
-- University of California.

module CPSA.Lib.Printer (pp) where

import CPSA.Lib.Pretty
import CPSA.Lib.SExpr

-- Pretty printer within specified margin.
pp :: Int -> Int -> SExpr a -> String
pp margin indent sexpr =
    pr margin (pretty indent sexpr) ""

type Printer a = Int -> SExpr a -> Pretty

-- A pretty printer that indents a constant amount for each list.  The
-- top-level lists are laid out specially.  Whenever some breaks
-- occur, all breaks are forced.  Also, breaks are only placed before
-- strings and lists.  CPSA protocols are handled specially.  Each
-- defrole is handled as are top-level lists.
pretty :: Printer a
pretty indent (L _ (x@(S _ "defprotocol") : xs)) =
    loop [block indent x, str "("] xs
    where
      loop es [] = grp indent (reverse (str ")" : es))
      loop es (x@(S _ _):xs) = loop (block indent x : str " " : es) xs
      loop es (x@(Q _ _):xs) = loop (block indent x : brk 1 : es) xs
      loop es (x@(N _ _):xs) = loop (block indent x : str " " : es) xs
      loop es (x@(L _ (S _ "defrole": _)):xs) =
          loop (group indent x : brk 1 : es) xs
      loop es (x@(L _ _):xs) = loop (block indent x : brk 1 : es) xs
pretty indent x = group indent x

group :: Printer a
group indent (L _ (x:xs)) =
    loop [block indent x, str "("] xs
    where
      loop es [] = grp indent (reverse (str ")" : es))
      loop es (x@(S _ _):xs) = loop (block indent x : str " " : es) xs
      loop es (x@(Q _ _):xs) = loop (block indent x : brk 1 : es) xs
      loop es (x@(N _ _):xs) = loop (block indent x : str " " : es) xs
      loop es (x@(L _ _):xs) = loop (block indent x : brk 1 : es) xs
group indent x = block indent x

-- A pretty printer for interior lists using block style breaking.
block :: Printer a
block _ (S _ s) = str s
block _ (Q _ s) = str (showQuoted s "")
block _ (N _ n) = str (show n)
block _ (L _ []) = str "()"
block indent (L _ (x:xs)) =
    loop [block indent x, str "("] xs
    where
      loop es [] = blo indent (reverse (str ")" : es))
      loop es (x:xs) = loop (block indent x : brk 1 : es) xs