aboutsummaryrefslogtreecommitdiff
path: root/src/Haskell/AST.hs
blob: f8b5c729c140bec1f896742fde3174cf9038b040 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
module Haskell.AST where

import Data.List
import Pretty


type Name = String
type TyVar = String

data AST = AST [Toplevel]
  deriving (Show, Eq)

data Toplevel = TopDef Def
              | TopDecl Decl
              | TopData Data
              | TopClass Class
              | TopInst Inst
  deriving (Show, Eq)

data Def = Def Name Expr
  deriving (Show, Eq)

data Expr = App Expr [Expr]
          | Ref Name
          | Num Integer
          | Tup [Expr]
          | Lam [Name] Expr
          | Case Expr [(Pat, Expr)]
  deriving (Show, Eq)

data Pat = PatAny
         | PatVar Name
         | PatCon Name [Pat]
         | PatTup [Pat]
  deriving (Show, Eq)

data Decl = Decl Name Type
  deriving (Show, Eq)

data Type = TyTup [Type]
          | TyInt
          | TyFun Type Type
          | TyRef Name [Type]
          | TyVar Name
          | TyVoid
  deriving (Show, Eq)

data Data = Data Name [TyVar] [(Name, [Type])]
  deriving (Show, Eq)

data Class = Class Name [TyVar] [Decl]
  deriving (Show, Eq)

data Inst = Inst Name Type [Def]
  deriving (Show, Eq)


instance Pretty AST where
    pretty (AST tops) = Node "" (map pretty tops)

instance Pretty Toplevel where
    pretty (TopDef x) = pretty x
    pretty (TopDecl x) = pretty x
    pretty (TopData x) = pretty x
    pretty (TopClass x) = pretty x
    pretty (TopInst x) = pretty x

instance Pretty Def where
    pretty (Def n e) = Node (n ++ " =") [pretty e]

instance Pretty Expr where
    pretty (App e as) = Bracket "(" ")" "" (map pretty (e:as))
    pretty (Ref n) = Leaf n
    pretty (Num n) = Leaf (show n)
    pretty (Tup es) = Bracket "(" ")" "," (map pretty es)
    pretty (Lam as e) = Bracket "(" ")" "" [Node ("\\" ++ intercalate " " as ++ " ->") [pretty e]]
    pretty (Case e arms) = Bracket "(" ")" "" [Node ("case " ++ pprintOneline e ++ " of") [Bracket "{" "}" ";" (map go arms)]]
      where go (p, e') = Node (pprintOneline p ++ " ->") [pretty e']

instance Pretty Pat where
    pretty PatAny = Leaf "_"
    pretty (PatVar n) = Leaf n
    pretty (PatCon n ps) = Bracket "(" ")" "" (Leaf n : map pretty ps)
    pretty (PatTup ps) = Bracket "(" ")" "," (map pretty ps)

instance Pretty Decl where
    pretty (Decl n t) = Node (n ++ " :: ") [pretty t]

instance Pretty Type where
    pretty (TyTup ts) = Bracket "(" ")" "," (map pretty ts)
    pretty TyInt = Leaf "Int"
    pretty (TyFun t u) = Leaf $ pprintOneline t ++ " -> " ++ pprintOneline u
    pretty (TyRef n as) = Bracket "(" ")" "" (Leaf n : map pretty as)
    pretty (TyVar n) = Leaf n
    pretty TyVoid = Leaf "#Void"

instance Pretty Data where
    pretty (Data n as cs) = Node ("data " ++ n ++ " " ++ intercalate " " as ++ " =") [Bracket "" "" "|" (map go cs)]
      where go (m, ts) = Node m (map pretty ts)

instance Pretty Class where
    pretty (Class n as ds) = Node ("class " ++ n ++ " " ++ intercalate " " as ++ " where") [Bracket "{" "}" ";" (map pretty ds)]

instance Pretty Inst where
    pretty (Inst n t ds) = Node ("instance " ++ n ++ " " ++ pprintOneline t ++ " where") [Bracket "{" "}" ";" (map pretty ds)]


class AllRefs a where
    allRefs :: a -> [Name]

instance AllRefs AST where
    allRefs (AST tops) = nub $ concatMap allRefs tops

instance AllRefs Toplevel where
    allRefs (TopDef def) = allRefs def
    allRefs (TopDecl _) = []
    allRefs (TopData _) = []
    allRefs (TopClass _) = []
    allRefs (TopInst inst) = allRefs inst

instance AllRefs Def where
    allRefs (Def _ e) = allRefs e

instance AllRefs Expr where
    allRefs (App e es) = nub $ concatMap allRefs (e : es)
    allRefs (Ref n) = [n]
    allRefs (Num _) = []
    allRefs (Tup es) = nub $ concatMap allRefs es
    allRefs (Lam ns e) = allRefs e \\ ns
    allRefs (Case e pairs) = nub $ allRefs e ++ concatMap (allRefs . snd) pairs

instance AllRefs Inst where
    allRefs (Inst _ _ ds) = nub $ concatMap allRefs ds