scop.c: extract out pet_stmt_is_affine_assume and pet_stmt_assume_get_index
[pet.git] / parse.c
blob3898fa57e35e79af193fa27818acd289f526553a
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 "loc.h"
40 #include "scop.h"
41 #include "scop_yaml.h"
43 static char *extract_string(isl_ctx *ctx, yaml_document_t *document,
44 yaml_node_t *node)
46 if (node->type != YAML_SCALAR_NODE)
47 isl_die(ctx, isl_error_invalid, "expecting scalar node",
48 return NULL);
50 return strdup((char *) node->data.scalar.value);
53 static int extract_int(isl_ctx *ctx, yaml_document_t *document,
54 yaml_node_t *node)
56 if (node->type != YAML_SCALAR_NODE)
57 isl_die(ctx, isl_error_invalid, "expecting scalar node",
58 return -1);
60 return atoi((char *) node->data.scalar.value);
63 static double extract_double(isl_ctx *ctx, yaml_document_t *document,
64 yaml_node_t *node)
66 if (node->type != YAML_SCALAR_NODE)
67 isl_die(ctx, isl_error_invalid, "expecting scalar node",
68 return -1);
70 return strtod((char *) node->data.scalar.value, NULL);
73 static enum pet_expr_type extract_expr_type(isl_ctx *ctx,
74 yaml_document_t *document, yaml_node_t *node)
76 if (node->type != YAML_SCALAR_NODE)
77 isl_die(ctx, isl_error_invalid, "expecting scalar node",
78 return -1);
80 return pet_str_type((char *) node->data.scalar.value);
83 static enum pet_op_type extract_op(isl_ctx *ctx, yaml_document_t *document,
84 yaml_node_t *node)
86 if (node->type != YAML_SCALAR_NODE)
87 isl_die(ctx, isl_error_invalid, "expecting scalar node",
88 return -1);
90 return pet_str_op((char *) node->data.scalar.value);
93 static __isl_give isl_set *extract_set(isl_ctx *ctx, yaml_document_t *document,
94 yaml_node_t *node)
96 if (node->type != YAML_SCALAR_NODE)
97 isl_die(ctx, isl_error_invalid, "expecting scalar node",
98 return NULL);
100 return isl_set_read_from_str(ctx, (char *) node->data.scalar.value);
103 static __isl_give isl_id *extract_id(isl_ctx *ctx, yaml_document_t *document,
104 yaml_node_t *node)
106 if (node->type != YAML_SCALAR_NODE)
107 isl_die(ctx, isl_error_invalid, "expecting scalar node",
108 return NULL);
110 return isl_id_alloc(ctx, (char *) node->data.scalar.value, NULL);
113 static __isl_give isl_map *extract_map(isl_ctx *ctx, yaml_document_t *document,
114 yaml_node_t *node)
116 if (node->type != YAML_SCALAR_NODE)
117 isl_die(ctx, isl_error_invalid, "expecting scalar node",
118 return NULL);
120 return isl_map_read_from_str(ctx, (char *) node->data.scalar.value);
123 /* Extract an isl_val from "node".
125 static __isl_give isl_val *extract_val(isl_ctx *ctx, yaml_document_t *document,
126 yaml_node_t *node)
128 if (node->type != YAML_SCALAR_NODE)
129 isl_die(ctx, isl_error_invalid, "expecting scalar node",
130 return NULL);
132 return isl_val_read_from_str(ctx, (char *) node->data.scalar.value);
135 /* Extract an isl_multi_pw_aff from "node".
137 static __isl_give isl_multi_pw_aff *extract_multi_pw_aff(isl_ctx *ctx,
138 yaml_document_t *document, yaml_node_t *node)
140 if (node->type != YAML_SCALAR_NODE)
141 isl_die(ctx, isl_error_invalid, "expecting scalar node",
142 return NULL);
144 return isl_multi_pw_aff_read_from_str(ctx,
145 (char *) node->data.scalar.value);
148 /* Extract a pet_type from "node".
150 static struct pet_type *extract_type(isl_ctx *ctx,
151 yaml_document_t *document, yaml_node_t *node)
153 struct pet_type *type;
154 yaml_node_pair_t * pair;
156 if (node->type != YAML_MAPPING_NODE)
157 isl_die(ctx, isl_error_invalid, "expecting mapping",
158 return NULL);
160 type = isl_calloc_type(ctx, struct pet_type);
161 if (!type)
162 return NULL;
164 for (pair = node->data.mapping.pairs.start;
165 pair < node->data.mapping.pairs.top; ++pair) {
166 yaml_node_t *key, *value;
168 key = yaml_document_get_node(document, pair->key);
169 value = yaml_document_get_node(document, pair->value);
171 if (key->type != YAML_SCALAR_NODE)
172 isl_die(ctx, isl_error_invalid, "expecting scalar key",
173 return pet_type_free(type));
175 if (!strcmp((char *) key->data.scalar.value, "name"))
176 type->name = extract_string(ctx, document, value);
177 if (!strcmp((char *) key->data.scalar.value, "definition"))
178 type->definition = extract_string(ctx, document, value);
181 return type;
184 /* Extract a sequence of types from "node" and store them in scop->types.
186 static struct pet_scop *extract_types(isl_ctx *ctx,
187 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
189 int i;
190 yaml_node_item_t *item;
192 if (node->type != YAML_SEQUENCE_NODE)
193 isl_die(ctx, isl_error_invalid, "expecting sequence",
194 return NULL);
196 scop->n_type = node->data.sequence.items.top
197 - node->data.sequence.items.start;
198 scop->types = isl_calloc_array(ctx, struct pet_type *, scop->n_type);
199 if (!scop->types)
200 return pet_scop_free(scop);
202 for (item = node->data.sequence.items.start, i = 0;
203 item < node->data.sequence.items.top; ++item, ++i) {
204 yaml_node_t *n;
206 n = yaml_document_get_node(document, *item);
207 scop->types[i] = extract_type(ctx, document, n);
208 if (!scop->types[i])
209 return pet_scop_free(scop);
212 return scop;
215 static struct pet_array *extract_array(isl_ctx *ctx, yaml_document_t *document,
216 yaml_node_t *node)
218 struct pet_array *array;
219 yaml_node_pair_t * pair;
221 if (node->type != YAML_MAPPING_NODE)
222 isl_die(ctx, isl_error_invalid, "expecting mapping",
223 return NULL);
225 array = isl_calloc_type(ctx, struct pet_array);
226 if (!array)
227 return NULL;
229 for (pair = node->data.mapping.pairs.start;
230 pair < node->data.mapping.pairs.top; ++pair) {
231 yaml_node_t *key, *value;
233 key = yaml_document_get_node(document, pair->key);
234 value = yaml_document_get_node(document, pair->value);
236 if (key->type != YAML_SCALAR_NODE)
237 isl_die(ctx, isl_error_invalid, "expecting scalar key",
238 return pet_array_free(array));
240 if (!strcmp((char *) key->data.scalar.value, "context"))
241 array->context = extract_set(ctx, document, value);
242 if (!strcmp((char *) key->data.scalar.value, "extent"))
243 array->extent = extract_set(ctx, document, value);
244 if (!strcmp((char *) key->data.scalar.value, "value_bounds"))
245 array->value_bounds = extract_set(ctx, document, value);
246 if (!strcmp((char *) key->data.scalar.value, "element_type"))
247 array->element_type =
248 extract_string(ctx, document, value);
249 if (!strcmp((char *) key->data.scalar.value, "element_size"))
250 array->element_size = extract_int(ctx, document, value);
251 if (!strcmp((char *) key->data.scalar.value,
252 "element_is_record"))
253 array->element_is_record =
254 extract_int(ctx, document, value);
255 if (!strcmp((char *) key->data.scalar.value, "live_out"))
256 array->live_out = extract_int(ctx, document, value);
257 if (!strcmp((char *) key->data.scalar.value,
258 "uniquely_defined"))
259 array->uniquely_defined =
260 extract_int(ctx, document, value);
261 if (!strcmp((char *) key->data.scalar.value, "declared"))
262 array->declared = extract_int(ctx, document, value);
263 if (!strcmp((char *) key->data.scalar.value, "exposed"))
264 array->exposed = extract_int(ctx, document, value);
267 return array;
270 static struct pet_scop *extract_arrays(isl_ctx *ctx, yaml_document_t *document,
271 yaml_node_t *node, struct pet_scop *scop)
273 int i;
274 yaml_node_item_t *item;
276 if (node->type != YAML_SEQUENCE_NODE)
277 isl_die(ctx, isl_error_invalid, "expecting sequence",
278 return NULL);
280 scop->n_array = node->data.sequence.items.top
281 - node->data.sequence.items.start;
282 scop->arrays = isl_calloc_array(ctx, struct pet_array *, scop->n_array);
283 if (!scop->arrays)
284 return pet_scop_free(scop);
286 for (item = node->data.sequence.items.start, i = 0;
287 item < node->data.sequence.items.top; ++item, ++i) {
288 yaml_node_t *n;
290 n = yaml_document_get_node(document, *item);
291 scop->arrays[i] = extract_array(ctx, document, n);
292 if (!scop->arrays[i])
293 return pet_scop_free(scop);
296 return scop;
299 static __isl_give pet_expr *extract_expr(isl_ctx *ctx,
300 yaml_document_t *document, yaml_node_t *node);
302 static __isl_give pet_expr *extract_arguments(isl_ctx *ctx,
303 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
305 int i, n;
306 yaml_node_item_t *item;
308 if (node->type != YAML_SEQUENCE_NODE)
309 isl_die(ctx, isl_error_invalid, "expecting sequence",
310 return pet_expr_free(expr));
312 n = node->data.sequence.items.top - node->data.sequence.items.start;
313 expr = pet_expr_set_n_arg(expr, n);
315 for (item = node->data.sequence.items.start, i = 0;
316 item < node->data.sequence.items.top; ++item, ++i) {
317 yaml_node_t *n;
318 pet_expr *arg;
320 n = yaml_document_get_node(document, *item);
321 arg = extract_expr(ctx, document, n);
322 expr = pet_expr_set_arg(expr, i, arg);
325 return expr;
328 /* Extract pet_expr_double specific fields from "node" and
329 * update "expr" accordingly.
331 static __isl_give pet_expr *extract_expr_double(isl_ctx *ctx,
332 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
334 yaml_node_pair_t *pair;
335 double d = 0;
336 char *s = NULL;
338 for (pair = node->data.mapping.pairs.start;
339 pair < node->data.mapping.pairs.top; ++pair) {
340 yaml_node_t *key, *value;
342 key = yaml_document_get_node(document, pair->key);
343 value = yaml_document_get_node(document, pair->value);
345 if (key->type != YAML_SCALAR_NODE)
346 isl_die(ctx, isl_error_invalid, "expecting scalar key",
347 return pet_expr_free(expr));
349 if (!strcmp((char *) key->data.scalar.value, "value"))
350 d = extract_double(ctx, document, value);
351 if (!strcmp((char *) key->data.scalar.value, "string"))
352 s = extract_string(ctx, document, value);
355 expr = pet_expr_double_set(expr, d, s);
356 free(s);
358 return expr;
361 /* Extract pet_expr_access specific fields from "node" and
362 * update "expr" accordingly.
364 static __isl_give pet_expr *extract_expr_access(isl_ctx *ctx,
365 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
367 yaml_node_pair_t *pair;
369 for (pair = node->data.mapping.pairs.start;
370 pair < node->data.mapping.pairs.top; ++pair) {
371 yaml_node_t *key, *value;
373 key = yaml_document_get_node(document, pair->key);
374 value = yaml_document_get_node(document, pair->value);
376 if (key->type != YAML_SCALAR_NODE)
377 isl_die(ctx, isl_error_invalid, "expecting scalar key",
378 return pet_expr_free(expr));
380 if (!strcmp((char *) key->data.scalar.value, "relation"))
381 expr = pet_expr_access_set_access(expr,
382 extract_map(ctx, document, value));
383 if (!strcmp((char *) key->data.scalar.value, "index"))
384 expr = pet_expr_access_set_index(expr,
385 extract_multi_pw_aff(ctx, document, value));
386 if (!strcmp((char *) key->data.scalar.value, "reference"))
387 expr = pet_expr_access_set_ref_id(expr,
388 extract_id(ctx, document, value));
389 if (!strcmp((char *) key->data.scalar.value, "read"))
390 expr = pet_expr_access_set_read(expr,
391 extract_int(ctx, document, value));
392 if (!strcmp((char *) key->data.scalar.value, "write"))
393 expr = pet_expr_access_set_write(expr,
394 extract_int(ctx, document, value));
397 return expr;
400 /* Extract operation expression specific fields from "node" and
401 * update "expr" accordingly.
403 static __isl_give pet_expr *extract_expr_op(isl_ctx *ctx,
404 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
406 yaml_node_pair_t *pair;
408 for (pair = node->data.mapping.pairs.start;
409 pair < node->data.mapping.pairs.top; ++pair) {
410 yaml_node_t *key, *value;
412 key = yaml_document_get_node(document, pair->key);
413 value = yaml_document_get_node(document, pair->value);
415 if (key->type != YAML_SCALAR_NODE)
416 isl_die(ctx, isl_error_invalid, "expecting scalar key",
417 return pet_expr_free(expr));
419 if (!strcmp((char *) key->data.scalar.value, "operation"))
420 expr = pet_expr_op_set_type(expr,
421 extract_op(ctx, document, value));
424 return expr;
427 /* Extract pet_expr_call specific fields from "node" and
428 * update "expr" accordingly.
430 static __isl_give pet_expr *extract_expr_call(isl_ctx *ctx,
431 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
433 yaml_node_pair_t *pair;
435 for (pair = node->data.mapping.pairs.start;
436 pair < node->data.mapping.pairs.top; ++pair) {
437 yaml_node_t *key, *value;
439 key = yaml_document_get_node(document, pair->key);
440 value = yaml_document_get_node(document, pair->value);
442 if (key->type != YAML_SCALAR_NODE)
443 isl_die(ctx, isl_error_invalid, "expecting scalar key",
444 return pet_expr_free(expr));
446 if (!strcmp((char *) key->data.scalar.value, "name"))
447 expr = pet_expr_call_set_name(expr,
448 extract_string(ctx, document, value));
451 return expr;
454 /* Extract pet_expr_cast specific fields from "node" and
455 * update "expr" accordingly.
457 static __isl_give pet_expr *extract_expr_cast(isl_ctx *ctx,
458 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
460 yaml_node_pair_t *pair;
462 for (pair = node->data.mapping.pairs.start;
463 pair < node->data.mapping.pairs.top; ++pair) {
464 yaml_node_t *key, *value;
466 key = yaml_document_get_node(document, pair->key);
467 value = yaml_document_get_node(document, pair->value);
469 if (key->type != YAML_SCALAR_NODE)
470 isl_die(ctx, isl_error_invalid, "expecting scalar key",
471 return pet_expr_free(expr));
473 if (!strcmp((char *) key->data.scalar.value, "type_name"))
474 expr = pet_expr_cast_set_type_name(expr,
475 extract_string(ctx, document, value));
478 return expr;
481 /* Extract pet_expr_int specific fields from "node" and
482 * update "expr" accordingly.
484 static __isl_give pet_expr *extract_expr_int(isl_ctx *ctx,
485 yaml_document_t *document, yaml_node_t *node, __isl_take pet_expr *expr)
487 yaml_node_pair_t * pair;
489 for (pair = node->data.mapping.pairs.start;
490 pair < node->data.mapping.pairs.top; ++pair) {
491 yaml_node_t *key, *value;
493 key = yaml_document_get_node(document, pair->key);
494 value = yaml_document_get_node(document, pair->value);
496 if (key->type != YAML_SCALAR_NODE)
497 isl_die(ctx, isl_error_invalid, "expecting scalar key",
498 return pet_expr_free(expr));
500 if (!strcmp((char *) key->data.scalar.value, "value"))
501 expr = pet_expr_int_set_val(expr,
502 extract_val(ctx, document, value));
505 return expr;
508 /* Extract a pet_expr from "node".
510 * We first extract the type and arguments of the expression and
511 * then extract additional fields depending on the type.
513 static __isl_give pet_expr *extract_expr(isl_ctx *ctx,
514 yaml_document_t *document, yaml_node_t *node)
516 enum pet_expr_type type = pet_expr_error;
517 pet_expr *expr;
518 yaml_node_pair_t *pair;
520 if (node->type != YAML_MAPPING_NODE)
521 isl_die(ctx, isl_error_invalid, "expecting mapping",
522 return NULL);
524 for (pair = node->data.mapping.pairs.start;
525 pair < node->data.mapping.pairs.top; ++pair) {
526 yaml_node_t *key, *value;
528 key = yaml_document_get_node(document, pair->key);
529 value = yaml_document_get_node(document, pair->value);
531 if (key->type != YAML_SCALAR_NODE)
532 isl_die(ctx, isl_error_invalid, "expecting scalar key",
533 return pet_expr_free(expr));
535 if (!strcmp((char *) key->data.scalar.value, "type"))
536 type = extract_expr_type(ctx, document, value);
539 if (type == pet_expr_error)
540 isl_die(ctx, isl_error_invalid, "cannot determine type",
541 return NULL);
543 expr = pet_expr_alloc(ctx, type);
544 if (!expr)
545 return NULL;
547 for (pair = node->data.mapping.pairs.start;
548 pair < node->data.mapping.pairs.top; ++pair) {
549 yaml_node_t *key, *value;
551 key = yaml_document_get_node(document, pair->key);
552 value = yaml_document_get_node(document, pair->value);
554 if (!strcmp((char *) key->data.scalar.value, "arguments"))
555 expr = extract_arguments(ctx, document, value, expr);
556 if (!expr)
557 return NULL;
560 switch (type) {
561 case pet_expr_error:
562 isl_die(ctx, isl_error_internal, "unreachable code",
563 return NULL);
564 case pet_expr_access:
565 expr = extract_expr_access(ctx, document, node, expr);
566 break;
567 case pet_expr_double:
568 expr = extract_expr_double(ctx, document, node, expr);
569 break;
570 case pet_expr_call:
571 expr = extract_expr_call(ctx, document, node, expr);
572 break;
573 case pet_expr_cast:
574 expr = extract_expr_cast(ctx, document, node, expr);
575 break;
576 case pet_expr_int:
577 expr = extract_expr_int(ctx, document, node, expr);
578 break;
579 case pet_expr_op:
580 expr = extract_expr_op(ctx, document, node, expr);
581 break;
584 return expr;
587 static struct pet_stmt *extract_stmt_arguments(isl_ctx *ctx,
588 yaml_document_t *document, yaml_node_t *node, struct pet_stmt *stmt)
590 int i;
591 yaml_node_item_t *item;
593 if (node->type != YAML_SEQUENCE_NODE)
594 isl_die(ctx, isl_error_invalid, "expecting sequence",
595 return pet_stmt_free(stmt));
597 stmt->n_arg = node->data.sequence.items.top
598 - node->data.sequence.items.start;
599 stmt->args = isl_calloc_array(ctx, pet_expr *, stmt->n_arg);
600 if (!stmt->args)
601 return pet_stmt_free(stmt);
603 for (item = node->data.sequence.items.start, i = 0;
604 item < node->data.sequence.items.top; ++item, ++i) {
605 yaml_node_t *n;
607 n = yaml_document_get_node(document, *item);
608 stmt->args[i] = extract_expr(ctx, document, n);
609 if (!stmt->args[i])
610 return pet_stmt_free(stmt);
613 return stmt;
616 static struct pet_stmt *extract_stmt(isl_ctx *ctx, yaml_document_t *document,
617 yaml_node_t *node)
619 struct pet_stmt *stmt;
620 yaml_node_pair_t * pair;
621 int line = -1;
622 unsigned start = 0, end = 0;
623 char *indent = NULL;
625 if (node->type != YAML_MAPPING_NODE)
626 isl_die(ctx, isl_error_invalid, "expecting mapping",
627 return NULL);
629 stmt = isl_calloc_type(ctx, struct pet_stmt);
630 if (!stmt)
631 return NULL;
633 stmt->loc = &pet_loc_dummy;
635 for (pair = node->data.mapping.pairs.start;
636 pair < node->data.mapping.pairs.top; ++pair) {
637 yaml_node_t *key, *value;
639 key = yaml_document_get_node(document, pair->key);
640 value = yaml_document_get_node(document, pair->value);
642 if (key->type != YAML_SCALAR_NODE)
643 isl_die(ctx, isl_error_invalid, "expecting scalar key",
644 return pet_stmt_free(stmt));
646 if (!strcmp((char *) key->data.scalar.value, "indent"))
647 indent = extract_string(ctx, document, value);
648 if (!strcmp((char *) key->data.scalar.value, "line"))
649 line = extract_int(ctx, document, value);
650 if (!strcmp((char *) key->data.scalar.value, "start"))
651 start = extract_int(ctx, document, value);
652 if (!strcmp((char *) key->data.scalar.value, "end"))
653 end = extract_int(ctx, document, value);
654 if (!strcmp((char *) key->data.scalar.value, "domain"))
655 stmt->domain = extract_set(ctx, document, value);
656 if (!strcmp((char *) key->data.scalar.value, "schedule"))
657 stmt->schedule = extract_map(ctx, document, value);
658 if (!strcmp((char *) key->data.scalar.value, "body"))
659 stmt->body = extract_expr(ctx, document, value);
661 if (!strcmp((char *) key->data.scalar.value, "arguments"))
662 stmt = extract_stmt_arguments(ctx, document,
663 value, stmt);
664 if (!stmt)
665 return NULL;
668 if (!indent)
669 indent = strdup("");
670 stmt->loc = pet_loc_alloc(ctx, start, end, line, indent);
671 if (!stmt->loc)
672 return pet_stmt_free(stmt);
674 return stmt;
677 static struct pet_scop *extract_statements(isl_ctx *ctx,
678 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
680 int i;
681 yaml_node_item_t *item;
683 if (node->type != YAML_SEQUENCE_NODE)
684 isl_die(ctx, isl_error_invalid, "expecting sequence",
685 return NULL);
687 scop->n_stmt = node->data.sequence.items.top
688 - node->data.sequence.items.start;
689 scop->stmts = isl_calloc_array(ctx, struct pet_stmt *, scop->n_stmt);
690 if (!scop->stmts)
691 return pet_scop_free(scop);
693 for (item = node->data.sequence.items.start, i = 0;
694 item < node->data.sequence.items.top; ++item, ++i) {
695 yaml_node_t *n;
697 n = yaml_document_get_node(document, *item);
698 scop->stmts[i] = extract_stmt(ctx, document, n);
699 if (!scop->stmts[i])
700 return pet_scop_free(scop);
703 return scop;
706 /* Extract a pet_implication from "node".
708 static struct pet_implication *extract_implication(isl_ctx *ctx,
709 yaml_document_t *document, yaml_node_t *node)
711 struct pet_implication *implication;
712 yaml_node_pair_t * pair;
714 if (node->type != YAML_MAPPING_NODE)
715 isl_die(ctx, isl_error_invalid, "expecting mapping",
716 return NULL);
718 implication = isl_calloc_type(ctx, struct pet_implication);
719 if (!implication)
720 return NULL;
722 for (pair = node->data.mapping.pairs.start;
723 pair < node->data.mapping.pairs.top; ++pair) {
724 yaml_node_t *key, *value;
726 key = yaml_document_get_node(document, pair->key);
727 value = yaml_document_get_node(document, pair->value);
729 if (key->type != YAML_SCALAR_NODE)
730 isl_die(ctx, isl_error_invalid, "expecting scalar key",
731 return pet_implication_free(implication));
733 if (!strcmp((char *) key->data.scalar.value, "satisfied"))
734 implication->satisfied =
735 extract_int(ctx, document, value);
736 if (!strcmp((char *) key->data.scalar.value, "extension"))
737 implication->extension =
738 extract_map(ctx, document, value);
741 return implication;
744 /* Extract a sequence of implications from "node" and
745 * store them in scop->implications.
747 static struct pet_scop *extract_implications(isl_ctx *ctx,
748 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
750 int i;
751 yaml_node_item_t *item;
753 if (node->type != YAML_SEQUENCE_NODE)
754 isl_die(ctx, isl_error_invalid, "expecting sequence",
755 return NULL);
757 scop->n_implication = node->data.sequence.items.top
758 - node->data.sequence.items.start;
759 scop->implications = isl_calloc_array(ctx, struct pet_implication *,
760 scop->n_implication);
761 if (!scop->implications)
762 return pet_scop_free(scop);
764 for (item = node->data.sequence.items.start, i = 0;
765 item < node->data.sequence.items.top; ++item, ++i) {
766 yaml_node_t *n;
768 n = yaml_document_get_node(document, *item);
769 scop->implications[i] = extract_implication(ctx, document, n);
770 if (!scop->implications[i])
771 return pet_scop_free(scop);
774 return scop;
777 static struct pet_scop *extract_scop(isl_ctx *ctx, yaml_document_t *document,
778 yaml_node_t *node)
780 struct pet_scop *scop;
781 yaml_node_pair_t * pair;
783 if (!node)
784 return NULL;
786 if (node->type != YAML_MAPPING_NODE)
787 isl_die(ctx, isl_error_invalid, "expecting mapping",
788 return NULL);
790 scop = pet_scop_alloc(ctx);
791 if (!scop)
792 return NULL;
794 for (pair = node->data.mapping.pairs.start;
795 pair < node->data.mapping.pairs.top; ++pair) {
796 yaml_node_t *key, *value;
798 key = yaml_document_get_node(document, pair->key);
799 value = yaml_document_get_node(document, pair->value);
801 if (key->type != YAML_SCALAR_NODE)
802 isl_die(ctx, isl_error_invalid, "expecting scalar key",
803 return pet_scop_free(scop));
804 if (!strcmp((char *) key->data.scalar.value, "context"))
805 scop->context = extract_set(ctx, document, value);
806 if (!strcmp((char *) key->data.scalar.value, "context_value"))
807 scop->context_value = extract_set(ctx, document, value);
808 if (!strcmp((char *) key->data.scalar.value, "types"))
809 scop = extract_types(ctx, document, value, scop);
810 if (!strcmp((char *) key->data.scalar.value, "arrays"))
811 scop = extract_arrays(ctx, document, value, scop);
812 if (!strcmp((char *) key->data.scalar.value, "statements"))
813 scop = extract_statements(ctx, document, value, scop);
814 if (!strcmp((char *) key->data.scalar.value, "implications"))
815 scop = extract_implications(ctx, document, value, scop);
816 if (!scop)
817 return NULL;
820 if (!scop->context_value) {
821 isl_space *space = isl_space_params_alloc(ctx, 0);
822 scop->context_value = isl_set_universe(space);
823 if (!scop->context_value)
824 return pet_scop_free(scop);
827 return scop;
830 /* Extract a pet_scop from the YAML description in "in".
832 struct pet_scop *pet_scop_parse(isl_ctx *ctx, FILE *in)
834 struct pet_scop *scop = NULL;
835 yaml_parser_t parser;
836 yaml_node_t *root;
837 yaml_document_t document = { 0 };
839 yaml_parser_initialize(&parser);
841 yaml_parser_set_input_file(&parser, in);
843 if (!yaml_parser_load(&parser, &document))
844 goto error;
846 root = yaml_document_get_root_node(&document);
848 scop = extract_scop(ctx, &document, root);
850 yaml_document_delete(&document);
852 yaml_parser_delete(&parser);
854 return scop;
855 error:
856 yaml_parser_delete(&parser);
857 pet_scop_free(scop);
858 return NULL;