pet_expr_dump_with_indent: also indent first line
[pet.git] / parse.c
blob68faab420abf505d96fa8598da964b3bc6c8d5bc
1 /*
2 * Copyright 2011 Leiden University. All rights reserved.
3 * Copyright 2013-2014 Ecole Normale Superieure. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY LEIDEN UNIVERSITY ''AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LEIDEN UNIVERSITY OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and documentation
30 * are those of the authors and should not be interpreted as
31 * representing official policies, either expressed or implied, of
32 * Leiden University.
33 */
35 #include <stdlib.h>
36 #include <yaml.h>
38 #include <isl/union_set.h>
40 #include "expr.h"
41 #include "loc.h"
42 #include "scop.h"
43 #include "scop_yaml.h"
44 #include "tree.h"
46 static char *extract_string(isl_ctx *ctx, yaml_document_t *document,
47 yaml_node_t *node)
49 if (node->type != YAML_SCALAR_NODE)
50 isl_die(ctx, isl_error_invalid, "expecting scalar node",
51 return NULL);
53 return strdup((char *) node->data.scalar.value);
56 static int extract_int(isl_ctx *ctx, yaml_document_t *document,
57 yaml_node_t *node)
59 if (node->type != YAML_SCALAR_NODE)
60 isl_die(ctx, isl_error_invalid, "expecting scalar node",
61 return -1);
63 return atoi((char *) node->data.scalar.value);
66 static double extract_double(isl_ctx *ctx, yaml_document_t *document,
67 yaml_node_t *node)
69 if (node->type != YAML_SCALAR_NODE)
70 isl_die(ctx, isl_error_invalid, "expecting scalar node",
71 return -1);
73 return strtod((char *) node->data.scalar.value, NULL);
76 static enum pet_expr_type extract_expr_type(isl_ctx *ctx,
77 yaml_document_t *document, yaml_node_t *node)
79 if (node->type != YAML_SCALAR_NODE)
80 isl_die(ctx, isl_error_invalid, "expecting scalar node",
81 return -1);
83 return pet_str_type((char *) node->data.scalar.value);
86 static enum pet_op_type extract_op(isl_ctx *ctx, yaml_document_t *document,
87 yaml_node_t *node)
89 if (node->type != YAML_SCALAR_NODE)
90 isl_die(ctx, isl_error_invalid, "expecting scalar node",
91 return -1);
93 return pet_str_op((char *) node->data.scalar.value);
96 static __isl_give isl_set *extract_set(isl_ctx *ctx, yaml_document_t *document,
97 yaml_node_t *node)
99 if (node->type != YAML_SCALAR_NODE)
100 isl_die(ctx, isl_error_invalid, "expecting scalar node",
101 return NULL);
103 return isl_set_read_from_str(ctx, (char *) node->data.scalar.value);
106 static __isl_give isl_id *extract_id(isl_ctx *ctx, yaml_document_t *document,
107 yaml_node_t *node)
109 if (node->type != YAML_SCALAR_NODE)
110 isl_die(ctx, isl_error_invalid, "expecting scalar node",
111 return NULL);
113 return isl_id_alloc(ctx, (char *) node->data.scalar.value, NULL);
116 static __isl_give isl_map *extract_map(isl_ctx *ctx, yaml_document_t *document,
117 yaml_node_t *node)
119 if (node->type != YAML_SCALAR_NODE)
120 isl_die(ctx, isl_error_invalid, "expecting scalar node",
121 return NULL);
123 return isl_map_read_from_str(ctx, (char *) node->data.scalar.value);
126 /* Extract an isl_union_set from "node".
128 static __isl_give isl_union_set *extract_union_set(isl_ctx *ctx,
129 yaml_document_t *document, yaml_node_t *node)
131 if (node->type != YAML_SCALAR_NODE)
132 isl_die(ctx, isl_error_invalid, "expecting scalar node",
133 return NULL);
135 return isl_union_set_read_from_str(ctx,
136 (char *) node->data.scalar.value);
139 /* Extract an isl_union_map from "node".
141 static __isl_give isl_union_map *extract_union_map(isl_ctx *ctx,
142 yaml_document_t *document, yaml_node_t *node)
144 if (node->type != YAML_SCALAR_NODE)
145 isl_die(ctx, isl_error_invalid, "expecting scalar node",
146 return NULL);
148 return isl_union_map_read_from_str(ctx,
149 (char *) node->data.scalar.value);
152 /* Extract an isl_val from "node".
154 static __isl_give isl_val *extract_val(isl_ctx *ctx, yaml_document_t *document,
155 yaml_node_t *node)
157 if (node->type != YAML_SCALAR_NODE)
158 isl_die(ctx, isl_error_invalid, "expecting scalar node",
159 return NULL);
161 return isl_val_read_from_str(ctx, (char *) node->data.scalar.value);
164 /* Extract an isl_multi_pw_aff from "node".
166 static __isl_give isl_multi_pw_aff *extract_multi_pw_aff(isl_ctx *ctx,
167 yaml_document_t *document, yaml_node_t *node)
169 if (node->type != YAML_SCALAR_NODE)
170 isl_die(ctx, isl_error_invalid, "expecting scalar node",
171 return NULL);
173 return isl_multi_pw_aff_read_from_str(ctx,
174 (char *) node->data.scalar.value);
177 /* Extract an isl_schedule from "node".
179 static __isl_give isl_schedule *extract_schedule(isl_ctx *ctx,
180 yaml_document_t *document, yaml_node_t *node)
182 if (node->type != YAML_SCALAR_NODE)
183 isl_die(ctx, isl_error_invalid, "expecting scalar node",
184 return NULL);
186 return isl_schedule_read_from_str(ctx,
187 (char *) node->data.scalar.value);
190 /* Extract a pet_type from "node".
192 static struct pet_type *extract_type(isl_ctx *ctx,
193 yaml_document_t *document, yaml_node_t *node)
195 struct pet_type *type;
196 yaml_node_pair_t * pair;
198 if (node->type != YAML_MAPPING_NODE)
199 isl_die(ctx, isl_error_invalid, "expecting mapping",
200 return NULL);
202 type = isl_calloc_type(ctx, struct pet_type);
203 if (!type)
204 return NULL;
206 for (pair = node->data.mapping.pairs.start;
207 pair < node->data.mapping.pairs.top; ++pair) {
208 yaml_node_t *key, *value;
210 key = yaml_document_get_node(document, pair->key);
211 value = yaml_document_get_node(document, pair->value);
213 if (key->type != YAML_SCALAR_NODE)
214 isl_die(ctx, isl_error_invalid, "expecting scalar key",
215 return pet_type_free(type));
217 if (!strcmp((char *) key->data.scalar.value, "name"))
218 type->name = extract_string(ctx, document, value);
219 if (!strcmp((char *) key->data.scalar.value, "definition"))
220 type->definition = extract_string(ctx, document, value);
223 return type;
226 /* Extract a sequence of types from "node" and store them in scop->types.
228 static struct pet_scop *extract_types(isl_ctx *ctx,
229 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
231 int i;
232 yaml_node_item_t *item;
234 if (node->type != YAML_SEQUENCE_NODE)
235 isl_die(ctx, isl_error_invalid, "expecting sequence",
236 return NULL);
238 scop->n_type = node->data.sequence.items.top
239 - node->data.sequence.items.start;
240 scop->types = isl_calloc_array(ctx, struct pet_type *, scop->n_type);
241 if (!scop->types)
242 return pet_scop_free(scop);
244 for (item = node->data.sequence.items.start, i = 0;
245 item < node->data.sequence.items.top; ++item, ++i) {
246 yaml_node_t *n;
248 n = yaml_document_get_node(document, *item);
249 scop->types[i] = extract_type(ctx, document, n);
250 if (!scop->types[i])
251 return pet_scop_free(scop);
254 return scop;
257 static struct pet_array *extract_array(isl_ctx *ctx, yaml_document_t *document,
258 yaml_node_t *node)
260 struct pet_array *array;
261 yaml_node_pair_t * pair;
263 if (node->type != YAML_MAPPING_NODE)
264 isl_die(ctx, isl_error_invalid, "expecting mapping",
265 return NULL);
267 array = isl_calloc_type(ctx, struct pet_array);
268 if (!array)
269 return NULL;
271 for (pair = node->data.mapping.pairs.start;
272 pair < node->data.mapping.pairs.top; ++pair) {
273 yaml_node_t *key, *value;
275 key = yaml_document_get_node(document, pair->key);
276 value = yaml_document_get_node(document, pair->value);
278 if (key->type != YAML_SCALAR_NODE)
279 isl_die(ctx, isl_error_invalid, "expecting scalar key",
280 return pet_array_free(array));
282 if (!strcmp((char *) key->data.scalar.value, "context"))
283 array->context = extract_set(ctx, document, value);
284 if (!strcmp((char *) key->data.scalar.value, "extent"))
285 array->extent = extract_set(ctx, document, value);
286 if (!strcmp((char *) key->data.scalar.value, "value_bounds"))
287 array->value_bounds = extract_set(ctx, document, value);
288 if (!strcmp((char *) key->data.scalar.value, "element_type"))
289 array->element_type =
290 extract_string(ctx, document, value);
291 if (!strcmp((char *) key->data.scalar.value, "element_size"))
292 array->element_size = extract_int(ctx, document, value);
293 if (!strcmp((char *) key->data.scalar.value,
294 "element_is_record"))
295 array->element_is_record =
296 extract_int(ctx, document, value);
297 if (!strcmp((char *) key->data.scalar.value, "live_out"))
298 array->live_out = extract_int(ctx, document, value);
299 if (!strcmp((char *) key->data.scalar.value,
300 "uniquely_defined"))
301 array->uniquely_defined =
302 extract_int(ctx, document, value);
303 if (!strcmp((char *) key->data.scalar.value, "declared"))
304 array->declared = extract_int(ctx, document, value);
305 if (!strcmp((char *) key->data.scalar.value, "exposed"))
306 array->exposed = extract_int(ctx, document, value);
309 return array;
312 static struct pet_scop *extract_arrays(isl_ctx *ctx, yaml_document_t *document,
313 yaml_node_t *node, struct pet_scop *scop)
315 int i;
316 yaml_node_item_t *item;
318 if (node->type != YAML_SEQUENCE_NODE)
319 isl_die(ctx, isl_error_invalid, "expecting sequence",
320 return NULL);
322 scop->n_array = node->data.sequence.items.top
323 - node->data.sequence.items.start;
324 scop->arrays = isl_calloc_array(ctx, struct pet_array *, scop->n_array);
325 if (!scop->arrays)
326 return pet_scop_free(scop);
328 for (item = node->data.sequence.items.start, i = 0;
329 item < node->data.sequence.items.top; ++item, ++i) {
330 yaml_node_t *n;
332 n = yaml_document_get_node(document, *item);
333 scop->arrays[i] = extract_array(ctx, document, n);
334 if (!scop->arrays[i])
335 return pet_scop_free(scop);
338 return scop;
341 static __isl_give pet_expr *extract_expr(isl_ctx *ctx,
342 yaml_document_t *document, yaml_node_t *node);
344 static __isl_give pet_expr *extract_arguments(isl_ctx *ctx,
345 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
347 int i, n;
348 yaml_node_item_t *item;
350 if (node->type != YAML_SEQUENCE_NODE)
351 isl_die(ctx, isl_error_invalid, "expecting sequence",
352 return pet_expr_free(expr));
354 n = node->data.sequence.items.top - node->data.sequence.items.start;
355 expr = pet_expr_set_n_arg(expr, n);
357 for (item = node->data.sequence.items.start, i = 0;
358 item < node->data.sequence.items.top; ++item, ++i) {
359 yaml_node_t *n;
360 pet_expr *arg;
362 n = yaml_document_get_node(document, *item);
363 arg = extract_expr(ctx, document, n);
364 expr = pet_expr_set_arg(expr, i, arg);
367 return expr;
370 /* Extract pet_expr_double specific fields from "node" and
371 * update "expr" accordingly.
373 static __isl_give pet_expr *extract_expr_double(isl_ctx *ctx,
374 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
376 yaml_node_pair_t *pair;
377 double d = 0;
378 char *s = NULL;
380 for (pair = node->data.mapping.pairs.start;
381 pair < node->data.mapping.pairs.top; ++pair) {
382 yaml_node_t *key, *value;
384 key = yaml_document_get_node(document, pair->key);
385 value = yaml_document_get_node(document, pair->value);
387 if (key->type != YAML_SCALAR_NODE)
388 isl_die(ctx, isl_error_invalid, "expecting scalar key",
389 return pet_expr_free(expr));
391 if (!strcmp((char *) key->data.scalar.value, "value"))
392 d = extract_double(ctx, document, value);
393 if (!strcmp((char *) key->data.scalar.value, "string"))
394 s = extract_string(ctx, document, value);
397 expr = pet_expr_double_set(expr, d, s);
398 free(s);
400 return expr;
403 /* Extract pet_expr_access specific fields from "node" and
404 * update "expr" accordingly.
406 * The depth of the access is initialized by pet_expr_access_set_index.
407 * Any explicitly specified depth therefore needs to be set after
408 * setting the index expression. Similiarly, the access relations (if any)
409 * need to be set after setting the depth.
411 static __isl_give pet_expr *extract_expr_access(isl_ctx *ctx,
412 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
414 yaml_node_pair_t *pair;
415 int depth = -1;
416 isl_multi_pw_aff *index = NULL;
418 for (pair = node->data.mapping.pairs.start;
419 pair < node->data.mapping.pairs.top; ++pair) {
420 yaml_node_t *key, *value;
422 key = yaml_document_get_node(document, pair->key);
423 value = yaml_document_get_node(document, pair->value);
425 if (key->type != YAML_SCALAR_NODE)
426 isl_die(ctx, isl_error_invalid, "expecting scalar key",
427 return pet_expr_free(expr));
429 if (!strcmp((char *) key->data.scalar.value, "index"))
430 index = extract_multi_pw_aff(ctx, document, value);
431 if (!strcmp((char *) key->data.scalar.value, "depth"))
432 depth = extract_int(ctx, document, value);
435 expr = pet_expr_access_set_index(expr, index);
436 if (depth >= 0)
437 expr = pet_expr_access_set_depth(expr, depth);
439 for (pair = node->data.mapping.pairs.start;
440 pair < node->data.mapping.pairs.top; ++pair) {
441 yaml_node_t *key, *value;
443 key = yaml_document_get_node(document, pair->key);
444 value = yaml_document_get_node(document, pair->value);
446 if (key->type != YAML_SCALAR_NODE)
447 isl_die(ctx, isl_error_invalid, "expecting scalar key",
448 return pet_expr_free(expr));
450 if (!strcmp((char *) key->data.scalar.value, "may_read"))
451 expr = pet_expr_access_set_access(expr,
452 pet_expr_access_may_read,
453 extract_union_map(ctx, document, value));
454 if (!strcmp((char *) key->data.scalar.value, "may_write"))
455 expr = pet_expr_access_set_access(expr,
456 pet_expr_access_may_write,
457 extract_union_map(ctx, document, value));
458 if (!strcmp((char *) key->data.scalar.value, "must_write"))
459 expr = pet_expr_access_set_access(expr,
460 pet_expr_access_must_write,
461 extract_union_map(ctx, document, value));
462 if (!strcmp((char *) key->data.scalar.value, "killed"))
463 expr = pet_expr_access_set_access(expr,
464 pet_expr_access_killed,
465 extract_union_map(ctx, document, value));
466 if (!strcmp((char *) key->data.scalar.value, "reference"))
467 expr = pet_expr_access_set_ref_id(expr,
468 extract_id(ctx, document, value));
469 if (!strcmp((char *) key->data.scalar.value, "read"))
470 expr = pet_expr_access_set_read(expr,
471 extract_int(ctx, document, value));
472 if (!strcmp((char *) key->data.scalar.value, "write"))
473 expr = pet_expr_access_set_write(expr,
474 extract_int(ctx, document, value));
475 if (!strcmp((char *) key->data.scalar.value, "kill"))
476 expr = pet_expr_access_set_kill(expr,
477 extract_int(ctx, document, value));
480 return expr;
483 /* Extract operation expression specific fields from "node" and
484 * update "expr" accordingly.
486 static __isl_give pet_expr *extract_expr_op(isl_ctx *ctx,
487 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
489 yaml_node_pair_t *pair;
491 for (pair = node->data.mapping.pairs.start;
492 pair < node->data.mapping.pairs.top; ++pair) {
493 yaml_node_t *key, *value;
495 key = yaml_document_get_node(document, pair->key);
496 value = yaml_document_get_node(document, pair->value);
498 if (key->type != YAML_SCALAR_NODE)
499 isl_die(ctx, isl_error_invalid, "expecting scalar key",
500 return pet_expr_free(expr));
502 if (!strcmp((char *) key->data.scalar.value, "operation"))
503 expr = pet_expr_op_set_type(expr,
504 extract_op(ctx, document, value));
507 return expr;
510 /* Extract pet_expr_call specific fields from "node" and
511 * update "expr" accordingly.
513 static __isl_give pet_expr *extract_expr_call(isl_ctx *ctx,
514 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
516 yaml_node_pair_t *pair;
518 for (pair = node->data.mapping.pairs.start;
519 pair < node->data.mapping.pairs.top; ++pair) {
520 yaml_node_t *key, *value;
522 key = yaml_document_get_node(document, pair->key);
523 value = yaml_document_get_node(document, pair->value);
525 if (key->type != YAML_SCALAR_NODE)
526 isl_die(ctx, isl_error_invalid, "expecting scalar key",
527 return pet_expr_free(expr));
529 if (!strcmp((char *) key->data.scalar.value, "name"))
530 expr = pet_expr_call_set_name(expr,
531 extract_string(ctx, document, value));
534 return expr;
537 /* Extract pet_expr_cast specific fields from "node" and
538 * update "expr" accordingly.
540 static __isl_give pet_expr *extract_expr_cast(isl_ctx *ctx,
541 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
543 yaml_node_pair_t *pair;
545 for (pair = node->data.mapping.pairs.start;
546 pair < node->data.mapping.pairs.top; ++pair) {
547 yaml_node_t *key, *value;
549 key = yaml_document_get_node(document, pair->key);
550 value = yaml_document_get_node(document, pair->value);
552 if (key->type != YAML_SCALAR_NODE)
553 isl_die(ctx, isl_error_invalid, "expecting scalar key",
554 return pet_expr_free(expr));
556 if (!strcmp((char *) key->data.scalar.value, "type_name"))
557 expr = pet_expr_cast_set_type_name(expr,
558 extract_string(ctx, document, value));
561 return expr;
564 /* Extract pet_expr_int specific fields from "node" and
565 * update "expr" accordingly.
567 static __isl_give pet_expr *extract_expr_int(isl_ctx *ctx,
568 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
570 yaml_node_pair_t * pair;
572 for (pair = node->data.mapping.pairs.start;
573 pair < node->data.mapping.pairs.top; ++pair) {
574 yaml_node_t *key, *value;
576 key = yaml_document_get_node(document, pair->key);
577 value = yaml_document_get_node(document, pair->value);
579 if (key->type != YAML_SCALAR_NODE)
580 isl_die(ctx, isl_error_invalid, "expecting scalar key",
581 return pet_expr_free(expr));
583 if (!strcmp((char *) key->data.scalar.value, "value"))
584 expr = pet_expr_int_set_val(expr,
585 extract_val(ctx, document, value));
588 return expr;
591 /* Extract a pet_expr from "node".
593 * We first extract the type and arguments of the expression and
594 * then extract additional fields depending on the type.
596 static __isl_give pet_expr *extract_expr(isl_ctx *ctx,
597 yaml_document_t *document, yaml_node_t *node)
599 enum pet_expr_type type = pet_expr_error;
600 pet_expr *expr;
601 yaml_node_pair_t *pair;
603 if (node->type != YAML_MAPPING_NODE)
604 isl_die(ctx, isl_error_invalid, "expecting mapping",
605 return NULL);
607 for (pair = node->data.mapping.pairs.start;
608 pair < node->data.mapping.pairs.top; ++pair) {
609 yaml_node_t *key, *value;
611 key = yaml_document_get_node(document, pair->key);
612 value = yaml_document_get_node(document, pair->value);
614 if (key->type != YAML_SCALAR_NODE)
615 isl_die(ctx, isl_error_invalid, "expecting scalar key",
616 return pet_expr_free(expr));
618 if (!strcmp((char *) key->data.scalar.value, "type"))
619 type = extract_expr_type(ctx, document, value);
622 if (type == pet_expr_error)
623 isl_die(ctx, isl_error_invalid, "cannot determine type",
624 return NULL);
626 expr = pet_expr_alloc(ctx, type);
627 if (!expr)
628 return NULL;
630 for (pair = node->data.mapping.pairs.start;
631 pair < node->data.mapping.pairs.top; ++pair) {
632 yaml_node_t *key, *value;
634 key = yaml_document_get_node(document, pair->key);
635 value = yaml_document_get_node(document, pair->value);
637 if (!strcmp((char *) key->data.scalar.value, "arguments"))
638 expr = extract_arguments(ctx, document, value, expr);
639 if (!expr)
640 return NULL;
643 switch (type) {
644 case pet_expr_error:
645 isl_die(ctx, isl_error_internal, "unreachable code",
646 return NULL);
647 case pet_expr_access:
648 expr = extract_expr_access(ctx, document, node, expr);
649 break;
650 case pet_expr_double:
651 expr = extract_expr_double(ctx, document, node, expr);
652 break;
653 case pet_expr_call:
654 expr = extract_expr_call(ctx, document, node, expr);
655 break;
656 case pet_expr_cast:
657 expr = extract_expr_cast(ctx, document, node, expr);
658 break;
659 case pet_expr_int:
660 expr = extract_expr_int(ctx, document, node, expr);
661 break;
662 case pet_expr_op:
663 expr = extract_expr_op(ctx, document, node, expr);
664 break;
667 return expr;
670 /* Extract a pet_tree_type from "node".
672 static enum pet_tree_type extract_tree_type(isl_ctx *ctx,
673 yaml_document_t *document, yaml_node_t *node)
675 if (node->type != YAML_SCALAR_NODE)
676 isl_die(ctx, isl_error_invalid, "expecting scalar node",
677 return -1);
679 return pet_tree_str_type((char *) node->data.scalar.value);
682 static __isl_give pet_tree *extract_tree(isl_ctx *ctx,
683 yaml_document_t *document, yaml_node_t *node);
685 /* Extract a pet_tree of type pet_tree_block from "node".
687 static __isl_give pet_tree *extract_tree_block(isl_ctx *ctx,
688 yaml_document_t *document, yaml_node_t *node)
690 int block = 0;
691 int i, n;
692 yaml_node_pair_t *pair;
693 yaml_node_item_t *item;
694 yaml_node_t *children = NULL;
695 pet_tree *tree;
697 for (pair = node->data.mapping.pairs.start;
698 pair < node->data.mapping.pairs.top; ++pair) {
699 yaml_node_t *key, *value;
701 key = yaml_document_get_node(document, pair->key);
702 value = yaml_document_get_node(document, pair->value);
704 if (key->type != YAML_SCALAR_NODE)
705 isl_die(ctx, isl_error_invalid, "expecting scalar key",
706 return NULL);
708 if (!strcmp((char *) key->data.scalar.value, "block"))
709 block = extract_int(ctx, document, value);
710 if (!strcmp((char *) key->data.scalar.value, "children"))
711 children = value;
714 if (!children)
715 n = 0;
716 else
717 n = children->data.sequence.items.top -
718 children->data.sequence.items.start;
720 tree = pet_tree_new_block(ctx, block, n);
721 if (!children)
722 return tree;
724 for (item = children->data.sequence.items.start, i = 0;
725 item < children->data.sequence.items.top; ++item, ++i) {
726 yaml_node_t *n;
727 pet_tree *child;
729 n = yaml_document_get_node(document, *item);
730 child = extract_tree(ctx, document, n);
731 tree = pet_tree_block_add_child(tree, child);
734 return tree;
737 /* Extract a pet_tree of type pet_tree_decl from "node".
739 static __isl_give pet_tree *extract_tree_decl(isl_ctx *ctx,
740 yaml_document_t *document, yaml_node_t *node)
742 yaml_node_pair_t *pair;
743 pet_expr *var = NULL;
745 for (pair = node->data.mapping.pairs.start;
746 pair < node->data.mapping.pairs.top; ++pair) {
747 yaml_node_t *key, *value;
749 key = yaml_document_get_node(document, pair->key);
750 value = yaml_document_get_node(document, pair->value);
752 if (key->type != YAML_SCALAR_NODE)
753 isl_die(ctx, isl_error_invalid, "expecting scalar key",
754 return NULL);
756 if (!strcmp((char *) key->data.scalar.value, "variable")) {
757 var = extract_expr(ctx, document, value);
758 if (!var)
759 return NULL;
763 if (!var)
764 isl_die(ctx, isl_error_invalid,
765 "no variable field", return NULL);
767 return pet_tree_new_decl(var);
770 /* Extract a pet_tree of type pet_tree_decl_init from "node".
772 static __isl_give pet_tree *extract_tree_decl_init(isl_ctx *ctx,
773 yaml_document_t *document, yaml_node_t *node)
775 yaml_node_pair_t *pair;
776 pet_expr *var = NULL;
777 pet_expr *init = NULL;
779 for (pair = node->data.mapping.pairs.start;
780 pair < node->data.mapping.pairs.top; ++pair) {
781 yaml_node_t *key, *value;
783 key = yaml_document_get_node(document, pair->key);
784 value = yaml_document_get_node(document, pair->value);
786 if (key->type != YAML_SCALAR_NODE)
787 isl_die(ctx, isl_error_invalid, "expecting scalar key",
788 return NULL);
790 if (!strcmp((char *) key->data.scalar.value, "variable")) {
791 var = extract_expr(ctx, document, value);
792 if (!var)
793 goto error;
795 if (!strcmp((char *) key->data.scalar.value,
796 "initialization")) {
797 init = extract_expr(ctx, document, value);
798 if (!init)
799 goto error;
803 if (!var)
804 isl_die(ctx, isl_error_invalid,
805 "no variable field", goto error);
806 if (!init)
807 isl_die(ctx, isl_error_invalid,
808 "no initialization field", goto error);
810 return pet_tree_new_decl_init(var, init);
811 error:
812 pet_expr_free(var);
813 pet_expr_free(init);
814 return NULL;
817 /* Extract a pet_tree of type pet_tree_expr from "node".
819 static __isl_give pet_tree *extract_tree_expr(isl_ctx *ctx,
820 yaml_document_t *document, yaml_node_t *node)
822 yaml_node_pair_t *pair;
823 pet_expr *expr = NULL;
825 for (pair = node->data.mapping.pairs.start;
826 pair < node->data.mapping.pairs.top; ++pair) {
827 yaml_node_t *key, *value;
829 key = yaml_document_get_node(document, pair->key);
830 value = yaml_document_get_node(document, pair->value);
832 if (key->type != YAML_SCALAR_NODE)
833 isl_die(ctx, isl_error_invalid, "expecting scalar key",
834 return NULL);
836 if (!strcmp((char *) key->data.scalar.value, "expr")) {
837 expr = extract_expr(ctx, document, value);
838 if (!expr)
839 return NULL;
843 if (!expr)
844 isl_die(ctx, isl_error_invalid,
845 "no expr field", return NULL);
847 return pet_tree_new_expr(expr);
850 /* Extract a pet_tree of type pet_tree_while from "node".
852 static __isl_give pet_tree *extract_tree_while(isl_ctx *ctx,
853 yaml_document_t *document, yaml_node_t *node)
855 yaml_node_pair_t *pair;
856 pet_expr *cond = NULL;
857 pet_tree *body = NULL;
859 for (pair = node->data.mapping.pairs.start;
860 pair < node->data.mapping.pairs.top; ++pair) {
861 yaml_node_t *key, *value;
863 key = yaml_document_get_node(document, pair->key);
864 value = yaml_document_get_node(document, pair->value);
866 if (key->type != YAML_SCALAR_NODE)
867 isl_die(ctx, isl_error_invalid, "expecting scalar key",
868 return NULL);
870 if (!strcmp((char *) key->data.scalar.value, "condition")) {
871 cond = extract_expr(ctx, document, value);
872 if (!cond)
873 goto error;
875 if (!strcmp((char *) key->data.scalar.value, "body")) {
876 body = extract_tree(ctx, document, value);
877 if (!body)
878 goto error;
882 if (!cond)
883 isl_die(ctx, isl_error_invalid,
884 "no condition field", goto error);
885 if (!body)
886 isl_die(ctx, isl_error_invalid,
887 "no body field", goto error);
889 return pet_tree_new_while(cond, body);
890 error:
891 pet_expr_free(cond);
892 pet_tree_free(body);
893 return NULL;
896 /* Extract a pet_tree of type pet_tree_infinite_loop from "node".
898 static __isl_give pet_tree *extract_tree_infinite_loop(isl_ctx *ctx,
899 yaml_document_t *document, yaml_node_t *node)
901 yaml_node_pair_t *pair;
902 pet_tree *body;
904 for (pair = node->data.mapping.pairs.start;
905 pair < node->data.mapping.pairs.top; ++pair) {
906 yaml_node_t *key, *value;
908 key = yaml_document_get_node(document, pair->key);
909 value = yaml_document_get_node(document, pair->value);
911 if (key->type != YAML_SCALAR_NODE)
912 isl_die(ctx, isl_error_invalid, "expecting scalar key",
913 return NULL);
915 if (!strcmp((char *) key->data.scalar.value, "body")) {
916 body = extract_tree(ctx, document, value);
917 if (!body)
918 return NULL;
922 if (!body)
923 isl_die(ctx, isl_error_invalid,
924 "no body field", return NULL);
926 return pet_tree_new_infinite_loop(body);
929 /* Extract a pet_tree of type pet_tree_if from "node".
931 static __isl_give pet_tree *extract_tree_if(isl_ctx *ctx,
932 yaml_document_t *document, yaml_node_t *node)
934 yaml_node_pair_t *pair;
935 pet_expr *cond = NULL;
936 pet_tree *then_body = NULL;
938 for (pair = node->data.mapping.pairs.start;
939 pair < node->data.mapping.pairs.top; ++pair) {
940 yaml_node_t *key, *value;
942 key = yaml_document_get_node(document, pair->key);
943 value = yaml_document_get_node(document, pair->value);
945 if (key->type != YAML_SCALAR_NODE)
946 isl_die(ctx, isl_error_invalid, "expecting scalar key",
947 return NULL);
949 if (!strcmp((char *) key->data.scalar.value, "condition")) {
950 cond = extract_expr(ctx, document, value);
951 if (!cond)
952 goto error;
954 if (!strcmp((char *) key->data.scalar.value, "then")) {
955 then_body = extract_tree(ctx, document, value);
956 if (!then_body)
957 goto error;
961 if (!cond)
962 isl_die(ctx, isl_error_invalid,
963 "no condition field", goto error);
964 if (!then_body)
965 isl_die(ctx, isl_error_invalid,
966 "no then body", goto error);
968 return pet_tree_new_if(cond, then_body);
969 error:
970 pet_expr_free(cond);
971 pet_tree_free(then_body);
972 return NULL;
975 /* Extract a pet_tree of type pet_tree_if_else from "node".
977 static __isl_give pet_tree *extract_tree_if_else(isl_ctx *ctx,
978 yaml_document_t *document, yaml_node_t *node)
980 yaml_node_pair_t *pair;
981 pet_expr *cond = NULL;
982 pet_tree *then_body = NULL;
983 pet_tree *else_body = NULL;
985 for (pair = node->data.mapping.pairs.start;
986 pair < node->data.mapping.pairs.top; ++pair) {
987 yaml_node_t *key, *value;
989 key = yaml_document_get_node(document, pair->key);
990 value = yaml_document_get_node(document, pair->value);
992 if (key->type != YAML_SCALAR_NODE)
993 isl_die(ctx, isl_error_invalid, "expecting scalar key",
994 return NULL);
996 if (!strcmp((char *) key->data.scalar.value, "condition")) {
997 cond = extract_expr(ctx, document, value);
998 if (!cond)
999 goto error;
1001 if (!strcmp((char *) key->data.scalar.value, "then")) {
1002 then_body = extract_tree(ctx, document, value);
1003 if (!then_body)
1004 goto error;
1006 if (!strcmp((char *) key->data.scalar.value, "else")) {
1007 else_body = extract_tree(ctx, document, value);
1008 if (!else_body)
1009 goto error;
1013 if (!cond)
1014 isl_die(ctx, isl_error_invalid,
1015 "no condition field", goto error);
1016 if (!then_body)
1017 isl_die(ctx, isl_error_invalid,
1018 "no then body", goto error);
1019 if (!else_body)
1020 isl_die(ctx, isl_error_invalid,
1021 "no else body", goto error);
1023 return pet_tree_new_if_else(cond, then_body, else_body);
1024 error:
1025 pet_expr_free(cond);
1026 pet_tree_free(then_body);
1027 pet_tree_free(else_body);
1028 return NULL;
1031 /* Extract a pet_tree of type pet_tree_for from "node".
1033 static __isl_give pet_tree *extract_tree_for(isl_ctx *ctx,
1034 yaml_document_t *document, yaml_node_t *node)
1036 yaml_node_pair_t *pair;
1037 int declared = 0;
1038 int independent = 0;
1039 pet_expr *iv = NULL;
1040 pet_expr *init = NULL;
1041 pet_expr *cond = NULL;
1042 pet_expr *inc = NULL;
1043 pet_tree *body = NULL;
1045 for (pair = node->data.mapping.pairs.start;
1046 pair < node->data.mapping.pairs.top; ++pair) {
1047 yaml_node_t *key, *value;
1049 key = yaml_document_get_node(document, pair->key);
1050 value = yaml_document_get_node(document, pair->value);
1052 if (key->type != YAML_SCALAR_NODE)
1053 isl_die(ctx, isl_error_invalid, "expecting scalar key",
1054 return NULL);
1056 if (!strcmp((char *) key->data.scalar.value, "declared"))
1057 declared = extract_int(ctx, document, value);
1058 if (!strcmp((char *) key->data.scalar.value, "independent"))
1059 independent = extract_int(ctx, document, value);
1060 if (!strcmp((char *) key->data.scalar.value, "variable")) {
1061 iv = extract_expr(ctx, document, value);
1062 if (!iv)
1063 goto error;
1065 if (!strcmp((char *) key->data.scalar.value,
1066 "initialization")) {
1067 init = extract_expr(ctx, document, value);
1068 if (!init)
1069 goto error;
1071 if (!strcmp((char *) key->data.scalar.value, "condition")) {
1072 cond = extract_expr(ctx, document, value);
1073 if (!cond)
1074 goto error;
1076 if (!strcmp((char *) key->data.scalar.value, "increment")) {
1077 inc = extract_expr(ctx, document, value);
1078 if (!inc)
1079 goto error;
1081 if (!strcmp((char *) key->data.scalar.value, "body")) {
1082 body = extract_tree(ctx, document, value);
1083 if (!body)
1084 goto error;
1088 if (!iv)
1089 isl_die(ctx, isl_error_invalid,
1090 "no variable field", goto error);
1091 if (!init)
1092 isl_die(ctx, isl_error_invalid,
1093 "no initialization field", goto error);
1094 if (!cond)
1095 isl_die(ctx, isl_error_invalid,
1096 "no condition field", goto error);
1097 if (!inc)
1098 isl_die(ctx, isl_error_invalid,
1099 "no increment field", goto error);
1100 if (!body)
1101 isl_die(ctx, isl_error_invalid,
1102 "no body field", goto error);
1104 return pet_tree_new_for(independent, declared, iv, init, cond, inc,
1105 body);
1106 error:
1107 pet_expr_free(iv);
1108 pet_expr_free(init);
1109 pet_expr_free(cond);
1110 pet_expr_free(inc);
1111 pet_tree_free(body);
1112 return NULL;
1115 /* Extract a pet_tree from "node".
1117 * We first extract the type of the pet_tree and then call
1118 * the appropriate function to extract and construct a pet_tree
1119 * of that type.
1121 static __isl_give pet_tree *extract_tree(isl_ctx *ctx,
1122 yaml_document_t *document, yaml_node_t *node)
1124 enum pet_tree_type type = pet_tree_error;
1125 pet_tree *tree;
1126 yaml_node_pair_t *pair;
1128 if (node->type != YAML_MAPPING_NODE)
1129 isl_die(ctx, isl_error_invalid, "expecting mapping",
1130 return NULL);
1132 for (pair = node->data.mapping.pairs.start;
1133 pair < node->data.mapping.pairs.top; ++pair) {
1134 yaml_node_t *key, *value;
1136 key = yaml_document_get_node(document, pair->key);
1137 value = yaml_document_get_node(document, pair->value);
1139 if (key->type != YAML_SCALAR_NODE)
1140 isl_die(ctx, isl_error_invalid, "expecting scalar key",
1141 return pet_tree_free(tree));
1143 if (!strcmp((char *) key->data.scalar.value, "type"))
1144 type = extract_tree_type(ctx, document, value);
1147 if (type == pet_tree_error)
1148 isl_die(ctx, isl_error_invalid, "cannot determine type",
1149 return NULL);
1151 switch (type) {
1152 case pet_tree_error:
1153 return NULL;
1154 case pet_tree_block:
1155 tree = extract_tree_block(ctx, document, node);
1156 break;
1157 case pet_tree_break:
1158 tree = pet_tree_new_break(ctx);
1159 break;
1160 case pet_tree_continue:
1161 tree = pet_tree_new_continue(ctx);
1162 break;
1163 case pet_tree_decl:
1164 tree = extract_tree_decl(ctx, document, node);
1165 break;
1166 case pet_tree_decl_init:
1167 tree = extract_tree_decl_init(ctx, document, node);
1168 break;
1169 case pet_tree_expr:
1170 tree = extract_tree_expr(ctx, document, node);
1171 break;
1172 case pet_tree_for:
1173 tree = extract_tree_for(ctx, document, node);
1174 break;
1175 case pet_tree_while:
1176 tree = extract_tree_while(ctx, document, node);
1177 break;
1178 case pet_tree_infinite_loop:
1179 tree = extract_tree_infinite_loop(ctx, document, node);
1180 break;
1181 case pet_tree_if:
1182 tree = extract_tree_if(ctx, document, node);
1183 break;
1184 case pet_tree_if_else:
1185 tree = extract_tree_if_else(ctx, document, node);
1186 break;
1189 return tree;
1192 static struct pet_stmt *extract_stmt_arguments(isl_ctx *ctx,
1193 yaml_document_t *document, yaml_node_t *node, struct pet_stmt *stmt)
1195 int i;
1196 yaml_node_item_t *item;
1198 if (node->type != YAML_SEQUENCE_NODE)
1199 isl_die(ctx, isl_error_invalid, "expecting sequence",
1200 return pet_stmt_free(stmt));
1202 stmt->n_arg = node->data.sequence.items.top
1203 - node->data.sequence.items.start;
1204 stmt->args = isl_calloc_array(ctx, pet_expr *, stmt->n_arg);
1205 if (!stmt->args)
1206 return pet_stmt_free(stmt);
1208 for (item = node->data.sequence.items.start, i = 0;
1209 item < node->data.sequence.items.top; ++item, ++i) {
1210 yaml_node_t *n;
1212 n = yaml_document_get_node(document, *item);
1213 stmt->args[i] = extract_expr(ctx, document, n);
1214 if (!stmt->args[i])
1215 return pet_stmt_free(stmt);
1218 return stmt;
1221 static struct pet_stmt *extract_stmt(isl_ctx *ctx, yaml_document_t *document,
1222 yaml_node_t *node)
1224 struct pet_stmt *stmt;
1225 yaml_node_pair_t * pair;
1226 int line = -1;
1227 unsigned start = 0, end = 0;
1228 char *indent = NULL;
1230 if (node->type != YAML_MAPPING_NODE)
1231 isl_die(ctx, isl_error_invalid, "expecting mapping",
1232 return NULL);
1234 stmt = isl_calloc_type(ctx, struct pet_stmt);
1235 if (!stmt)
1236 return NULL;
1238 stmt->loc = &pet_loc_dummy;
1240 for (pair = node->data.mapping.pairs.start;
1241 pair < node->data.mapping.pairs.top; ++pair) {
1242 yaml_node_t *key, *value;
1244 key = yaml_document_get_node(document, pair->key);
1245 value = yaml_document_get_node(document, pair->value);
1247 if (key->type != YAML_SCALAR_NODE)
1248 isl_die(ctx, isl_error_invalid, "expecting scalar key",
1249 return pet_stmt_free(stmt));
1251 if (!strcmp((char *) key->data.scalar.value, "indent"))
1252 indent = extract_string(ctx, document, value);
1253 if (!strcmp((char *) key->data.scalar.value, "line"))
1254 line = extract_int(ctx, document, value);
1255 if (!strcmp((char *) key->data.scalar.value, "start"))
1256 start = extract_int(ctx, document, value);
1257 if (!strcmp((char *) key->data.scalar.value, "end"))
1258 end = extract_int(ctx, document, value);
1259 if (!strcmp((char *) key->data.scalar.value, "domain"))
1260 stmt->domain = extract_set(ctx, document, value);
1261 if (!strcmp((char *) key->data.scalar.value, "body"))
1262 stmt->body = extract_tree(ctx, document, value);
1264 if (!strcmp((char *) key->data.scalar.value, "arguments"))
1265 stmt = extract_stmt_arguments(ctx, document,
1266 value, stmt);
1267 if (!stmt)
1268 return NULL;
1271 if (!indent)
1272 indent = strdup("");
1273 stmt->loc = pet_loc_alloc(ctx, start, end, line, indent);
1274 if (!stmt->loc)
1275 return pet_stmt_free(stmt);
1277 return stmt;
1280 static struct pet_scop *extract_statements(isl_ctx *ctx,
1281 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
1283 int i;
1284 yaml_node_item_t *item;
1286 if (node->type != YAML_SEQUENCE_NODE)
1287 isl_die(ctx, isl_error_invalid, "expecting sequence",
1288 return NULL);
1290 scop->n_stmt = node->data.sequence.items.top
1291 - node->data.sequence.items.start;
1292 scop->stmts = isl_calloc_array(ctx, struct pet_stmt *, scop->n_stmt);
1293 if (!scop->stmts)
1294 return pet_scop_free(scop);
1296 for (item = node->data.sequence.items.start, i = 0;
1297 item < node->data.sequence.items.top; ++item, ++i) {
1298 yaml_node_t *n;
1300 n = yaml_document_get_node(document, *item);
1301 scop->stmts[i] = extract_stmt(ctx, document, n);
1302 if (!scop->stmts[i])
1303 return pet_scop_free(scop);
1306 return scop;
1309 /* Extract a pet_implication from "node".
1311 static struct pet_implication *extract_implication(isl_ctx *ctx,
1312 yaml_document_t *document, yaml_node_t *node)
1314 struct pet_implication *implication;
1315 yaml_node_pair_t * pair;
1317 if (node->type != YAML_MAPPING_NODE)
1318 isl_die(ctx, isl_error_invalid, "expecting mapping",
1319 return NULL);
1321 implication = isl_calloc_type(ctx, struct pet_implication);
1322 if (!implication)
1323 return NULL;
1325 for (pair = node->data.mapping.pairs.start;
1326 pair < node->data.mapping.pairs.top; ++pair) {
1327 yaml_node_t *key, *value;
1329 key = yaml_document_get_node(document, pair->key);
1330 value = yaml_document_get_node(document, pair->value);
1332 if (key->type != YAML_SCALAR_NODE)
1333 isl_die(ctx, isl_error_invalid, "expecting scalar key",
1334 return pet_implication_free(implication));
1336 if (!strcmp((char *) key->data.scalar.value, "satisfied"))
1337 implication->satisfied =
1338 extract_int(ctx, document, value);
1339 if (!strcmp((char *) key->data.scalar.value, "extension"))
1340 implication->extension =
1341 extract_map(ctx, document, value);
1344 return implication;
1347 /* Extract a sequence of implications from "node" and
1348 * store them in scop->implications.
1350 static struct pet_scop *extract_implications(isl_ctx *ctx,
1351 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
1353 int i;
1354 yaml_node_item_t *item;
1356 if (node->type != YAML_SEQUENCE_NODE)
1357 isl_die(ctx, isl_error_invalid, "expecting sequence",
1358 return NULL);
1360 scop->n_implication = node->data.sequence.items.top
1361 - node->data.sequence.items.start;
1362 scop->implications = isl_calloc_array(ctx, struct pet_implication *,
1363 scop->n_implication);
1364 if (!scop->implications)
1365 return pet_scop_free(scop);
1367 for (item = node->data.sequence.items.start, i = 0;
1368 item < node->data.sequence.items.top; ++item, ++i) {
1369 yaml_node_t *n;
1371 n = yaml_document_get_node(document, *item);
1372 scop->implications[i] = extract_implication(ctx, document, n);
1373 if (!scop->implications[i])
1374 return pet_scop_free(scop);
1377 return scop;
1380 /* Extract a pet_independence from "node".
1382 static struct pet_independence *extract_independence(isl_ctx *ctx,
1383 yaml_document_t *document, yaml_node_t *node)
1385 struct pet_independence *independence;
1386 yaml_node_pair_t * pair;
1388 if (node->type != YAML_MAPPING_NODE)
1389 isl_die(ctx, isl_error_invalid, "expecting mapping",
1390 return NULL);
1392 independence = isl_calloc_type(ctx, struct pet_independence);
1393 if (!independence)
1394 return NULL;
1396 for (pair = node->data.mapping.pairs.start;
1397 pair < node->data.mapping.pairs.top; ++pair) {
1398 yaml_node_t *key, *value;
1400 key = yaml_document_get_node(document, pair->key);
1401 value = yaml_document_get_node(document, pair->value);
1403 if (key->type != YAML_SCALAR_NODE)
1404 isl_die(ctx, isl_error_invalid, "expecting scalar key",
1405 return pet_independence_free(independence));
1407 if (!strcmp((char *) key->data.scalar.value, "filter"))
1408 independence->filter =
1409 extract_union_map(ctx, document, value);
1410 if (!strcmp((char *) key->data.scalar.value, "local"))
1411 independence->local =
1412 extract_union_set(ctx, document, value);
1415 if (!independence->filter)
1416 isl_die(ctx, isl_error_invalid, "no filter field",
1417 return pet_independence_free(independence));
1418 if (!independence->local)
1419 isl_die(ctx, isl_error_invalid, "no local field",
1420 return pet_independence_free(independence));
1422 return independence;
1425 /* Extract a sequence of independences from "node" and
1426 * store them in scop->independences.
1428 static struct pet_scop *extract_independences(isl_ctx *ctx,
1429 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
1431 int i;
1432 yaml_node_item_t *item;
1434 if (node->type != YAML_SEQUENCE_NODE)
1435 isl_die(ctx, isl_error_invalid, "expecting sequence",
1436 return NULL);
1438 scop->n_independence = node->data.sequence.items.top
1439 - node->data.sequence.items.start;
1440 scop->independences = isl_calloc_array(ctx, struct pet_independence *,
1441 scop->n_independence);
1442 if (!scop->independences)
1443 return pet_scop_free(scop);
1445 for (item = node->data.sequence.items.start, i = 0;
1446 item < node->data.sequence.items.top; ++item, ++i) {
1447 yaml_node_t *n;
1449 n = yaml_document_get_node(document, *item);
1450 scop->independences[i] = extract_independence(ctx, document, n);
1451 if (!scop->independences[i])
1452 return pet_scop_free(scop);
1455 return scop;
1458 static struct pet_scop *extract_scop(isl_ctx *ctx, yaml_document_t *document,
1459 yaml_node_t *node)
1461 struct pet_scop *scop;
1462 yaml_node_pair_t * pair;
1464 if (!node)
1465 return NULL;
1467 if (node->type != YAML_MAPPING_NODE)
1468 isl_die(ctx, isl_error_invalid, "expecting mapping",
1469 return NULL);
1471 scop = pet_scop_alloc(ctx);
1472 if (!scop)
1473 return NULL;
1475 for (pair = node->data.mapping.pairs.start;
1476 pair < node->data.mapping.pairs.top; ++pair) {
1477 yaml_node_t *key, *value;
1479 key = yaml_document_get_node(document, pair->key);
1480 value = yaml_document_get_node(document, pair->value);
1482 if (key->type != YAML_SCALAR_NODE)
1483 isl_die(ctx, isl_error_invalid, "expecting scalar key",
1484 return pet_scop_free(scop));
1485 if (!strcmp((char *) key->data.scalar.value, "context"))
1486 scop->context = extract_set(ctx, document, value);
1487 if (!strcmp((char *) key->data.scalar.value, "context_value"))
1488 scop->context_value = extract_set(ctx, document, value);
1489 if (!strcmp((char *) key->data.scalar.value, "schedule"))
1490 scop->schedule = extract_schedule(ctx, document, value);
1491 if (!strcmp((char *) key->data.scalar.value, "types"))
1492 scop = extract_types(ctx, document, value, scop);
1493 if (!strcmp((char *) key->data.scalar.value, "arrays"))
1494 scop = extract_arrays(ctx, document, value, scop);
1495 if (!strcmp((char *) key->data.scalar.value, "statements"))
1496 scop = extract_statements(ctx, document, value, scop);
1497 if (!strcmp((char *) key->data.scalar.value, "implications"))
1498 scop = extract_implications(ctx, document, value, scop);
1499 if (!strcmp((char *) key->data.scalar.value, "independences"))
1500 scop = extract_independences(ctx,
1501 document, value, scop);
1502 if (!scop)
1503 return NULL;
1506 if (!scop->context_value) {
1507 isl_space *space = isl_space_params_alloc(ctx, 0);
1508 scop->context_value = isl_set_universe(space);
1509 if (!scop->context_value)
1510 return pet_scop_free(scop);
1513 return scop;
1516 /* Extract a pet_scop from the YAML description in "in".
1518 struct pet_scop *pet_scop_parse(isl_ctx *ctx, FILE *in)
1520 struct pet_scop *scop = NULL;
1521 yaml_parser_t parser;
1522 yaml_node_t *root;
1523 yaml_document_t document = { 0 };
1525 yaml_parser_initialize(&parser);
1527 yaml_parser_set_input_file(&parser, in);
1529 if (!yaml_parser_load(&parser, &document))
1530 goto error;
1532 root = yaml_document_get_root_node(&document);
1534 scop = extract_scop(ctx, &document, root);
1536 yaml_document_delete(&document);
1538 yaml_parser_delete(&parser);
1540 return scop;
1541 error:
1542 yaml_parser_delete(&parser);
1543 pet_scop_free(scop);
1544 return NULL;