uu-cco-0.1.0.0: src/CCO/Tree/ATerm.hs
-------------------------------------------------------------------------------
-- |
-- Module : CCO.Tree.ATerm
-- Copyright : (c) 2008 Utrecht University
-- License : All rights reserved
--
-- Maintainer : stefan@cs.uu.nl
-- Stability : provisional
-- Portability : portable
--
-- A straightforward implementation of the ATerm format for exchanging
-- tree-structured data; see
--
-- * Mark van den Brand, Hayco de Jong, Paul Klint, and Pieter A. Olivier.
-- Efficient annotated terms.
-- /Software - Practice and Experience (SPE)/, 30(3):259-291, 2000.
--
-------------------------------------------------------------------------------
module CCO.Tree.ATerm (
-- * The @ATerm@ type
ATerm (..) -- instances: Eq, Read, Show, Printable
, Con -- = String
) where
import CCO.Printing
import Data.List
-------------------------------------------------------------------------------
-- The ATerm type
-------------------------------------------------------------------------------
-- | Node constructors.
type Con = String
-- | Terms.
data ATerm = Integer Integer -- ^Integer literal.
| Float Double -- ^Floating-point literal.
| String String -- ^Textual literal.
| App Con [ATerm] -- ^Constructor application.
| Tuple [ATerm] -- ^Tuple of terms.
| List [ATerm] -- ^List of terms.
| Ann ATerm [ATerm] -- ^Annotated term.
deriving (Eq, Read, Show)
instance Printable ATerm where pp = ppATerm
-------------------------------------------------------------------------------
-- Pretty printing
-------------------------------------------------------------------------------
-- We distinguish between two fundamental modes for printing compound 'ATerm's
-- (i.e., 'App's, 'Tuple's, 'List's, and 'Ann's): single-line mode and
-- multi-line mode.
-- Subterms of a term printed in single-line mode are themselves required to
-- be printed in single-line mode; subterms of a term printed in multi-line
-- mode may be printed in either mode.
-- | Representation of the printing modes: a function that takes the a
-- \"preamble\", a left bracket symbol, a right bracket symbol, and a list of
-- subterms as arguments and produces a 'Doc' for the compound term that is to
-- be printed.
type Mode = Doc -> -- \"Preamble\".
Doc -> -- Left bracket.
Doc -> -- Right bracket.
[ATerm] -> -- List of subterms.
Doc -- 'Doc' for the compound term.
-- | Single-line mode.
singleLineMode :: Mode
singleLineMode = \pre l r ts ->
let docs = [ppATermIn singleLineMode t | t <- ts] `sepBy` text ", "
in pre >|< l >|< docs >|< r
-- | Multi-line mode.
multiLineMode :: Mode
multiLineMode = \pre l r ts ->
singleLineMode pre l r ts >//< case ts of
[] -> pre >|< l >-< r
t : ts' ->
let p = if isEmpty pre then l >|< text " " else pre >|< l >-< text " "
in p >|< ppATermIn multiLineMode t >-<
above [text ", " >|< ppATermIn multiLineMode t' | t' <- ts'] >-<
r
-- | Pretty prints an 'ATerm' in multi-line mode.
ppATerm :: ATerm -> Doc
ppATerm = ppATermIn multiLineMode
ppATermIn :: Mode -> ATerm -> Doc
ppATermIn _ (Integer n) = pp n
ppATermIn _ (Float r) = pp r
ppATermIn _ (String txt) = text (show txt)
ppATermIn _ (App c []) = blue (text c)
ppATermIn mode (App c ts) = mode (blue (text c)) lparen rparen ts
ppATermIn mode (Tuple ts) = mode empty lparen rparen ts
ppATermIn mode (List ts) = mode empty lbracket rbracket ts
ppATermIn mode (Ann t ts) = mode (ppATermIn mode t) lbrace rbrace ts