]> Git — Sourcephile - haskell/symantic.git/blob - Language/Symantic/Repr/Text.hs
init
[haskell/symantic.git] / Language / Symantic / Repr / Text.hs
1 {-# LANGUAGE FlexibleInstances #-}
2 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
3 {-# LANGUAGE MultiParamTypeClasses #-}
4 {-# LANGUAGE OverloadedStrings #-}
5 {-# LANGUAGE TypeFamilies #-}
6 -- | Interpreter to serialize an expression into a 'Text'.
7 module Language.Symantic.Repr.Text where
8
9 import Data.Monoid ((<>))
10 import Data.String (IsString(..))
11 import Data.Text (Text)
12 import qualified Data.Text as Text
13
14 import Language.Symantic.Expr
15
16 -- * Type 'Repr_Text'
17
18 -- | Interpreter's data.
19 newtype Repr_Text (lam:: * -> *) h
20 = Repr_Text
21 { unRepr_Text
22 -- Inherited attributes:
23 :: Precedence
24 -> Repr_Text_Lambda_Depth
25 -- Synthetised attributes:
26 -> Text
27 }
28 type Repr_Text_Lambda_Depth = Int
29
30 -- | Interpreter.
31 text_from_expr :: Repr_Text lam h -> Text
32 text_from_expr r = unRepr_Text r precedence_Toplevel 0
33
34 {-
35 instance Show (Repr_Text lam a) where
36 show = text_from_expr
37 -}
38 instance Sym_Lambda lam (Repr_Text lam) where
39 type Lambda_from_Repr (Repr_Text lam) = lam
40 app (Repr_Text f) (Repr_Text x) = Repr_Text $ \p v ->
41 let p' = precedence_App in
42 paren p p' $
43 f p' v <> " " <> x p' v
44 inline = repr_text_fun "!"
45 val = repr_text_fun ""
46 lazy = repr_text_fun "~"
47
48 let_inline = repr_text_let "!"
49 let_val = repr_text_let ""
50 let_lazy = repr_text_let "~"
51
52 -- ** Helpers for 'Sym_Lambda' instances
53 repr_text_fun :: Text -> (Repr_Text lam a2 -> Repr_Text lam a1) -> Repr_Text lam a
54 repr_text_fun mode e =
55 Repr_Text $ \p v ->
56 let p' = precedence_Lambda in
57 let x = "x" <> Text.pack (show v) in
58 paren p p' $
59 "\\" <> mode <> x <> " -> " <>
60 unRepr_Text (e (Repr_Text $ \_p _v -> x)) p' (succ v)
61 repr_text_let
62 :: Text
63 -> Repr_Text lam a1
64 -> (Repr_Text lam a3 -> Repr_Text lam a2)
65 -> Repr_Text lam a
66 repr_text_let mode e in_ =
67 Repr_Text $ \p v ->
68 let p' = precedence_Let in
69 let x = "x" <> Text.pack (show v) in
70 paren p p' $
71 "let" <> mode <> " " <> x <> " = " <> unRepr_Text e p (succ v) <> " in " <>
72 unRepr_Text (in_ (Repr_Text $ \_p _v -> x)) p (succ v)
73
74 instance Sym_Bool (Repr_Text lam) where
75 bool a = Repr_Text $ \_p _v ->
76 Text.pack (show a)
77 not (Repr_Text x) =
78 Repr_Text $ \p v ->
79 let p' = precedence_Not in
80 paren p p' $ "!" <> x p' v
81 (&&) (Repr_Text x) (Repr_Text y) =
82 Repr_Text $ \p v ->
83 let p' = precedence_And in
84 paren p p' $ x p' v <> " && " <> y p' v
85 (||) (Repr_Text x) (Repr_Text y) =
86 Repr_Text $ \p v ->
87 let p' = precedence_Or in
88 paren p p' $ x p' v <> " || " <> y p' v
89 xor (Repr_Text x) (Repr_Text y) =
90 Repr_Text $ \p v ->
91 let p' = precedence_Xor in
92 paren p p' $ "xor " <> x p' v <> " " <> y p' v
93 instance Sym_Int (Repr_Text lam) where
94 int a = Repr_Text $ \_p _v ->
95 Text.pack (show a)
96 abs (Repr_Text x) =
97 Repr_Text $ \p v ->
98 let p' = precedence_App in
99 paren p p' $ "abs " <> x p' v
100 negate (Repr_Text x) =
101 Repr_Text $ \p v ->
102 let p' = precedence_Neg in
103 paren p p' $ "-" <> x p' v
104 (+) (Repr_Text x) (Repr_Text y) =
105 Repr_Text $ \p v ->
106 let p' = precedence_Add in
107 paren p p' $ x p' v <> " + " <> y p' v
108 (-) (Repr_Text x) (Repr_Text y) =
109 Repr_Text $ \p v ->
110 let p' = precedence_Sub in
111 paren p p' $ x p' v <> " - " <> y p' v
112 (*) (Repr_Text x) (Repr_Text y) =
113 Repr_Text $ \p v ->
114 let p' = precedence_Mul in
115 paren p p' $ x p' v <> " * " <> y p' v
116 mod (Repr_Text x) (Repr_Text y) =
117 Repr_Text $ \p v ->
118 let p' = precedence_Mod in
119 paren p p' $ x p' v <> " % " <> y p' v
120 instance Sym_Maybe (Repr_Text lam) where
121 nothing =
122 Repr_Text $ \_p _v ->
123 "nothing"
124 just (Repr_Text a) =
125 Repr_Text $ \p v ->
126 let p' = precedence_App in
127 paren p p' $ "just "
128 <> a (p') v
129 instance Sym_Maybe_Lam lam (Repr_Text lam) where
130 maybe (Repr_Text n) (Repr_Text j) (Repr_Text m) =
131 Repr_Text $ \p v ->
132 let p' = precedence_App in
133 paren p p' $ "maybe"
134 <> " " <> n p' v
135 <> " " <> j p' v
136 <> " " <> m p' v
137 instance Sym_If (Repr_Text lam) where
138 if_ (Repr_Text cond) (Repr_Text ok) (Repr_Text ko) =
139 Repr_Text $ \p v ->
140 let p' = precedence_If in
141 paren p p' $
142 "if " <> cond p' v <>
143 " then " <> ok p' v <>
144 " else " <> ko p' v
145 instance Sym_When (Repr_Text lam) where
146 when (Repr_Text cond) (Repr_Text ok) =
147 Repr_Text $ \p v ->
148 let p' = precedence_If in
149 paren p p' $
150 "when " <> cond p' v <>
151 " " <> ok p' v
152 instance Sym_Eq (Repr_Text lam) where
153 (==) (Repr_Text x) (Repr_Text y) =
154 Repr_Text $ \p v ->
155 let p' = precedence_Eq in
156 paren p p' $
157 x p' v <> " == " <> y p' v
158 instance Sym_Ord (Repr_Text lam) where
159 compare (Repr_Text x) (Repr_Text y) =
160 Repr_Text $ \p v ->
161 let p' = precedence_Eq in
162 paren p p' $
163 "compare " <> x p' v <> " " <> y p' v
164 instance Sym_List (Repr_Text lam) where
165 list_empty = Repr_Text $ \_p _v ->
166 "[]"
167 list_cons (Repr_Text x) (Repr_Text xs) =
168 Repr_Text $ \p v ->
169 let p' = precedence_App in
170 paren p p' $
171 x p' v <> ":" <> xs p' v
172 list l = Repr_Text $ \_p v ->
173 let p' = precedence_Toplevel in
174 "[" <> Text.intercalate ", " ((\(Repr_Text a) -> a p' v) <$> l) <> "]"
175 instance Sym_List_Lam lam (Repr_Text lam) where
176 list_filter (Repr_Text f) (Repr_Text l) =
177 Repr_Text $ \p v ->
178 let p' = precedence_App in
179 paren p p' $
180 "list_filter " <> f p' v <> ":" <> l p' v
181 instance Sym_Tuple2 (Repr_Text lam) where
182 tuple2 (Repr_Text a) (Repr_Text b) =
183 Repr_Text $ \_p v ->
184 let p' = precedence_Toplevel in
185 "(" <> a p' v <> ", " <> b p' v <> ")"
186 instance Monad lam => Sym_Map (Repr_Text lam) where
187 map_from_list (Repr_Text l) =
188 Repr_Text $ \_p v ->
189 let p' = precedence_App in
190 "map_from_list " <> l p' v
191 instance Monad lam => Sym_Map_Lam lam (Repr_Text lam) where
192 map_map (Repr_Text f) (Repr_Text m) =
193 Repr_Text $ \_p v ->
194 let p' = precedence_App in
195 "map_map " <> f p' v <> " " <> m p' v
196
197 -- ** Type 'Precedence'
198
199 newtype Precedence = Precedence Int
200 deriving (Eq, Ord, Show)
201 precedence_pred :: Precedence -> Precedence
202 precedence_pred (Precedence p) = Precedence (pred p)
203 precedence_succ :: Precedence -> Precedence
204 precedence_succ (Precedence p) = Precedence (succ p)
205 paren :: (Monoid s, IsString s) => Precedence -> Precedence -> s -> s
206 paren prec prec' x =
207 if prec >= prec'
208 then fromString "(" <> x <> fromString ")"
209 else x
210
211 precedence_Toplevel :: Precedence
212 precedence_Toplevel = Precedence 0
213 precedence_Lambda :: Precedence
214 precedence_Lambda = Precedence 1
215 precedence_If :: Precedence
216 precedence_If = Precedence 2
217 precedence_Let :: Precedence
218 precedence_Let = Precedence 3
219 precedence_Eq :: Precedence
220 precedence_Eq = Precedence 4
221 precedence_Or :: Precedence
222 precedence_Or = Precedence 5
223 precedence_Xor :: Precedence
224 precedence_Xor = precedence_Or
225 precedence_And :: Precedence
226 precedence_And = Precedence 6
227 precedence_Add :: Precedence
228 precedence_Add = precedence_And
229 precedence_Sub :: Precedence
230 precedence_Sub = precedence_Add
231 precedence_Mul :: Precedence
232 precedence_Mul = Precedence 7
233 precedence_Mod :: Precedence
234 precedence_Mod = precedence_Mul
235 precedence_App :: Precedence
236 precedence_App = Precedence 8
237 precedence_Not :: Precedence
238 precedence_Not = Precedence 9
239 precedence_Neg :: Precedence
240 precedence_Neg = precedence_Not
241 precedence_Atomic :: Precedence
242 precedence_Atomic = Precedence maxBound