-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsimple_printer.ml
More file actions
237 lines (215 loc) · 5.7 KB
/
simple_printer.ml
File metadata and controls
237 lines (215 loc) · 5.7 KB
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
module SimplePrinter : Pprinter.PPRINTER = struct
open Nix.Ast
let rec print chan = function
| BinaryOp(op, lhs, rhs) ->
print chan lhs; print_bop chan op; print chan rhs
| UnaryOp(op, e) ->
print_uop chan op; print chan e
| Cond(e1, e2, e3) ->
output_string chan "if ";
print chan e1;
output_string chan " then ";
print_paren chan e2;
output_string chan " else ";
print chan e3
| With(e1, e2) ->
output_string chan "with ";
print chan e1;
output_string chan "; ";
print chan e2
| Assert(e1, e2) ->
output_string chan "assert ";
print chan e1;
output_string chan "; ";
print chan e2
| Test(e1, attpath) ->
print chan e1;
output_string chan "? ";
separated_list chan ", " attpath
| Let(bindings, e) ->
output_string chan "let ";
List.iter (fun binding ->
print_binding chan binding;
output_char chan ' '
) bindings;
output_string chan " in ";
print chan e
| Val v ->
print_val chan v
| Id id ->
output_string chan id
| Select(e1, components, defval) ->
print_path_component chan e1;
List.iter (fun c ->
output_char chan '.';
print_path_component chan c
) components;
(
match defval with
| Some e ->
output_string chan " or ";
print_paren chan e
| None ->
()
)
| Apply(f, arg) ->
print chan f;
output_char chan ' ';
delimited chan "(" arg ")"
| Aquote e ->
delimited chan "${" e "}"
and print_paren chan e =
delimited chan "(" e ")"
and print_path_component chan = function
| (Val _) as e -> print chan e
| (Id _) as e -> print chan e
| e -> print_paren chan e
and print_bop chan op =
output_string chan (match op with
| Plus -> "+"
| Minus -> "-"
| Mult -> "*"
| Div -> "/"
| Gt -> ">"
| Lt -> "<"
| Lte -> "<="
| Gte -> ">="
| Eq -> "=="
| Neq -> "!="
| Or -> "||"
| And -> "&&"
| Impl -> "->"
| Merge -> "//"
| Concat -> "++"
)
and print_uop chan op =
output_char chan (match op with | Negate -> '-' | Not -> '-')
and print_val chan = function
| Str(s, mids) -> print_str chan (s, mids)
| IStr(i, s, mids) -> print_istr chan (i, s, mids)
| Int i -> output_string chan i
| Float f -> output_string chan f
| Path p -> output_string chan p
| SPath s -> output_string chan s
| HPath h -> output_string chan h
| Uri u -> output_string chan u
| Bool b -> output_string chan b
| Lambda(p, e) -> print_lam chan (p, e)
| List es ->
output_string chan "[";
List.iter (fun e -> output_char chan ' ';
print_paren chan e
) es;
output_string chan " ]"
| AttSet atts ->
output_string chan "{ ";
List.iter (fun att ->
print_binding chan att;
output_char chan ' '
) atts;
output_char chan '}'
| RecAttSet atts ->
output_string chan "rec { ";
List.iter (fun att ->
print_binding chan att;
output_char chan ' '
) atts;
output_char chan '}'
| Null ->
output_string chan "null"
and print_str chan (s, mids) =
output_char chan '"';
output_string chan s;
List.iter (fun (e, s) ->
output_string chan "${";
print chan e;
output_char chan '}';
output_string chan s
) mids;
output_char chan '"'
and print_istr chan (_, s, mids) =
output_string chan "''";
output_string chan s;
List.iter (fun (e, s) ->
output_string chan "${";
print chan e;
output_char chan '}';
output_string chan s
) mids;
output_string chan "''"
and print_lam chan (p, e) =
(match p with
| Alias x ->
output_string chan x
| ParamSet ps ->
output_char chan '{';
print_param_set chan ps;
output_char chan '}'
| AliasedSet (id, ps) ->
output_char chan '{';
print_param_set chan ps;
output_string chan "}@ ";
output_string chan id
);
output_string chan ": ";
print chan e
and print_param_set chan = function
| (head :: tail), Some () ->
print_param chan head;
List.iter (fun x ->
output_string chan ", ";
print_param chan x
) tail;
output_string chan ", ..."
| (head :: tail), None ->
print_param chan head;
List.iter (fun x ->
output_string chan ", ";
print_param chan x
) tail
| [], Some () ->
output_string chan "..."
| [], None ->
()
and print_param chan (id, maybe_expr) =
output_string chan id;
match maybe_expr with
| Some e ->
output_string chan "? ";
print chan e
| None -> ()
and print_binding chan = function
| AttrPath(es, e) ->
separated_list chan "." es;
output_string chan " = ";
print chan e;
output_char chan ';'
| Inherit(maybe_e, ids) ->
output_string chan "inherit ";
(
match maybe_e with
| Some e ->
print_paren chan e
| None -> ()
);
List.iter (fun x ->
output_char chan ' ';
output_string chan x
) ids;
output_char chan ';'
and delimited chan l e r =
output_string chan l;
print chan e;
output_string chan r
and separated_list chan sep xs =
match xs with
| head :: tail ->
print chan head;
List.iter (fun e ->
output_string chan sep;
print chan e
) tail
| [] ->
()
end
include SimplePrinter