PetScan::resolve_nested: handle self dependences in conditional assignments
[pet.git] / parse.c
blob114718112c32113f9c3f610ed358306c829181c1
1 /*
2 * Copyright 2011 Leiden University. All rights reserved.
3 * Copyright 2013 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 "expr.h"
39 #include "scop.h"
40 #include "scop_yaml.h"
42 static char *extract_string(isl_ctx *ctx, yaml_document_t *document,
43 yaml_node_t *node)
45 if (node->type != YAML_SCALAR_NODE)
46 isl_die(ctx, isl_error_invalid, "expecting scalar node",
47 return NULL);
49 return strdup((char *) node->data.scalar.value);
52 static int extract_int(isl_ctx *ctx, yaml_document_t *document,
53 yaml_node_t *node)
55 if (node->type != YAML_SCALAR_NODE)
56 isl_die(ctx, isl_error_invalid, "expecting scalar node",
57 return -1);
59 return atoi((char *) node->data.scalar.value);
62 static double extract_double(isl_ctx *ctx, yaml_document_t *document,
63 yaml_node_t *node)
65 if (node->type != YAML_SCALAR_NODE)
66 isl_die(ctx, isl_error_invalid, "expecting scalar node",
67 return -1);
69 return strtod((char *) node->data.scalar.value, NULL);
72 static enum pet_expr_type extract_expr_type(isl_ctx *ctx,
73 yaml_document_t *document, yaml_node_t *node)
75 if (node->type != YAML_SCALAR_NODE)
76 isl_die(ctx, isl_error_invalid, "expecting scalar node",
77 return -1);
79 return pet_str_type((char *) node->data.scalar.value);
82 static enum pet_op_type extract_op(isl_ctx *ctx, yaml_document_t *document,
83 yaml_node_t *node)
85 if (node->type != YAML_SCALAR_NODE)
86 isl_die(ctx, isl_error_invalid, "expecting scalar node",
87 return -1);
89 return pet_str_op((char *) node->data.scalar.value);
92 static __isl_give isl_set *extract_set(isl_ctx *ctx, yaml_document_t *document,
93 yaml_node_t *node)
95 if (node->type != YAML_SCALAR_NODE)
96 isl_die(ctx, isl_error_invalid, "expecting scalar node",
97 return NULL);
99 return isl_set_read_from_str(ctx, (char *) node->data.scalar.value);
102 static __isl_give isl_id *extract_id(isl_ctx *ctx, yaml_document_t *document,
103 yaml_node_t *node)
105 if (node->type != YAML_SCALAR_NODE)
106 isl_die(ctx, isl_error_invalid, "expecting scalar node",
107 return NULL);
109 return isl_id_alloc(ctx, (char *) node->data.scalar.value, NULL);
112 static __isl_give isl_map *extract_map(isl_ctx *ctx, yaml_document_t *document,
113 yaml_node_t *node)
115 if (node->type != YAML_SCALAR_NODE)
116 isl_die(ctx, isl_error_invalid, "expecting scalar node",
117 return NULL);
119 return isl_map_read_from_str(ctx, (char *) node->data.scalar.value);
122 /* Extract an isl_val from "node".
124 static __isl_give isl_val *extract_val(isl_ctx *ctx, yaml_document_t *document,
125 yaml_node_t *node)
127 if (node->type != YAML_SCALAR_NODE)
128 isl_die(ctx, isl_error_invalid, "expecting scalar node",
129 return NULL);
131 return isl_val_read_from_str(ctx, (char *) node->data.scalar.value);
134 /* Extract an isl_multi_pw_aff from "node".
136 static __isl_give isl_multi_pw_aff *extract_multi_pw_aff(isl_ctx *ctx,
137 yaml_document_t *document, yaml_node_t *node)
139 if (node->type != YAML_SCALAR_NODE)
140 isl_die(ctx, isl_error_invalid, "expecting scalar node",
141 return NULL);
143 return isl_multi_pw_aff_read_from_str(ctx,
144 (char *) node->data.scalar.value);
147 /* Extract a pet_type from "node".
149 static struct pet_type *extract_type(isl_ctx *ctx,
150 yaml_document_t *document, yaml_node_t *node)
152 struct pet_type *type;
153 yaml_node_pair_t * pair;
155 if (node->type != YAML_MAPPING_NODE)
156 isl_die(ctx, isl_error_invalid, "expecting mapping",
157 return NULL);
159 type = isl_calloc_type(ctx, struct pet_type);
160 if (!type)
161 return NULL;
163 for (pair = node->data.mapping.pairs.start;
164 pair < node->data.mapping.pairs.top; ++pair) {
165 yaml_node_t *key, *value;
167 key = yaml_document_get_node(document, pair->key);
168 value = yaml_document_get_node(document, pair->value);
170 if (key->type != YAML_SCALAR_NODE)
171 isl_die(ctx, isl_error_invalid, "expecting scalar key",
172 return pet_type_free(type));
174 if (!strcmp((char *) key->data.scalar.value, "name"))
175 type->name = extract_string(ctx, document, value);
176 if (!strcmp((char *) key->data.scalar.value, "definition"))
177 type->definition = extract_string(ctx, document, value);
180 return type;
183 /* Extract a sequence of types from "node" and store them in scop->types.
185 static struct pet_scop *extract_types(isl_ctx *ctx,
186 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
188 int i;
189 yaml_node_item_t *item;
191 if (node->type != YAML_SEQUENCE_NODE)
192 isl_die(ctx, isl_error_invalid, "expecting sequence",
193 return NULL);
195 scop->n_type = node->data.sequence.items.top
196 - node->data.sequence.items.start;
197 scop->types = isl_calloc_array(ctx, struct pet_type *, scop->n_type);
198 if (!scop->types)
199 return pet_scop_free(scop);
201 for (item = node->data.sequence.items.start, i = 0;
202 item < node->data.sequence.items.top; ++item, ++i) {
203 yaml_node_t *n;
205 n = yaml_document_get_node(document, *item);
206 scop->types[i] = extract_type(ctx, document, n);
207 if (!scop->types[i])
208 return pet_scop_free(scop);
211 return scop;
214 static struct pet_array *extract_array(isl_ctx *ctx, yaml_document_t *document,
215 yaml_node_t *node)
217 struct pet_array *array;
218 yaml_node_pair_t * pair;
220 if (node->type != YAML_MAPPING_NODE)
221 isl_die(ctx, isl_error_invalid, "expecting mapping",
222 return NULL);
224 array = isl_calloc_type(ctx, struct pet_array);
225 if (!array)
226 return NULL;
228 for (pair = node->data.mapping.pairs.start;
229 pair < node->data.mapping.pairs.top; ++pair) {
230 yaml_node_t *key, *value;
232 key = yaml_document_get_node(document, pair->key);
233 value = yaml_document_get_node(document, pair->value);
235 if (key->type != YAML_SCALAR_NODE)
236 isl_die(ctx, isl_error_invalid, "expecting scalar key",
237 return pet_array_free(array));
239 if (!strcmp((char *) key->data.scalar.value, "context"))
240 array->context = extract_set(ctx, document, value);
241 if (!strcmp((char *) key->data.scalar.value, "extent"))
242 array->extent = extract_set(ctx, document, value);
243 if (!strcmp((char *) key->data.scalar.value, "value_bounds"))
244 array->value_bounds = extract_set(ctx, document, value);
245 if (!strcmp((char *) key->data.scalar.value, "element_type"))
246 array->element_type =
247 extract_string(ctx, document, value);
248 if (!strcmp((char *) key->data.scalar.value, "element_size"))
249 array->element_size = extract_int(ctx, document, value);
250 if (!strcmp((char *) key->data.scalar.value,
251 "element_is_record"))
252 array->element_is_record =
253 extract_int(ctx, document, value);
254 if (!strcmp((char *) key->data.scalar.value, "live_out"))
255 array->live_out = extract_int(ctx, document, value);
256 if (!strcmp((char *) key->data.scalar.value,
257 "uniquely_defined"))
258 array->uniquely_defined =
259 extract_int(ctx, document, value);
260 if (!strcmp((char *) key->data.scalar.value, "declared"))
261 array->declared = extract_int(ctx, document, value);
262 if (!strcmp((char *) key->data.scalar.value, "exposed"))
263 array->exposed = extract_int(ctx, document, value);
266 return array;
269 static struct pet_scop *extract_arrays(isl_ctx *ctx, yaml_document_t *document,
270 yaml_node_t *node, struct pet_scop *scop)
272 int i;
273 yaml_node_item_t *item;
275 if (node->type != YAML_SEQUENCE_NODE)
276 isl_die(ctx, isl_error_invalid, "expecting sequence",
277 return NULL);
279 scop->n_array = node->data.sequence.items.top
280 - node->data.sequence.items.start;
281 scop->arrays = isl_calloc_array(ctx, struct pet_array *, scop->n_array);
282 if (!scop->arrays)
283 return pet_scop_free(scop);
285 for (item = node->data.sequence.items.start, i = 0;
286 item < node->data.sequence.items.top; ++item, ++i) {
287 yaml_node_t *n;
289 n = yaml_document_get_node(document, *item);
290 scop->arrays[i] = extract_array(ctx, document, n);
291 if (!scop->arrays[i])
292 return pet_scop_free(scop);
295 return scop;
298 static __isl_give pet_expr *extract_expr(isl_ctx *ctx,
299 yaml_document_t *document, yaml_node_t *node);
301 static __isl_give pet_expr *extract_arguments(isl_ctx *ctx,
302 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
304 int i, n;
305 yaml_node_item_t *item;
307 if (node->type != YAML_SEQUENCE_NODE)
308 isl_die(ctx, isl_error_invalid, "expecting sequence",
309 return pet_expr_free(expr));
311 n = node->data.sequence.items.top - node->data.sequence.items.start;
312 expr = pet_expr_set_n_arg(expr, n);
314 for (item = node->data.sequence.items.start, i = 0;
315 item < node->data.sequence.items.top; ++item, ++i) {
316 yaml_node_t *n;
317 pet_expr *arg;
319 n = yaml_document_get_node(document, *item);
320 arg = extract_expr(ctx, document, n);
321 expr = pet_expr_set_arg(expr, i, arg);
324 return expr;
327 /* Extract pet_expr_double specific fields from "node" and
328 * update "expr" accordingly.
330 static __isl_give pet_expr *extract_expr_double(isl_ctx *ctx,
331 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
333 yaml_node_pair_t *pair;
334 double d = 0;
335 char *s = NULL;
337 for (pair = node->data.mapping.pairs.start;
338 pair < node->data.mapping.pairs.top; ++pair) {
339 yaml_node_t *key, *value;
341 key = yaml_document_get_node(document, pair->key);
342 value = yaml_document_get_node(document, pair->value);
344 if (key->type != YAML_SCALAR_NODE)
345 isl_die(ctx, isl_error_invalid, "expecting scalar key",
346 return pet_expr_free(expr));
348 if (!strcmp((char *) key->data.scalar.value, "value"))
349 d = extract_double(ctx, document, value);
350 if (!strcmp((char *) key->data.scalar.value, "string"))
351 s = extract_string(ctx, document, value);
354 expr = pet_expr_double_set(expr, d, s);
355 free(s);
357 return expr;
360 /* Extract pet_expr_access specific fields from "node" and
361 * update "expr" accordingly.
363 static __isl_give pet_expr *extract_expr_access(isl_ctx *ctx,
364 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
366 yaml_node_pair_t *pair;
368 for (pair = node->data.mapping.pairs.start;
369 pair < node->data.mapping.pairs.top; ++pair) {
370 yaml_node_t *key, *value;
372 key = yaml_document_get_node(document, pair->key);
373 value = yaml_document_get_node(document, pair->value);
375 if (key->type != YAML_SCALAR_NODE)
376 isl_die(ctx, isl_error_invalid, "expecting scalar key",
377 return pet_expr_free(expr));
379 if (!strcmp((char *) key->data.scalar.value, "relation"))
380 expr = pet_expr_access_set_access(expr,
381 extract_map(ctx, document, value));
382 if (!strcmp((char *) key->data.scalar.value, "index"))
383 expr = pet_expr_access_set_index(expr,
384 extract_multi_pw_aff(ctx, document, value));
385 if (!strcmp((char *) key->data.scalar.value, "reference"))
386 expr = pet_expr_access_set_ref_id(expr,
387 extract_id(ctx, document, value));
388 if (!strcmp((char *) key->data.scalar.value, "read"))
389 expr = pet_expr_access_set_read(expr,
390 extract_int(ctx, document, value));
391 if (!strcmp((char *) key->data.scalar.value, "write"))
392 expr = pet_expr_access_set_write(expr,
393 extract_int(ctx, document, value));
396 return expr;
399 /* Extract operation expression specific fields from "node" and
400 * update "expr" accordingly.
402 static __isl_give pet_expr *extract_expr_op(isl_ctx *ctx,
403 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
405 yaml_node_pair_t *pair;
407 for (pair = node->data.mapping.pairs.start;
408 pair < node->data.mapping.pairs.top; ++pair) {
409 yaml_node_t *key, *value;
411 key = yaml_document_get_node(document, pair->key);
412 value = yaml_document_get_node(document, pair->value);
414 if (key->type != YAML_SCALAR_NODE)
415 isl_die(ctx, isl_error_invalid, "expecting scalar key",
416 return pet_expr_free(expr));
418 if (!strcmp((char *) key->data.scalar.value, "operation"))
419 expr = pet_expr_op_set_type(expr,
420 extract_op(ctx, document, value));
423 return expr;
426 /* Extract pet_expr_call specific fields from "node" and
427 * update "expr" accordingly.
429 static __isl_give pet_expr *extract_expr_call(isl_ctx *ctx,
430 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
432 yaml_node_pair_t *pair;
434 for (pair = node->data.mapping.pairs.start;
435 pair < node->data.mapping.pairs.top; ++pair) {
436 yaml_node_t *key, *value;
438 key = yaml_document_get_node(document, pair->key);
439 value = yaml_document_get_node(document, pair->value);
441 if (key->type != YAML_SCALAR_NODE)
442 isl_die(ctx, isl_error_invalid, "expecting scalar key",
443 return pet_expr_free(expr));
445 if (!strcmp((char *) key->data.scalar.value, "name"))
446 expr = pet_expr_call_set_name(expr,
447 extract_string(ctx, document, value));
450 return expr;
453 /* Extract pet_expr_cast specific fields from "node" and
454 * update "expr" accordingly.
456 static __isl_give pet_expr *extract_expr_cast(isl_ctx *ctx,
457 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
459 yaml_node_pair_t *pair;
461 for (pair = node->data.mapping.pairs.start;
462 pair < node->data.mapping.pairs.top; ++pair) {
463 yaml_node_t *key, *value;
465 key = yaml_document_get_node(document, pair->key);
466 value = yaml_document_get_node(document, pair->value);
468 if (key->type != YAML_SCALAR_NODE)
469 isl_die(ctx, isl_error_invalid, "expecting scalar key",
470 return pet_expr_free(expr));
472 if (!strcmp((char *) key->data.scalar.value, "type_name"))
473 expr = pet_expr_cast_set_type_name(expr,
474 extract_string(ctx, document, value));
477 return expr;
480 /* Extract pet_expr_int specific fields from "node" and
481 * update "expr" accordingly.
483 static __isl_give pet_expr *extract_expr_int(isl_ctx *ctx,
484 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
486 yaml_node_pair_t * pair;
488 for (pair = node->data.mapping.pairs.start;
489 pair < node->data.mapping.pairs.top; ++pair) {
490 yaml_node_t *key, *value;
492 key = yaml_document_get_node(document, pair->key);
493 value = yaml_document_get_node(document, pair->value);
495 if (key->type != YAML_SCALAR_NODE)
496 isl_die(ctx, isl_error_invalid, "expecting scalar key",
497 return pet_expr_free(expr));
499 if (!strcmp((char *) key->data.scalar.value, "value"))
500 expr = pet_expr_int_set_val(expr,
501 extract_val(ctx, document, value));
504 return expr;
507 /* Extract a pet_expr from "node".
509 * We first extract the type and arguments of the expression and
510 * then extract additional fields depending on the type.
512 static __isl_give pet_expr *extract_expr(isl_ctx *ctx,
513 yaml_document_t *document, yaml_node_t *node)
515 enum pet_expr_type type = pet_expr_error;
516 pet_expr *expr;
517 yaml_node_pair_t *pair;
519 if (node->type != YAML_MAPPING_NODE)
520 isl_die(ctx, isl_error_invalid, "expecting mapping",
521 return NULL);
523 for (pair = node->data.mapping.pairs.start;
524 pair < node->data.mapping.pairs.top; ++pair) {
525 yaml_node_t *key, *value;
527 key = yaml_document_get_node(document, pair->key);
528 value = yaml_document_get_node(document, pair->value);
530 if (key->type != YAML_SCALAR_NODE)
531 isl_die(ctx, isl_error_invalid, "expecting scalar key",
532 return pet_expr_free(expr));
534 if (!strcmp((char *) key->data.scalar.value, "type"))
535 type = extract_expr_type(ctx, document, value);
538 if (type == pet_expr_error)
539 isl_die(ctx, isl_error_invalid, "cannot determine type",
540 return NULL);
542 expr = pet_expr_alloc(ctx, type);
543 if (!expr)
544 return NULL;
546 for (pair = node->data.mapping.pairs.start;
547 pair < node->data.mapping.pairs.top; ++pair) {
548 yaml_node_t *key, *value;
550 key = yaml_document_get_node(document, pair->key);
551 value = yaml_document_get_node(document, pair->value);
553 if (!strcmp((char *) key->data.scalar.value, "arguments"))
554 expr = extract_arguments(ctx, document, value, expr);
555 if (!expr)
556 return NULL;
559 switch (type) {
560 case pet_expr_error:
561 isl_die(ctx, isl_error_internal, "unreachable code",
562 return NULL);
563 case pet_expr_access:
564 expr = extract_expr_access(ctx, document, node, expr);
565 break;
566 case pet_expr_double:
567 expr = extract_expr_double(ctx, document, node, expr);
568 break;
569 case pet_expr_call:
570 expr = extract_expr_call(ctx, document, node, expr);
571 break;
572 case pet_expr_cast:
573 expr = extract_expr_cast(ctx, document, node, expr);
574 break;
575 case pet_expr_int:
576 expr = extract_expr_int(ctx, document, node, expr);
577 break;
578 case pet_expr_op:
579 expr = extract_expr_op(ctx, document, node, expr);
580 break;
583 return expr;
586 static struct pet_stmt *extract_stmt_arguments(isl_ctx *ctx,
587 yaml_document_t *document, yaml_node_t *node, struct pet_stmt *stmt)
589 int i;
590 yaml_node_item_t *item;
592 if (node->type != YAML_SEQUENCE_NODE)
593 isl_die(ctx, isl_error_invalid, "expecting sequence",
594 return pet_stmt_free(stmt));
596 stmt->n_arg = node->data.sequence.items.top
597 - node->data.sequence.items.start;
598 stmt->args = isl_calloc_array(ctx, pet_expr *, stmt->n_arg);
599 if (!stmt->args)
600 return pet_stmt_free(stmt);
602 for (item = node->data.sequence.items.start, i = 0;
603 item < node->data.sequence.items.top; ++item, ++i) {
604 yaml_node_t *n;
606 n = yaml_document_get_node(document, *item);
607 stmt->args[i] = extract_expr(ctx, document, n);
608 if (!stmt->args[i])
609 return pet_stmt_free(stmt);
612 return stmt;
615 static struct pet_stmt *extract_stmt(isl_ctx *ctx, yaml_document_t *document,
616 yaml_node_t *node)
618 struct pet_stmt *stmt;
619 yaml_node_pair_t * pair;
621 if (node->type != YAML_MAPPING_NODE)
622 isl_die(ctx, isl_error_invalid, "expecting mapping",
623 return NULL);
625 stmt = isl_calloc_type(ctx, struct pet_stmt);
626 if (!stmt)
627 return NULL;
629 for (pair = node->data.mapping.pairs.start;
630 pair < node->data.mapping.pairs.top; ++pair) {
631 yaml_node_t *key, *value;
633 key = yaml_document_get_node(document, pair->key);
634 value = yaml_document_get_node(document, pair->value);
636 if (key->type != YAML_SCALAR_NODE)
637 isl_die(ctx, isl_error_invalid, "expecting scalar key",
638 return pet_stmt_free(stmt));
640 if (!strcmp((char *) key->data.scalar.value, "line"))
641 stmt->line = extract_int(ctx, document, value);
642 if (!strcmp((char *) key->data.scalar.value, "domain"))
643 stmt->domain = extract_set(ctx, document, value);
644 if (!strcmp((char *) key->data.scalar.value, "schedule"))
645 stmt->schedule = extract_map(ctx, document, value);
646 if (!strcmp((char *) key->data.scalar.value, "body"))
647 stmt->body = extract_expr(ctx, document, value);
649 if (!strcmp((char *) key->data.scalar.value, "arguments"))
650 stmt = extract_stmt_arguments(ctx, document,
651 value, stmt);
652 if (!stmt)
653 return NULL;
656 return stmt;
659 static struct pet_scop *extract_statements(isl_ctx *ctx,
660 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
662 int i;
663 yaml_node_item_t *item;
665 if (node->type != YAML_SEQUENCE_NODE)
666 isl_die(ctx, isl_error_invalid, "expecting sequence",
667 return NULL);
669 scop->n_stmt = node->data.sequence.items.top
670 - node->data.sequence.items.start;
671 scop->stmts = isl_calloc_array(ctx, struct pet_stmt *, scop->n_stmt);
672 if (!scop->stmts)
673 return pet_scop_free(scop);
675 for (item = node->data.sequence.items.start, i = 0;
676 item < node->data.sequence.items.top; ++item, ++i) {
677 yaml_node_t *n;
679 n = yaml_document_get_node(document, *item);
680 scop->stmts[i] = extract_stmt(ctx, document, n);
681 if (!scop->stmts[i])
682 return pet_scop_free(scop);
685 return scop;
688 /* Extract a pet_implication from "node".
690 static struct pet_implication *extract_implication(isl_ctx *ctx,
691 yaml_document_t *document, yaml_node_t *node)
693 struct pet_implication *implication;
694 yaml_node_pair_t * pair;
696 if (node->type != YAML_MAPPING_NODE)
697 isl_die(ctx, isl_error_invalid, "expecting mapping",
698 return NULL);
700 implication = isl_calloc_type(ctx, struct pet_implication);
701 if (!implication)
702 return NULL;
704 for (pair = node->data.mapping.pairs.start;
705 pair < node->data.mapping.pairs.top; ++pair) {
706 yaml_node_t *key, *value;
708 key = yaml_document_get_node(document, pair->key);
709 value = yaml_document_get_node(document, pair->value);
711 if (key->type != YAML_SCALAR_NODE)
712 isl_die(ctx, isl_error_invalid, "expecting scalar key",
713 return pet_implication_free(implication));
715 if (!strcmp((char *) key->data.scalar.value, "satisfied"))
716 implication->satisfied =
717 extract_int(ctx, document, value);
718 if (!strcmp((char *) key->data.scalar.value, "extension"))
719 implication->extension =
720 extract_map(ctx, document, value);
723 return implication;
726 /* Extract a sequence of implications from "node" and
727 * store them in scop->implications.
729 static struct pet_scop *extract_implications(isl_ctx *ctx,
730 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
732 int i;
733 yaml_node_item_t *item;
735 if (node->type != YAML_SEQUENCE_NODE)
736 isl_die(ctx, isl_error_invalid, "expecting sequence",
737 return NULL);
739 scop->n_implication = node->data.sequence.items.top
740 - node->data.sequence.items.start;
741 scop->implications = isl_calloc_array(ctx, struct pet_implication *,
742 scop->n_implication);
743 if (!scop->implications)
744 return pet_scop_free(scop);
746 for (item = node->data.sequence.items.start, i = 0;
747 item < node->data.sequence.items.top; ++item, ++i) {
748 yaml_node_t *n;
750 n = yaml_document_get_node(document, *item);
751 scop->implications[i] = extract_implication(ctx, document, n);
752 if (!scop->implications[i])
753 return pet_scop_free(scop);
756 return scop;
759 static struct pet_scop *extract_scop(isl_ctx *ctx, yaml_document_t *document,
760 yaml_node_t *node)
762 struct pet_scop *scop;
763 yaml_node_pair_t * pair;
765 if (!node)
766 return NULL;
768 if (node->type != YAML_MAPPING_NODE)
769 isl_die(ctx, isl_error_invalid, "expecting mapping",
770 return NULL);
772 scop = pet_scop_alloc(ctx);
773 if (!scop)
774 return NULL;
776 for (pair = node->data.mapping.pairs.start;
777 pair < node->data.mapping.pairs.top; ++pair) {
778 yaml_node_t *key, *value;
780 key = yaml_document_get_node(document, pair->key);
781 value = yaml_document_get_node(document, pair->value);
783 if (key->type != YAML_SCALAR_NODE)
784 isl_die(ctx, isl_error_invalid, "expecting scalar key",
785 return pet_scop_free(scop));
786 if (!strcmp((char *) key->data.scalar.value, "context"))
787 scop->context = extract_set(ctx, document, value);
788 if (!strcmp((char *) key->data.scalar.value, "context_value"))
789 scop->context_value = extract_set(ctx, document, value);
790 if (!strcmp((char *) key->data.scalar.value, "types"))
791 scop = extract_types(ctx, document, value, scop);
792 if (!strcmp((char *) key->data.scalar.value, "arrays"))
793 scop = extract_arrays(ctx, document, value, scop);
794 if (!strcmp((char *) key->data.scalar.value, "statements"))
795 scop = extract_statements(ctx, document, value, scop);
796 if (!strcmp((char *) key->data.scalar.value, "implications"))
797 scop = extract_implications(ctx, document, value, scop);
798 if (!scop)
799 return NULL;
802 if (!scop->context_value) {
803 isl_space *space = isl_space_params_alloc(ctx, 0);
804 scop->context_value = isl_set_universe(space);
805 if (!scop->context_value)
806 return pet_scop_free(scop);
809 return scop;
812 /* Extract a pet_scop from the YAML description in "in".
814 struct pet_scop *pet_scop_parse(isl_ctx *ctx, FILE *in)
816 struct pet_scop *scop = NULL;
817 yaml_parser_t parser;
818 yaml_node_t *root;
819 yaml_document_t document = { 0 };
821 yaml_parser_initialize(&parser);
823 yaml_parser_set_input_file(&parser, in);
825 if (!yaml_parser_load(&parser, &document))
826 goto error;
828 root = yaml_document_get_root_node(&document);
830 scop = extract_scop(ctx, &document, root);
832 yaml_document_delete(&document);
834 yaml_parser_delete(&parser);
836 return scop;
837 error:
838 yaml_parser_delete(&parser);
839 pet_scop_free(scop);
840 return NULL;