pet 0.04
[pet.git] / emit.c
blob7f4bc6a5356037122ff4a1f23a33447a190ca434
1 /*
2 * Copyright 2011 Leiden University. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY LEIDEN UNIVERSITY ''AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LEIDEN UNIVERSITY OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * The views and conclusions contained in the software and documentation
29 * are those of the authors and should not be interpreted as
30 * representing official policies, either expressed or implied, of
31 * Leiden University.
32 */
34 #include <yaml.h>
36 #include "scop.h"
37 #include "scop_yaml.h"
39 static int emit_string(yaml_emitter_t *emitter, const char *str)
41 yaml_event_t event;
43 if (!yaml_scalar_event_initialize(&event, NULL, NULL,
44 (yaml_char_t *) str, strlen(str),
45 1, 1, YAML_PLAIN_SCALAR_STYLE))
46 return -1;
47 if (!yaml_emitter_emit(emitter, &event))
48 return -1;
50 return 0;
53 static int emit_int(yaml_emitter_t *emitter, int i)
55 char buffer[40];
57 snprintf(buffer, sizeof(buffer), "%d", i);
58 return emit_string(emitter, buffer);
61 static int emit_named_int(yaml_emitter_t *emitter, const char *name, int i)
63 if (emit_string(emitter, name) < 0)
64 return -1;
65 if (emit_int(emitter, i) < 0)
66 return -1;
67 return 0;
70 /* Print the unsigned integer "u" to "emitter".
72 static int emit_unsigned(yaml_emitter_t *emitter, unsigned u)
74 char buffer[40];
76 snprintf(buffer, sizeof(buffer), "%u", u);
77 return emit_string(emitter, buffer);
80 /* Print the string "name" and the unsigned integer "u" to "emitter".
82 static int emit_named_unsigned(yaml_emitter_t *emitter, const char *name,
83 unsigned u)
85 if (emit_string(emitter, name) < 0)
86 return -1;
87 if (emit_int(emitter, u) < 0)
88 return -1;
89 return 0;
92 static int emit_double(yaml_emitter_t *emitter, double d)
94 char buffer[40];
96 snprintf(buffer, sizeof(buffer), "%g", d);
97 return emit_string(emitter, buffer);
100 static int emit_map(yaml_emitter_t *emitter, __isl_keep isl_map *map)
102 isl_ctx *ctx = isl_map_get_ctx(map);
103 isl_printer *p;
104 char *str;
105 int r;
107 p = isl_printer_to_str(ctx);
108 p = isl_printer_print_map(p, map);
109 str = isl_printer_get_str(p);
110 isl_printer_free(p);
111 r = emit_string(emitter, str);
112 free(str);
113 return r;
116 static int emit_set(yaml_emitter_t *emitter, __isl_keep isl_set *set)
118 isl_ctx *ctx = isl_set_get_ctx(set);
119 isl_printer *p;
120 char *str;
121 int r;
123 p = isl_printer_to_str(ctx);
124 p = isl_printer_print_set(p, set);
125 str = isl_printer_get_str(p);
126 isl_printer_free(p);
127 r = emit_string(emitter, str);
128 free(str);
129 return r;
132 static int emit_named_set(yaml_emitter_t *emitter, const char *name,
133 __isl_keep isl_set *set)
135 if (emit_string(emitter, name) < 0)
136 return -1;
137 if (emit_set(emitter, set) < 0)
138 return -1;
139 return 0;
142 static int emit_array(yaml_emitter_t *emitter, struct pet_array *array)
144 yaml_event_t event;
146 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
147 YAML_BLOCK_MAPPING_STYLE))
148 return -1;
149 if (!yaml_emitter_emit(emitter, &event))
150 return -1;
152 if (emit_string(emitter, "context") < 0)
153 return -1;
154 if (emit_set(emitter, array->context) < 0)
155 return -1;
157 if (emit_string(emitter, "extent") < 0)
158 return -1;
159 if (emit_set(emitter, array->extent) < 0)
160 return -1;
162 if (array->value_bounds) {
163 if (emit_string(emitter, "value_bounds") < 0)
164 return -1;
165 if (emit_set(emitter, array->value_bounds) < 0)
166 return -1;
169 if (emit_string(emitter, "element_type") < 0)
170 return -1;
171 if (emit_string(emitter, array->element_type) < 0)
172 return -1;
173 if (emit_named_int(emitter, "element_size", array->element_size) < 0)
174 return -1;
176 if (array->live_out) {
177 if (emit_string(emitter, "live_out") < 0)
178 return -1;
179 if (emit_string(emitter, "1") < 0)
180 return -1;
183 if (array->uniquely_defined) {
184 if (emit_string(emitter, "uniquely_defined") < 0)
185 return -1;
186 if (emit_string(emitter, "1") < 0)
187 return -1;
190 if (array->declared && emit_named_int(emitter, "declared", 1) < 0)
191 return -1;
192 if (array->exposed && emit_named_int(emitter, "exposed", 1) < 0)
193 return -1;
195 if (!yaml_mapping_end_event_initialize(&event))
196 return -1;
197 if (!yaml_emitter_emit(emitter, &event))
198 return -1;
200 return 0;
203 static int emit_arrays(yaml_emitter_t *emitter, int n_array,
204 struct pet_array **arrays)
206 int i;
207 yaml_event_t event;
209 if (emit_string(emitter, "arrays") < 0)
210 return -1;
211 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
212 YAML_BLOCK_SEQUENCE_STYLE))
213 return -1;
214 if (!yaml_emitter_emit(emitter, &event))
215 return -1;
217 for (i = 0; i < n_array; ++i)
218 if (emit_array(emitter, arrays[i]) < 0)
219 return -1;
221 if (!yaml_sequence_end_event_initialize(&event))
222 return -1;
223 if (!yaml_emitter_emit(emitter, &event))
224 return -1;
226 return 0;
229 static int emit_type(yaml_emitter_t *emitter, enum pet_expr_type type)
231 if (emit_string(emitter, pet_type_str(type)) < 0)
232 return -1;
233 return 0;
236 static int emit_expr(yaml_emitter_t *emitter, struct pet_expr *expr)
238 yaml_event_t event;
240 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
241 YAML_BLOCK_MAPPING_STYLE))
242 return -1;
243 if (!yaml_emitter_emit(emitter, &event))
244 return -1;
246 if (emit_string(emitter, "type") < 0)
247 return -1;
248 if (emit_type(emitter, expr->type) < 0)
249 return -1;
251 switch (expr->type) {
252 case pet_expr_double:
253 if (emit_string(emitter, "value") < 0)
254 return -1;
255 if (emit_double(emitter, expr->d.val) < 0)
256 return -1;
257 if (emit_string(emitter, "string") < 0)
258 return -1;
259 if (emit_string(emitter, expr->d.s) < 0)
260 return -1;
261 break;
262 case pet_expr_access:
263 if (emit_string(emitter, "relation") < 0)
264 return -1;
265 if (emit_map(emitter, expr->acc.access) < 0)
266 return -1;
267 if (emit_string(emitter, "read") < 0)
268 return -1;
269 if (emit_int(emitter, expr->acc.read) < 0)
270 return -1;
271 if (emit_string(emitter, "write") < 0)
272 return -1;
273 if (emit_int(emitter, expr->acc.write) < 0)
274 return -1;
275 break;
276 case pet_expr_unary:
277 case pet_expr_binary:
278 if (emit_string(emitter, "operation") < 0)
279 return -1;
280 if (emit_string(emitter, pet_op_str(expr->op)) < 0)
281 return -1;
282 break;
283 case pet_expr_ternary:
284 break;
285 case pet_expr_call:
286 if (emit_string(emitter, "name") < 0)
287 return -1;
288 if (emit_string(emitter, expr->name) < 0)
289 return -1;
290 break;
291 case pet_expr_cast:
292 if (emit_string(emitter, "type_name") < 0)
293 return -1;
294 if (emit_string(emitter, expr->type_name) < 0)
295 return -1;
296 break;
299 if (expr->n_arg > 0) {
300 int i;
302 if (emit_string(emitter, "arguments") < 0)
303 return -1;
304 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
305 YAML_BLOCK_SEQUENCE_STYLE))
306 return -1;
307 if (!yaml_emitter_emit(emitter, &event))
308 return -1;
310 for (i = 0; i < expr->n_arg; ++i)
311 if (emit_expr(emitter, expr->args[i]) < 0)
312 return -1;
314 if (!yaml_sequence_end_event_initialize(&event))
315 return -1;
316 if (!yaml_emitter_emit(emitter, &event))
317 return -1;
320 if (!yaml_mapping_end_event_initialize(&event))
321 return -1;
322 if (!yaml_emitter_emit(emitter, &event))
323 return -1;
325 return 0;
328 static int emit_stmt(yaml_emitter_t *emitter, struct pet_stmt *stmt)
330 yaml_event_t event;
332 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
333 YAML_BLOCK_MAPPING_STYLE))
334 return -1;
335 if (!yaml_emitter_emit(emitter, &event))
336 return -1;
338 if (emit_string(emitter, "line") < 0)
339 return -1;
340 if (emit_int(emitter, stmt->line) < 0)
341 return -1;
343 if (emit_string(emitter, "domain") < 0)
344 return -1;
345 if (emit_set(emitter, stmt->domain) < 0)
346 return -1;
348 if (emit_string(emitter, "schedule") < 0)
349 return -1;
350 if (emit_map(emitter, stmt->schedule) < 0)
351 return -1;
353 if (emit_string(emitter, "body") < 0)
354 return -1;
355 if (emit_expr(emitter, stmt->body) < 0)
356 return -1;
358 if (stmt->n_arg > 0) {
359 int i;
361 if (emit_string(emitter, "arguments") < 0)
362 return -1;
363 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
364 YAML_BLOCK_SEQUENCE_STYLE))
365 return -1;
366 if (!yaml_emitter_emit(emitter, &event))
367 return -1;
369 for (i = 0; i < stmt->n_arg; ++i)
370 if (emit_expr(emitter, stmt->args[i]) < 0)
371 return -1;
373 if (!yaml_sequence_end_event_initialize(&event))
374 return -1;
375 if (!yaml_emitter_emit(emitter, &event))
376 return -1;
379 if (!yaml_mapping_end_event_initialize(&event))
380 return -1;
381 if (!yaml_emitter_emit(emitter, &event))
382 return -1;
384 return 0;
387 static int emit_statements(yaml_emitter_t *emitter, int n_stmt,
388 struct pet_stmt **stmts)
390 int i;
391 yaml_event_t event;
393 if (emit_string(emitter, "statements") < 0)
394 return -1;
395 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
396 YAML_BLOCK_SEQUENCE_STYLE))
397 return -1;
398 if (!yaml_emitter_emit(emitter, &event))
399 return -1;
401 for (i = 0; i < n_stmt; ++i)
402 if (emit_stmt(emitter, stmts[i]) < 0)
403 return -1;
405 if (!yaml_sequence_end_event_initialize(&event))
406 return -1;
407 if (!yaml_emitter_emit(emitter, &event))
408 return -1;
410 return 0;
413 static int emit_scop(yaml_emitter_t *emitter, struct pet_scop *scop)
415 yaml_event_t event;
417 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
418 YAML_BLOCK_MAPPING_STYLE))
419 return -1;
420 if (!yaml_emitter_emit(emitter, &event))
421 return -1;
423 if (emit_named_unsigned(emitter, "start", scop->start) < 0)
424 return -1;
425 if (emit_named_unsigned(emitter, "end", scop->end) < 0)
426 return -1;
427 if (emit_string(emitter, "context") < 0)
428 return -1;
429 if (emit_set(emitter, scop->context) < 0)
430 return -1;
431 if (!isl_set_plain_is_universe(scop->context_value) &&
432 emit_named_set(emitter, "context_value", scop->context_value) < 0)
433 return -1;
435 if (emit_arrays(emitter, scop->n_array, scop->arrays) < 0)
436 return -1;
438 if (emit_statements(emitter, scop->n_stmt, scop->stmts) < 0)
439 return -1;
441 if (!yaml_mapping_end_event_initialize(&event))
442 return -1;
443 if (!yaml_emitter_emit(emitter, &event))
444 return -1;
446 return 0;
449 /* Print a YAML serialization of "scop" to "out".
451 int pet_scop_emit(FILE *out, struct pet_scop *scop)
453 yaml_emitter_t emitter;
454 yaml_event_t event;
456 yaml_emitter_initialize(&emitter);
458 yaml_emitter_set_output_file(&emitter, out);
460 yaml_stream_start_event_initialize(&event, YAML_UTF8_ENCODING);
461 if (!yaml_emitter_emit(&emitter, &event))
462 goto error;
464 if (!yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 1))
465 goto error;
466 if (!yaml_emitter_emit(&emitter, &event))
467 goto error;
469 if (emit_scop(&emitter, scop) < 0)
470 goto error;
472 if (!yaml_document_end_event_initialize(&event, 1))
473 goto error;
474 if (!yaml_emitter_emit(&emitter, &event))
475 goto error;
477 yaml_stream_end_event_initialize(&event);
478 if (!yaml_emitter_emit(&emitter, &event))
479 goto error;
481 yaml_emitter_delete(&emitter);
482 return 0;
483 error:
484 yaml_emitter_delete(&emitter);
485 return -1;