hlShowPNExpr :: PNExpr -> ShowS
    hlShowPNExpr expr = body expr
        where
            body (PNLiteral NoSimValue) = showString "dot"
            body (PNLiteral (SimValue int [])) = shows int
            body (PNBool True) = showString "tt"
            body (PNBool False) = showString "ff"
            body (PNInput inp) = showChar 'i' . shows inp
            body (PNBitfield slice expr) = hlBitfield slice (subExpr expr)
            body (PNInsertBitfield slice expr1 expr2) = foldl1' (hlInfixOp "+") $ catMaybes [
                if offset == 0 then Nothing else Just $ hlBitfield (0 +: offset) shows1,
                Just $ hlInfixOp "-" shows1 $ hlInfixOp "%" shows1 $ showsBit $ sliceHigh slice + 1,
                Just $ hlShl shows2 offset ]
                where
                    shows1 = subExpr expr1
                    shows2 = subExpr expr2
                    offset = sliceOffset slice
            body (PNAppend widths exprs) = hlAppend widths $ map subExpr exprs
            body (PNMatch slice imps expr) = hlImpsMatch (sliceWidth slice) imps $ hlBitfield slice $ subExpr expr
            body (PNOp terms expr) = hlShowOTerms terms expr
            body expr = error $ "body: can't show PNExpr `" ++ show expr ++ "'"

            subExpr expr = hlShowPNExpr expr
hlShowPNExpr :: PNExpr -> ShowS
hlShowPNExpr expr = body expr
        where
            body (PNLiteral NoSimValue) = showString "dot"
            body (PNLiteral (SimValue int [])) = shows int
            body (PNBool True) = showString "tt"
            body (PNBool False) = showString "ff"
            body (PNInput inp) = showChar 'i' . shows inp
            body (PNBitfield slice expr) = hlBitfield slice (subExpr expr)
            body (PNInsertBitfield slice expr1 expr2) = foldl1' (hlInfixOp "+") $ catMaybes [
                if offset == 0 then Nothing else Just $ hlBitfield (0 +: offset) shows1,
                Just $ hlInfixOp "-" shows1 $ hlInfixOp "%" shows1 $ showsBit $ sliceHigh slice + 1,
                Just $ hlShl shows2 offset ]
                where
                    shows1 = subExpr expr1
                    shows2 = subExpr expr2
                    offset = sliceOffset slice
            body (PNAppend widths exprs) = hlAppend widths $ map subExpr exprs
            body (PNMatch slice imps expr) = hlImpsMatch (sliceWidth slice) imps $ hlBitfield slice $ subExpr expr
            body (PNOp terms expr) = hlShowOTerms terms expr
            body expr = error $ "body: can't show PNExpr `" ++ show expr ++ "'"

            subExpr expr = hlShowPNExpr expr
hlShowPNExpr expr = body expr
        where
            body (PNLiteral NoSimValue) = showString "dot"
            body (PNLiteral (SimValue int [])) = shows int
            body (PNBool True) = showString "tt"
            body (PNBool False) = showString "ff"
            body (PNInput inp) = showChar 'i' . shows inp
            body (PNBitfield slice expr) = hlBitfield slice (subExpr expr)
            body (PNInsertBitfield slice expr1 expr2) = foldl1' (hlInfixOp "+") $ catMaybes [
                if offset == 0 then Nothing else Just $ hlBitfield (0 +: offset) shows1,
                Just $ hlInfixOp "-" shows1 $ hlInfixOp "%" shows1 $ showsBit $ sliceHigh slice + 1,
                Just $ hlShl shows2 offset ]
                where
                    shows1 = subExpr expr1
                    shows2 = subExpr expr2
                    offset = sliceOffset slice
            body (PNAppend widths exprs) = hlAppend widths $ map subExpr exprs
            body (PNMatch slice imps expr) = hlImpsMatch (sliceWidth slice) imps $ hlBitfield slice $ subExpr expr
            body (PNOp terms expr) = hlShowOTerms terms expr
            body expr = error $ "body: can't show PNExpr `" ++ show expr ++ "'"

            subExpr expr = hlShowPNExpr expr