uu-cco-examples-0.1.0.1: src/CCO/ArithBool/AG/Printing.ag
imports
{
import CCO.Printing
}
-------------------------------------------------------------------------------
-- Pretty printing
-------------------------------------------------------------------------------
attr Tm Tm_
syn pp :: Doc
sem Tm_
| Num lhs.pp = showable @n
| False_ lhs.pp = text "false"
| True_ lhs.pp = text "true"
sem Tm_
| If lhs.pp = ppIf @t1.pp @t2.pp @t3.pp
{
-- | Pretty prints a conditional.
ppIf :: Doc -> Doc -> Doc -> Doc
ppIf guard then_ else_ = singleLine >//< multiLine >//< indented
where
singleLine = ppIf_ >#< guard >#<
ppThen >#< then_ >#<
ppElse >#< else_ >#<
ppFi
multiLine = ppIf_ >|< text " " >|< guard >-<
ppThen >#< then_ >-<
ppElse >#< else_ >-<
ppFi
indented = ppIf_ >-< indent 2 guard >-<
ppThen >-< indent 2 then_ >-<
ppElse >-< indent 2 else_ >-<
ppFi
ppIf_ = text "if"
ppThen = text "then"
ppElse = text "else"
ppFi = text "fi"
}
sem Tm_
| Add lhs.pp = ppInfix @lhs.prec ("+" , 6) @t1.pp @t2.pp
| Sub lhs.pp = ppInfix @lhs.prec ("-" , 6) @t1.pp @t2.pp
| Mul lhs.pp = ppInfix @lhs.prec ("*" , 7) @t1.pp @t2.pp
| Div lhs.pp = ppInfix @lhs.prec ("/" , 7) @t1.pp @t2.pp
| Lt lhs.pp = ppInfix @lhs.prec ("<" , 4) @t1.pp @t2.pp
| Eq lhs.pp = ppInfix @lhs.prec ("==", 4) @t1.pp @t2.pp
| Gt lhs.pp = ppInfix @lhs.prec (">" , 4) @t1.pp @t2.pp
-------------------------------------------------------------------------------
-- Precedence levels
-------------------------------------------------------------------------------
{
-- | Type of precedence levels.
type Prec = Int
}
attr Tm Tm_
inh prec :: Int
sem Tm_
| If t1.prec = 0
t2.prec = 0
t3.prec = 0
| Add Sub t1.prec = 6
t2.prec = 7
| Mul Div t1.prec = 7
t2.prec = 8
| Lt Eq Gt t1.prec = 4
t2.prec = 4
{
-- | Pretty prints, given the precedence level of its immediate context, a term
-- constructed from a binary operator of a specified precedence level.
--
-- A term is enclosed in parentheses if the precedence level of its operator
-- is less than the precedence level of the enclosing context.
ppInfix :: Prec -> (String, Prec) -> Doc -> Doc -> Doc
ppInfix ctx (op, prec) l r = modifier $ l >#< ppOp >#< r
where
modifier = if prec < ctx then parens else id
ppOp = text op
}