{-|
Module      : Htcc.Visualizer.Core
Description : Build AST from C source code
Copyright   : (c) roki, 2019
License     : MIT
Maintainer  : falgon53@yahoo.co.jp
Stability   : experimental
Portability : POSIX

Build AST from C source code
-}
{-# LANGUAGE FlexibleContexts, OverloadedStrings #-}
module Htcc.Visualizer.Core (
    visualize
) where

import qualified Data.Text                 as T
import           Data.Tree                 (Tree (..))
import           Diagrams.Backend.SVG      (SVG, renderPretty)
import           Diagrams.Prelude
import           Diagrams.TwoD.Layout.Tree (renderTree, slHSep, slVSep,
                                            symmLayout')

import           Htcc.CRules.Types         as CT
import           Htcc.Parser               (ASTs)
import           Htcc.Parser.AST.Core      (ATKind (..), ATree (..),
                                            fromATKindFor)
import           Htcc.Utils                (putStrLnErr)

-- | the function to convert `ATree` to `Data.Tree`
encodeTree :: Show i => ATree i -> Tree String
encodeTree :: ATree i -> Tree String
encodeTree ATEmpty = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "Null" []
encodeTree (ATNode ATAdd _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "+" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATAddPtr _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "+" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATSub _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "-" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATSubPtr _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "-" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATPtrDis _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "-" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATMul _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "*" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATDiv _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "/" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATMod _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "%" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATAddAssign _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "+=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATSubAssign _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "-=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATMulAssign _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "*=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATDivAssign _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "/=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATAddPtrAssign _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "+=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATSubPtrAssign _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "-=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATLAnd _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "&&" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATLOr _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "||" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATAnd _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "&" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATAndAssign _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "&=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATOr _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "|" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATOrAssign _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "|=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATXor _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "^" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATXorAssign _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "^=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATBitNot _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "~" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATShl _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "<<" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATShlAssign _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "<<=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATShr _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node ">>" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATShrAssign _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node ">>=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATLT _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "<" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATLEQ _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "<=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATGT _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node ">" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATGEQ _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node ">=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATEQ _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "==" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATNEQ _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "!=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATNot _ l :: ATree i
l _) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "!" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l]
encodeTree (ATNode ATAddr _ l :: ATree i
l _) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "&" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l]
encodeTree (ATNode ATDeref _ l :: ATree i
l _) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "*" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l]
encodeTree (ATNode ATAssign _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "=" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATPreInc _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "++ (pre)" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATPreDec _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "-- (pre)" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATPostInc _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "++ (post)" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATPostDec _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "-- (post)" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode (ATNum n :: i
n) t :: StorageClass i
t l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node (i -> String
forall a. Show a => a -> String
show i
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ " (" String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeKind i -> String
forall a. Show a => a -> String
show (StorageClass i -> TypeKind i
forall (a :: * -> *) i. TypeKindBase a => a i -> TypeKind i
CT.toTypeKind StorageClass i
t) String -> String -> String
forall a. [a] -> [a] -> [a]
++ ")") [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode (ATConditional a :: ATree i
a b :: ATree i
b c :: ATree i
c) _ _ _) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "?:" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
a, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
b, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
c]
encodeTree (ATNode ATComma _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "," [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATCast t :: StorageClass i
t l :: ATree i
l _) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node ("(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeKind i -> String
forall a. Show a => a -> String
show (StorageClass i -> TypeKind i
forall (a :: * -> *) i. TypeKindBase a => a i -> TypeKind i
CT.toTypeKind StorageClass i
t) String -> String -> String
forall a. [a] -> [a] -> [a]
++ ")\n(type cast)") [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l]
encodeTree (ATNode (ATMemberAcc _) _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "." [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATReturn _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "return" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATIf _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "if" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATElse _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "else" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode (ATSwitch th :: ATree i
th xs :: [ATree i]
xs) _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "switch" (Forest String -> Tree String) -> Forest String -> Tree String
forall a b. (a -> b) -> a -> b
$ ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
th Tree String -> Forest String -> Forest String
forall a. a -> [a] -> [a]
: (ATree i -> Tree String) -> [ATree i] -> Forest String
forall a b. (a -> b) -> [a] -> [b]
map ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree [ATree i]
xs Forest String -> Forest String -> Forest String
forall a. [a] -> [a] -> [a]
++ [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode (ATCase _ v :: i
v) _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node ("case " String -> String -> String
forall a. [a] -> [a] -> [a]
++ i -> String
forall a. Show a => a -> String
show i
v) [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode (ATDefault _) _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "default" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATWhile _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "while" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode (ATFor atf :: [ATKindFor i]
atf) _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "for" (Forest String -> Tree String) -> Forest String -> Tree String
forall a b. (a -> b) -> a -> b
$ (ATKindFor i -> Tree String) -> [ATKindFor i] -> Forest String
forall a b. (a -> b) -> [a] -> [b]
map (ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree (ATree i -> Tree String)
-> (ATKindFor i -> ATree i) -> ATKindFor i -> Tree String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ATKindFor i -> ATree i
forall a. ATKindFor a -> ATree a
fromATKindFor) [ATKindFor i]
atf Forest String -> Forest String -> Forest String
forall a. [a] -> [a] -> [a]
++ [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATBreak _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "break" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode ATContinue _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "continue" [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode (ATGoto lbl :: Text
lbl) _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node ("goto " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
lbl) [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode (ATLabel lbl :: Text
lbl) _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node (":" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
lbl) [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode (ATBlock xs :: [ATree i]
xs) _ _ _) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "{}" (Forest String -> Tree String) -> Forest String -> Tree String
forall a b. (a -> b) -> a -> b
$ (ATree i -> Tree String) -> [ATree i] -> Forest String
forall a b. (a -> b) -> [a] -> [b]
map ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree [ATree i]
xs
encodeTree (ATNode (ATLVar t :: StorageClass i
t o :: i
o) _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node (StorageClass i -> String
forall a. Show a => a -> String
show StorageClass i
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ " lvar" String -> String -> String
forall a. [a] -> [a] -> [a]
++ i -> String
forall a. Show a => a -> String
show i
o) [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode (ATGVar t :: StorageClass i
t n :: Text
n) _ l :: ATree i
l r :: ATree i
r) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node (StorageClass i -> String
forall a. Show a => a -> String
show StorageClass i
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ " " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
n) [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
l, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
r]
encodeTree (ATNode (ATDefFunc fname :: Text
fname Nothing) t :: StorageClass i
t lhs :: ATree i
lhs _) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node (TypeKind i -> String
forall a. Show a => a -> String
show (StorageClass i -> TypeKind i
forall (a :: * -> *) i. TypeKindBase a => a i -> TypeKind i
CT.toTypeKind StorageClass i
t) String -> String -> String
forall a. [a] -> [a] -> [a]
++ " " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
fname String -> String -> String
forall a. [a] -> [a] -> [a]
++ "()") [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
lhs]
encodeTree (ATNode (ATDefFunc fname :: Text
fname (Just args :: [ATree i]
args)) t :: StorageClass i
t lhs :: ATree i
lhs _) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node (TypeKind i -> String
forall a. Show a => a -> String
show (StorageClass i -> TypeKind i
forall (a :: * -> *) i. TypeKindBase a => a i -> TypeKind i
CT.toTypeKind StorageClass i
t) String -> String -> String
forall a. [a] -> [a] -> [a]
++ " " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
fname String -> String -> String
forall a. [a] -> [a] -> [a]
++ "(some arguments)") (Forest String -> Tree String) -> Forest String -> Tree String
forall a b. (a -> b) -> a -> b
$ (ATree i -> Tree String) -> [ATree i] -> Forest String
forall a b. (a -> b) -> [a] -> [b]
map ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree [ATree i]
args Forest String -> Forest String -> Forest String
forall a. [a] -> [a] -> [a]
++ [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
lhs]
encodeTree (ATNode (ATCallFunc fname :: Text
fname Nothing) _ lhs :: ATree i
lhs rhs :: ATree i
rhs) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node (Text -> String
T.unpack Text
fname String -> String -> String
forall a. [a] -> [a] -> [a]
++ "()") [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
lhs, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
rhs]
encodeTree (ATNode (ATCallFunc fname :: Text
fname (Just args :: [ATree i]
args)) _ lhs :: ATree i
lhs rhs :: ATree i
rhs) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node (Text -> String
T.unpack Text
fname String -> String -> String
forall a. [a] -> [a] -> [a]
++ "(some arguments)") (Forest String -> Tree String) -> Forest String -> Tree String
forall a b. (a -> b) -> a -> b
$ (ATree i -> Tree String) -> [ATree i] -> Forest String
forall a b. (a -> b) -> [a] -> [b]
map ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree [ATree i]
args Forest String -> Forest String -> Forest String
forall a. [a] -> [a] -> [a]
++ [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
lhs, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
rhs]
encodeTree (ATNode ATExprStmt _ lhs :: ATree i
lhs _) = ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
lhs
encodeTree (ATNode (ATStmtExpr exps :: [ATree i]
exps) _ lhs :: ATree i
lhs rhs :: ATree i
rhs) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "({})" (Forest String -> Tree String) -> Forest String -> Tree String
forall a b. (a -> b) -> a -> b
$ (ATree i -> Tree String) -> [ATree i] -> Forest String
forall a b. (a -> b) -> [a] -> [b]
map ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree [ATree i]
exps Forest String -> Forest String -> Forest String
forall a. [a] -> [a] -> [a]
++ [ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
lhs, ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ATree i
rhs]
encodeTree (ATNode (ATNull _) _ _ _) = String -> Forest String -> Tree String
forall a. a -> Forest a -> Tree a
Node "" []

renderNTree :: Tree String -> QDiagram SVG V2 Double Any
renderNTree :: Tree String -> QDiagram SVG V2 Double Any
renderNTree nt :: Tree String
nt = (String -> QDiagram SVG V2 Double Any)
-> (P2 Double -> P2 Double -> QDiagram SVG V2 Double Any)
-> Tree (String, P2 Double)
-> QDiagram SVG V2 Double Any
forall m n a b.
(Monoid' m, Floating n, Ord n) =>
(a -> QDiagram b V2 n m)
-> (P2 n -> P2 n -> QDiagram b V2 n m)
-> Tree (a, P2 n)
-> QDiagram b V2 n m
renderTree
    (\a :: String
a -> String -> QDiagram SVG V2 Double Any
forall n b.
(Typeable n, RealFloat n, Renderable (Text n) b) =>
String -> QDiagram b V2 n Any
letter String
a QDiagram SVG V2 Double Any
-> QDiagram SVG V2 Double Any -> QDiagram SVG V2 Double Any
forall n (v :: * -> *) m b.
(OrderedField n, Metric v, Semigroup m) =>
QDiagram b v n m -> QDiagram b v n m -> QDiagram b v n m
`atop` Double -> QDiagram SVG V2 Double Any
forall t n.
(TrailLike t, V t ~ V2, N t ~ n, Transformable t) =>
n -> t
circle 2.5 QDiagram SVG V2 Double Any
-> (QDiagram SVG V2 Double Any -> QDiagram SVG V2 Double Any)
-> QDiagram SVG V2 Double Any
forall a b. a -> (a -> b) -> b
# Colour Double
-> QDiagram SVG V2 Double Any -> QDiagram SVG V2 Double Any
forall n a.
(InSpace V2 n a, Floating n, Typeable n, HasStyle a) =>
Colour Double -> a -> a
fc Colour Double
forall a. (Ord a, Floating a) => Colour a
white)
    P2 Double -> P2 Double -> QDiagram SVG V2 Double Any
forall t (v :: * -> *) n.
(V t ~ v, N t ~ n, TrailLike t) =>
Point v n -> Point v n -> t
(~~)
    (SymmLayoutOpts Double String
-> Tree String -> Tree (String, P2 Double)
forall n a.
(Fractional n, Ord n) =>
SymmLayoutOpts n a -> Tree a -> Tree (a, P2 n)
symmLayout' (SymmLayoutOpts Double String
forall d. Default d => d
with SymmLayoutOpts Double String
-> (SymmLayoutOpts Double String -> SymmLayoutOpts Double String)
-> SymmLayoutOpts Double String
forall a b. a -> (a -> b) -> b
& (Double -> Identity Double)
-> SymmLayoutOpts Double String
-> Identity (SymmLayoutOpts Double String)
forall n a. Lens' (SymmLayoutOpts n a) n
slHSep ((Double -> Identity Double)
 -> SymmLayoutOpts Double String
 -> Identity (SymmLayoutOpts Double String))
-> Double
-> SymmLayoutOpts Double String
-> SymmLayoutOpts Double String
forall s t a b. ASetter s t a b -> b -> s -> t
.~ 6 SymmLayoutOpts Double String
-> (SymmLayoutOpts Double String -> SymmLayoutOpts Double String)
-> SymmLayoutOpts Double String
forall a b. a -> (a -> b) -> b
& (Double -> Identity Double)
-> SymmLayoutOpts Double String
-> Identity (SymmLayoutOpts Double String)
forall n a. Lens' (SymmLayoutOpts n a) n
slVSep ((Double -> Identity Double)
 -> SymmLayoutOpts Double String
 -> Identity (SymmLayoutOpts Double String))
-> Double
-> SymmLayoutOpts Double String
-> SymmLayoutOpts Double String
forall s t a b. ASetter s t a b -> b -> s -> t
.~ 6) Tree String
nt)
    where
        letter :: String -> QDiagram b V2 n Any
letter a :: String
a = String -> QDiagram b V2 n Any
forall n b.
(TypeableFloat n, Renderable (Text n) b) =>
String -> QDiagram b V2 n Any
text String
a QDiagram b V2 n Any
-> (QDiagram b V2 n Any -> QDiagram b V2 n Any)
-> QDiagram b V2 n Any
forall a b. a -> (a -> b) -> b
# String -> QDiagram b V2 n Any -> QDiagram b V2 n Any
forall a. HasStyle a => String -> a -> a
font "monospace" QDiagram b V2 n Any
-> (QDiagram b V2 n Any -> QDiagram b V2 n Any)
-> QDiagram b V2 n Any
forall a b. a -> (a -> b) -> b
# Measure n -> QDiagram b V2 n Any -> QDiagram b V2 n Any
forall a n.
(N a ~ n, Typeable n, HasStyle a) =>
Measure n -> a -> a
fontSize (n -> Measure n
forall n. Num n => n -> Measure n
local 0.7)

-- | Build AST from C source code
visualize :: Show i => ASTs i -> SizeSpec V2 Double -> FilePath -> IO ()
visualize :: ASTs i -> SizeSpec V2 Double -> String -> IO ()
visualize ast :: ASTs i
ast ss :: SizeSpec V2 Double
ss fpath :: String
fpath = let et :: Forest String
et = (ATree i -> Tree String) -> ASTs i -> Forest String
forall a b. (a -> b) -> [a] -> [b]
map ATree i -> Tree String
forall i. Show i => ATree i -> Tree String
encodeTree ASTs i
ast in if Bool -> Bool
not (Forest String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Forest String
et) then
    String -> SizeSpec V2 Double -> QDiagram SVG V2 Double Any -> IO ()
forall n.
SVGFloat n =>
String -> SizeSpec V2 n -> QDiagram SVG V2 n Any -> IO ()
renderPretty String
fpath SizeSpec V2 Double
ss ((Tree String
 -> QDiagram SVG V2 Double Any -> QDiagram SVG V2 Double Any)
-> QDiagram SVG V2 Double Any
-> Forest String
-> QDiagram SVG V2 Double Any
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (QDiagram SVG V2 Double Any
-> QDiagram SVG V2 Double Any -> QDiagram SVG V2 Double Any
forall n a.
(InSpace V2 n a, Juxtaposable a, Semigroup a) =>
a -> a -> a
(|||) (QDiagram SVG V2 Double Any
 -> QDiagram SVG V2 Double Any -> QDiagram SVG V2 Double Any)
-> (Tree String -> QDiagram SVG V2 Double Any)
-> Tree String
-> QDiagram SVG V2 Double Any
-> QDiagram SVG V2 Double Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tree String -> QDiagram SVG V2 Double Any
renderNTree) (Tree String -> QDiagram SVG V2 Double Any
renderNTree (Tree String -> QDiagram SVG V2 Double Any)
-> Tree String -> QDiagram SVG V2 Double Any
forall a b. (a -> b) -> a -> b
$ Forest String -> Tree String
forall a. [a] -> a
head Forest String
et) (Forest String -> QDiagram SVG V2 Double Any)
-> Forest String -> QDiagram SVG V2 Double Any
forall a b. (a -> b) -> a -> b
$ Forest String -> Forest String
forall a. [a] -> [a]
tail Forest String
et) else
        Text -> IO ()
putStrLnErr "There is nothing to describe"