PetScan::extract_scop: populate pet_context with parameter assignments
[pet.git] / parse.c
blob8b6b36ff8059363d1855fb536ee8a1146516a6ed
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;
624 if (node->type != YAML_MAPPING_NODE)
625 isl_die(ctx, isl_error_invalid, "expecting mapping",
626 return NULL);
628 stmt = isl_calloc_type(ctx, struct pet_stmt);
629 if (!stmt)
630 return NULL;
632 stmt->loc = &pet_loc_dummy;
634 for (pair = node->data.mapping.pairs.start;
635 pair < node->data.mapping.pairs.top; ++pair) {
636 yaml_node_t *key, *value;
638 key = yaml_document_get_node(document, pair->key);
639 value = yaml_document_get_node(document, pair->value);
641 if (key->type != YAML_SCALAR_NODE)
642 isl_die(ctx, isl_error_invalid, "expecting scalar key",
643 return pet_stmt_free(stmt));
645 if (!strcmp((char *) key->data.scalar.value, "line"))
646 line = extract_int(ctx, document, value);
647 if (!strcmp((char *) key->data.scalar.value, "start"))
648 start = extract_int(ctx, document, value);
649 if (!strcmp((char *) key->data.scalar.value, "end"))
650 end = extract_int(ctx, document, value);
651 if (!strcmp((char *) key->data.scalar.value, "domain"))
652 stmt->domain = extract_set(ctx, document, value);
653 if (!strcmp((char *) key->data.scalar.value, "schedule"))
654 stmt->schedule = extract_map(ctx, document, value);
655 if (!strcmp((char *) key->data.scalar.value, "body"))
656 stmt->body = extract_expr(ctx, document, value);
658 if (!strcmp((char *) key->data.scalar.value, "arguments"))
659 stmt = extract_stmt_arguments(ctx, document,
660 value, stmt);
661 if (!stmt)
662 return NULL;
665 stmt->loc = pet_loc_alloc(ctx, start, end, line);
666 if (!stmt->loc)
667 return pet_stmt_free(stmt);
669 return stmt;
672 static struct pet_scop *extract_statements(isl_ctx *ctx,
673 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
675 int i;
676 yaml_node_item_t *item;
678 if (node->type != YAML_SEQUENCE_NODE)
679 isl_die(ctx, isl_error_invalid, "expecting sequence",
680 return NULL);
682 scop->n_stmt = node->data.sequence.items.top
683 - node->data.sequence.items.start;
684 scop->stmts = isl_calloc_array(ctx, struct pet_stmt *, scop->n_stmt);
685 if (!scop->stmts)
686 return pet_scop_free(scop);
688 for (item = node->data.sequence.items.start, i = 0;
689 item < node->data.sequence.items.top; ++item, ++i) {
690 yaml_node_t *n;
692 n = yaml_document_get_node(document, *item);
693 scop->stmts[i] = extract_stmt(ctx, document, n);
694 if (!scop->stmts[i])
695 return pet_scop_free(scop);
698 return scop;
701 /* Extract a pet_implication from "node".
703 static struct pet_implication *extract_implication(isl_ctx *ctx,
704 yaml_document_t *document, yaml_node_t *node)
706 struct pet_implication *implication;
707 yaml_node_pair_t * pair;
709 if (node->type != YAML_MAPPING_NODE)
710 isl_die(ctx, isl_error_invalid, "expecting mapping",
711 return NULL);
713 implication = isl_calloc_type(ctx, struct pet_implication);
714 if (!implication)
715 return NULL;
717 for (pair = node->data.mapping.pairs.start;
718 pair < node->data.mapping.pairs.top; ++pair) {
719 yaml_node_t *key, *value;
721 key = yaml_document_get_node(document, pair->key);
722 value = yaml_document_get_node(document, pair->value);
724 if (key->type != YAML_SCALAR_NODE)
725 isl_die(ctx, isl_error_invalid, "expecting scalar key",
726 return pet_implication_free(implication));
728 if (!strcmp((char *) key->data.scalar.value, "satisfied"))
729 implication->satisfied =
730 extract_int(ctx, document, value);
731 if (!strcmp((char *) key->data.scalar.value, "extension"))
732 implication->extension =
733 extract_map(ctx, document, value);
736 return implication;
739 /* Extract a sequence of implications from "node" and
740 * store them in scop->implications.
742 static struct pet_scop *extract_implications(isl_ctx *ctx,
743 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
745 int i;
746 yaml_node_item_t *item;
748 if (node->type != YAML_SEQUENCE_NODE)
749 isl_die(ctx, isl_error_invalid, "expecting sequence",
750 return NULL);
752 scop->n_implication = node->data.sequence.items.top
753 - node->data.sequence.items.start;
754 scop->implications = isl_calloc_array(ctx, struct pet_implication *,
755 scop->n_implication);
756 if (!scop->implications)
757 return pet_scop_free(scop);
759 for (item = node->data.sequence.items.start, i = 0;
760 item < node->data.sequence.items.top; ++item, ++i) {
761 yaml_node_t *n;
763 n = yaml_document_get_node(document, *item);
764 scop->implications[i] = extract_implication(ctx, document, n);
765 if (!scop->implications[i])
766 return pet_scop_free(scop);
769 return scop;
772 static struct pet_scop *extract_scop(isl_ctx *ctx, yaml_document_t *document,
773 yaml_node_t *node)
775 struct pet_scop *scop;
776 yaml_node_pair_t * pair;
778 if (!node)
779 return NULL;
781 if (node->type != YAML_MAPPING_NODE)
782 isl_die(ctx, isl_error_invalid, "expecting mapping",
783 return NULL);
785 scop = pet_scop_alloc(ctx);
786 if (!scop)
787 return NULL;
789 for (pair = node->data.mapping.pairs.start;
790 pair < node->data.mapping.pairs.top; ++pair) {
791 yaml_node_t *key, *value;
793 key = yaml_document_get_node(document, pair->key);
794 value = yaml_document_get_node(document, pair->value);
796 if (key->type != YAML_SCALAR_NODE)
797 isl_die(ctx, isl_error_invalid, "expecting scalar key",
798 return pet_scop_free(scop));
799 if (!strcmp((char *) key->data.scalar.value, "context"))
800 scop->context = extract_set(ctx, document, value);
801 if (!strcmp((char *) key->data.scalar.value, "context_value"))
802 scop->context_value = extract_set(ctx, document, value);
803 if (!strcmp((char *) key->data.scalar.value, "types"))
804 scop = extract_types(ctx, document, value, scop);
805 if (!strcmp((char *) key->data.scalar.value, "arrays"))
806 scop = extract_arrays(ctx, document, value, scop);
807 if (!strcmp((char *) key->data.scalar.value, "statements"))
808 scop = extract_statements(ctx, document, value, scop);
809 if (!strcmp((char *) key->data.scalar.value, "implications"))
810 scop = extract_implications(ctx, document, value, scop);
811 if (!scop)
812 return NULL;
815 if (!scop->context_value) {
816 isl_space *space = isl_space_params_alloc(ctx, 0);
817 scop->context_value = isl_set_universe(space);
818 if (!scop->context_value)
819 return pet_scop_free(scop);
822 return scop;
825 /* Extract a pet_scop from the YAML description in "in".
827 struct pet_scop *pet_scop_parse(isl_ctx *ctx, FILE *in)
829 struct pet_scop *scop = NULL;
830 yaml_parser_t parser;
831 yaml_node_t *root;
832 yaml_document_t document = { 0 };
834 yaml_parser_initialize(&parser);
836 yaml_parser_set_input_file(&parser, in);
838 if (!yaml_parser_load(&parser, &document))
839 goto error;
841 root = yaml_document_get_root_node(&document);
843 scop = extract_scop(ctx, &document, root);
845 yaml_document_delete(&document);
847 yaml_parser_delete(&parser);
849 return scop;
850 error:
851 yaml_parser_delete(&parser);
852 pet_scop_free(scop);
853 return NULL;