on a85deed help sign in
elk/src/AST/Expression/General.hs
131 lines 3.9 kB history raw
1{-# OPTIONS_GHC -Wall #-}
3{-| The Abstract Syntax Tree (AST) for expressions comes in a couple formats.
4The first is the fully general version and is labeled with a prime (Expr').
5The others are specialized versions of the AST that represent specific phases
6of the compilation process. I expect there to be more phases as we begin to
7enrich the AST with more information.
8-}
9module AST.Expression.General where
11import qualified Data.List as List
13import qualified AST.Effects as Effects
14import qualified AST.Literal as Literal
15import qualified AST.Module.Name as ModuleName
16import qualified AST.Pattern as Pattern
17import qualified AST.Variable as Var
18import qualified Reporting.Annotation as A
22---- GENERAL AST ----
25{-| This is a fully general Abstract Syntax Tree (AST) for expressions. It has
26"type holes" that allow us to enrich the AST with additional information as we
27move through the compilation process. The type holes are used to represent:
29 ann: Annotations for arbitrary expressions. Allows you to add information
30 to the AST like position in source code or inferred types.
32 def: Definition style. The source syntax separates type annotations and
33 definitions, but after parsing we check that they are well formed and
34 collapse them.
36 var: Representation of variables. Starts as strings, but is later enriched
37 with information about what module a variable came from.
39-}
40type Expr annotation definition variable tipe =
41 A.Annotated annotation (Expr' annotation definition variable tipe)
44data Expr' ann def var typ
45 = Literal Literal.Literal
46 | Var var
47 | ExplicitList [Expr ann def var typ]
48 | Binop var (Expr ann def var typ) (Expr ann def var typ)
49 | Lambda (Pattern.Pattern ann var) (Expr ann def var typ)
50 | App (Expr ann def var typ) (Expr ann def var typ)
51 | If [(Expr ann def var typ, Expr ann def var typ)] (Expr ann def var typ)
52 | Let [def] (Expr ann def var typ)
53 | Case (Expr ann def var typ) [(Pattern.Pattern ann var, Expr ann def var typ)]
54 | Data String [Expr ann def var typ]
55 | Access (Expr ann def var typ) String
56 | Update (Expr ann def var typ) [(String, Expr ann def var typ)]
57 | Record [(String, Expr ann def var typ)]
58 -- for type checking and code gen only
59 | Cmd ModuleName.Canonical
60 | Sub ModuleName.Canonical
61 | OutgoingPort String typ
62 | IncomingPort String typ
63 | Program (Main typ) (Expr ann def var typ)
64 | SaveEnv ModuleName.Canonical Effects.Canonical
65 | GLShader String String Literal.GLShaderTipe
68data Main typ
69 = VDom
70 | NoFlags
71 | Flags typ
75---- UTILITIES ----
78rawVar :: String -> Expr' ann def Var.Raw typ
79rawVar x =
80 Var (Var.Raw x)
83localVar :: String -> Expr' ann def Var.Canonical typ
84localVar x =
85 Var (Var.Canonical Var.Local x)
88tuple :: [Expr ann def var typ] -> Expr' ann def var typ
89tuple expressions =
90 Data ("_Tuple" ++ show (length expressions)) expressions
93collectFields :: (Var.ToString var) => Expr ann def var typ -> Maybe String
94collectFields expr =
95 collectFieldsHelp expr []
98collectFieldsHelp :: (Var.ToString var) => Expr ann def var typ -> [String] -> Maybe String
99collectFieldsHelp (A.A _ expr) fields =
100 case expr of
101 Var var ->
102 Just (List.intercalate "." (Var.toString var : fields))
104 Access record field ->
105 collectFieldsHelp record (field : fields)
107 _ ->
108 Nothing
111collectApps :: Expr ann def var typ -> [Expr ann def var typ]
112collectApps annExpr@(A.A _ expr) =
113 case expr of
114 App a b ->
115 collectApps a ++ [b]
117 _ ->
118 [annExpr]
121collectLambdas :: Expr ann def var typ -> ([Pattern.Pattern ann var], Expr ann def var typ)
122collectLambdas lexpr@(A.A _ expr) =
123 case expr of
124 Lambda pattern body ->
125 let
126 (ps, body') = collectLambdas body
127 in
128 (pattern : ps, body')
130 _ ->
131 ([], lexpr)