1{-# LANGUAGE DeriveDataTypeable #-}
2module SourceSyntax.Expression where
5import Data.List (intercalate)
6import qualified Text.Pandoc as Pandoc
7import SourceSyntax.PrettyPrint
8import Text.PrettyPrint as PP
9import qualified SourceSyntax.Helpers as Help
10import qualified SourceSyntax.Location as Location
11import qualified SourceSyntax.Pattern as Pattern
12import qualified SourceSyntax.Literal as Literal
15type LExpr tipe var = Location.Located (Expr tipe var)
17 = Literal Literal.Literal
19 | Range (LExpr t v) (LExpr t v)
20 | ExplicitList [LExpr t v]
21 | Binop String (LExpr t v) (LExpr t v)
22 | Lambda Pattern.Pattern (LExpr t v)
23 | App (LExpr t v) (LExpr t v)
24 | MultiIf [(LExpr t v,LExpr t v)]
25 | Let [Def t v] (LExpr t v)
26 | Case (LExpr t v) [(Pattern.Pattern, LExpr t v)]
27 | Data String [LExpr t v]
28 | Access (LExpr t v) String
29 | Remove (LExpr t v) String
30 | Insert (LExpr t v) String (LExpr t v)
31 | Modify (LExpr t v) [(String, LExpr t v)]
32 | Record [(String, LExpr t v)]
33 | Markdown Pandoc.Pandoc
34 deriving (Eq, Data, Typeable, Show)
37 = Def Pattern.Pattern (LExpr tipe var)
38 | TypeAnnotation String Type
39 deriving (Eq, Data, Typeable, Show)
41tuple es = Data ("Tuple" ++ show (length es)) es
43delist (Location.L _ _ (Data "::" [h,t])) = h : delist t
46instance Pretty (Expr t v) where
49 Literal lit -> pretty lit
50 Var x@(c:_) -> parensIf (Help.isOp c) (PP.text x)
51 Range e1 e2 -> PP.brackets (pretty e1 <> PP.text ".." <> pretty e2)
52 ExplicitList es -> PP.brackets (commaCat (map pretty es))
53 Binop op e1 e2 -> PP.sep [ prettyParens e1 <+> PP.text op, prettyParens e2 ]
54 Lambda p e -> let (ps,body) = collectLambdas (Location.none $ Lambda p e)
55 in PP.text "\\" <> PP.sep ps <+> PP.text "->" <+> pretty body
56 App _ _ -> PP.hang func 2 (PP.sep args)
57 where func:args = map prettyParens (collectApps (Location.none expr))
58 MultiIf branches -> PP.text "if" $$ nest 3 (vcat $ map iff branches)
60 iff (b,e) = PP.text "|" <+> PP.hang (pretty b <+> PP.text "->") 2 (pretty e)
62 PP.sep [ PP.hang (PP.text "let") 4 (PP.vcat (map pretty defs))
63 , PP.text "in" <+> pretty e ]
65 PP.hang pexpr 2 (PP.vcat (map pretty' pats))
67 pexpr = PP.sep [ PP.text "case" <+> pretty e, PP.text "of" ]
68 pretty' (p,e) = pretty p <+> PP.text "->" <+> pretty e
69 Data "::" [hd,tl] -> pretty hd <+> PP.text "::" <+> pretty tl
70 Data "[]" [] -> PP.text "[]"
71 Data name es -> PP.hang (PP.text name) 2 (PP.sep (map prettyParens es))
72 Access e x -> prettyParens e <> PP.text "." <> PP.text x
73 Remove e x -> PP.braces (pretty e <+> PP.text "-" <+> PP.text x)
74 Insert (Location.L _ _ (Remove e y)) x v ->
75 PP.braces (pretty e <+> PP.text "-" <+> PP.text y <+> PP.text "|" <+> PP.text x <+> PP.text "=" <+> pretty v)
77 PP.braces (pretty e <+> PP.text "|" <+> PP.text x <+> PP.text "=" <+> pretty v)
80 PP.braces $ PP.hang (pretty e <+> PP.text "|")
82 (PP.sep . PP.punctuate PP.comma $ map field fs)
84 field (x,e) = PP.text x <+> PP.text "<-" <+> pretty e
87 PP.braces $ PP.nest 2 (PP.sep . PP.punctuate PP.comma $ map field fs)
89 field (x,e) = PP.text x <+> PP.text "=" <+> pretty e
91 Markdown _ -> PP.text "[markdown| ... |]"
93instance Pretty (Def t v) where
96 TypeAnnotation name tipe ->
97 PP.text name <+> PP.text ":" <+> PP.text (show tipe)
99 pretty pattern <+> PP.text "=" <+> pretty expr
101collectApps lexpr@(Location.L _ _ expr) =
103 App a b -> collectApps a ++ [b]
106collectLambdas lexpr@(Location.L _ _ expr) =
108 Lambda pattern body ->
109 let (ps, body') = collectLambdas body
110 in (pretty pattern : ps, body')
113prettyParens (Location.L _ _ expr) = parensIf needed (pretty expr)
123 Data name (x:xs) -> name /= "::"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list