pet_expr: merge unary, binary and ternary types into operation type
[pet.git] / parse.c
blobfb56efd21b9394c114952be1e4f7826b942db8ea
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 "scop.h"
39 #include "scop_yaml.h"
41 static char *extract_string(isl_ctx *ctx, yaml_document_t *document,
42 yaml_node_t *node)
44 if (node->type != YAML_SCALAR_NODE)
45 isl_die(ctx, isl_error_invalid, "expecting scalar node",
46 return NULL);
48 return strdup((char *) node->data.scalar.value);
51 static int extract_int(isl_ctx *ctx, yaml_document_t *document,
52 yaml_node_t *node)
54 if (node->type != YAML_SCALAR_NODE)
55 isl_die(ctx, isl_error_invalid, "expecting scalar node",
56 return -1);
58 return atoi((char *) node->data.scalar.value);
61 static double extract_double(isl_ctx *ctx, yaml_document_t *document,
62 yaml_node_t *node)
64 if (node->type != YAML_SCALAR_NODE)
65 isl_die(ctx, isl_error_invalid, "expecting scalar node",
66 return -1);
68 return strtod((char *) node->data.scalar.value, NULL);
71 static enum pet_expr_type extract_expr_type(isl_ctx *ctx,
72 yaml_document_t *document, yaml_node_t *node)
74 if (node->type != YAML_SCALAR_NODE)
75 isl_die(ctx, isl_error_invalid, "expecting scalar node",
76 return -1);
78 return pet_str_type((char *) node->data.scalar.value);
81 static enum pet_op_type extract_op(isl_ctx *ctx, yaml_document_t *document,
82 yaml_node_t *node)
84 if (node->type != YAML_SCALAR_NODE)
85 isl_die(ctx, isl_error_invalid, "expecting scalar node",
86 return -1);
88 return pet_str_op((char *) node->data.scalar.value);
91 static __isl_give isl_set *extract_set(isl_ctx *ctx, yaml_document_t *document,
92 yaml_node_t *node)
94 if (node->type != YAML_SCALAR_NODE)
95 isl_die(ctx, isl_error_invalid, "expecting scalar node",
96 return NULL);
98 return isl_set_read_from_str(ctx, (char *) node->data.scalar.value);
101 static __isl_give isl_id *extract_id(isl_ctx *ctx, yaml_document_t *document,
102 yaml_node_t *node)
104 if (node->type != YAML_SCALAR_NODE)
105 isl_die(ctx, isl_error_invalid, "expecting scalar node",
106 return NULL);
108 return isl_id_alloc(ctx, (char *) node->data.scalar.value, NULL);
111 static __isl_give isl_map *extract_map(isl_ctx *ctx, yaml_document_t *document,
112 yaml_node_t *node)
114 if (node->type != YAML_SCALAR_NODE)
115 isl_die(ctx, isl_error_invalid, "expecting scalar node",
116 return NULL);
118 return isl_map_read_from_str(ctx, (char *) node->data.scalar.value);
121 /* Extract an isl_val from "node".
123 static __isl_give isl_val *extract_val(isl_ctx *ctx, yaml_document_t *document,
124 yaml_node_t *node)
126 if (node->type != YAML_SCALAR_NODE)
127 isl_die(ctx, isl_error_invalid, "expecting scalar node",
128 return NULL);
130 return isl_val_read_from_str(ctx, (char *) node->data.scalar.value);
133 /* Extract an isl_multi_pw_aff from "node".
135 static __isl_give isl_multi_pw_aff *extract_multi_pw_aff(isl_ctx *ctx,
136 yaml_document_t *document, yaml_node_t *node)
138 if (node->type != YAML_SCALAR_NODE)
139 isl_die(ctx, isl_error_invalid, "expecting scalar node",
140 return NULL);
142 return isl_multi_pw_aff_read_from_str(ctx,
143 (char *) node->data.scalar.value);
146 /* Extract a pet_type from "node".
148 static struct pet_type *extract_type(isl_ctx *ctx,
149 yaml_document_t *document, yaml_node_t *node)
151 struct pet_type *type;
152 yaml_node_pair_t * pair;
154 if (node->type != YAML_MAPPING_NODE)
155 isl_die(ctx, isl_error_invalid, "expecting mapping",
156 return NULL);
158 type = isl_calloc_type(ctx, struct pet_type);
159 if (!type)
160 return NULL;
162 for (pair = node->data.mapping.pairs.start;
163 pair < node->data.mapping.pairs.top; ++pair) {
164 yaml_node_t *key, *value;
166 key = yaml_document_get_node(document, pair->key);
167 value = yaml_document_get_node(document, pair->value);
169 if (key->type != YAML_SCALAR_NODE)
170 isl_die(ctx, isl_error_invalid, "expecting scalar key",
171 return pet_type_free(type));
173 if (!strcmp((char *) key->data.scalar.value, "name"))
174 type->name = extract_string(ctx, document, value);
175 if (!strcmp((char *) key->data.scalar.value, "definition"))
176 type->definition = extract_string(ctx, document, value);
179 return type;
182 /* Extract a sequence of types from "node" and store them in scop->types.
184 static struct pet_scop *extract_types(isl_ctx *ctx,
185 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
187 int i;
188 yaml_node_item_t *item;
190 if (node->type != YAML_SEQUENCE_NODE)
191 isl_die(ctx, isl_error_invalid, "expecting sequence",
192 return NULL);
194 scop->n_type = node->data.sequence.items.top
195 - node->data.sequence.items.start;
196 scop->types = isl_calloc_array(ctx, struct pet_type *, scop->n_type);
197 if (!scop->types)
198 return pet_scop_free(scop);
200 for (item = node->data.sequence.items.start, i = 0;
201 item < node->data.sequence.items.top; ++item, ++i) {
202 yaml_node_t *n;
204 n = yaml_document_get_node(document, *item);
205 scop->types[i] = extract_type(ctx, document, n);
206 if (!scop->types[i])
207 return pet_scop_free(scop);
210 return scop;
213 static struct pet_array *extract_array(isl_ctx *ctx, yaml_document_t *document,
214 yaml_node_t *node)
216 struct pet_array *array;
217 yaml_node_pair_t * pair;
219 if (node->type != YAML_MAPPING_NODE)
220 isl_die(ctx, isl_error_invalid, "expecting mapping",
221 return NULL);
223 array = isl_calloc_type(ctx, struct pet_array);
224 if (!array)
225 return NULL;
227 for (pair = node->data.mapping.pairs.start;
228 pair < node->data.mapping.pairs.top; ++pair) {
229 yaml_node_t *key, *value;
231 key = yaml_document_get_node(document, pair->key);
232 value = yaml_document_get_node(document, pair->value);
234 if (key->type != YAML_SCALAR_NODE)
235 isl_die(ctx, isl_error_invalid, "expecting scalar key",
236 return pet_array_free(array));
238 if (!strcmp((char *) key->data.scalar.value, "context"))
239 array->context = extract_set(ctx, document, value);
240 if (!strcmp((char *) key->data.scalar.value, "extent"))
241 array->extent = extract_set(ctx, document, value);
242 if (!strcmp((char *) key->data.scalar.value, "value_bounds"))
243 array->value_bounds = extract_set(ctx, document, value);
244 if (!strcmp((char *) key->data.scalar.value, "element_type"))
245 array->element_type =
246 extract_string(ctx, document, value);
247 if (!strcmp((char *) key->data.scalar.value, "element_size"))
248 array->element_size = extract_int(ctx, document, value);
249 if (!strcmp((char *) key->data.scalar.value,
250 "element_is_record"))
251 array->element_is_record =
252 extract_int(ctx, document, value);
253 if (!strcmp((char *) key->data.scalar.value, "live_out"))
254 array->live_out = extract_int(ctx, document, value);
255 if (!strcmp((char *) key->data.scalar.value,
256 "uniquely_defined"))
257 array->uniquely_defined =
258 extract_int(ctx, document, value);
259 if (!strcmp((char *) key->data.scalar.value, "declared"))
260 array->declared = extract_int(ctx, document, value);
261 if (!strcmp((char *) key->data.scalar.value, "exposed"))
262 array->exposed = extract_int(ctx, document, value);
265 return array;
268 static struct pet_scop *extract_arrays(isl_ctx *ctx, yaml_document_t *document,
269 yaml_node_t *node, struct pet_scop *scop)
271 int i;
272 yaml_node_item_t *item;
274 if (node->type != YAML_SEQUENCE_NODE)
275 isl_die(ctx, isl_error_invalid, "expecting sequence",
276 return NULL);
278 scop->n_array = node->data.sequence.items.top
279 - node->data.sequence.items.start;
280 scop->arrays = isl_calloc_array(ctx, struct pet_array *, scop->n_array);
281 if (!scop->arrays)
282 return pet_scop_free(scop);
284 for (item = node->data.sequence.items.start, i = 0;
285 item < node->data.sequence.items.top; ++item, ++i) {
286 yaml_node_t *n;
288 n = yaml_document_get_node(document, *item);
289 scop->arrays[i] = extract_array(ctx, document, n);
290 if (!scop->arrays[i])
291 return pet_scop_free(scop);
294 return scop;
297 static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document,
298 yaml_node_t *node);
300 static struct pet_expr *extract_arguments(isl_ctx *ctx,
301 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
303 int i;
304 yaml_node_item_t *item;
306 if (node->type != YAML_SEQUENCE_NODE)
307 isl_die(ctx, isl_error_invalid, "expecting sequence",
308 return pet_expr_free(expr));
310 expr->n_arg = node->data.sequence.items.top
311 - node->data.sequence.items.start;
312 expr->args = isl_calloc_array(ctx, struct pet_expr *, expr->n_arg);
313 if (!expr->args)
314 return pet_expr_free(expr);
316 for (item = node->data.sequence.items.start, i = 0;
317 item < node->data.sequence.items.top; ++item, ++i) {
318 yaml_node_t *n;
320 n = yaml_document_get_node(document, *item);
321 expr->args[i] = extract_expr(ctx, document, n);
322 if (!expr->args[i])
323 return pet_expr_free(expr);
326 return expr;
329 /* Extract pet_expr_double specific fields from "node" and
330 * update "expr" accordingly.
332 static struct pet_expr *extract_expr_double(isl_ctx *ctx,
333 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
335 yaml_node_pair_t *pair;
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 expr->d.val = extract_double(ctx, document, value);
350 if (!strcmp((char *) key->data.scalar.value, "string"))
351 expr->d.s = extract_string(ctx, document, value);
354 return expr;
357 /* Extract pet_expr_access specific fields from "node" and
358 * update "expr" accordingly.
360 static struct pet_expr *extract_expr_access(isl_ctx *ctx,
361 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
363 yaml_node_pair_t *pair;
365 for (pair = node->data.mapping.pairs.start;
366 pair < node->data.mapping.pairs.top; ++pair) {
367 yaml_node_t *key, *value;
369 key = yaml_document_get_node(document, pair->key);
370 value = yaml_document_get_node(document, pair->value);
372 if (key->type != YAML_SCALAR_NODE)
373 isl_die(ctx, isl_error_invalid, "expecting scalar key",
374 return pet_expr_free(expr));
376 if (!strcmp((char *) key->data.scalar.value, "relation"))
377 expr->acc.access = extract_map(ctx, document, value);
378 if (!strcmp((char *) key->data.scalar.value, "index"))
379 expr->acc.index = extract_multi_pw_aff(ctx, document,
380 value);
381 if (!strcmp((char *) key->data.scalar.value, "reference"))
382 expr->acc.ref_id = extract_id(ctx, document, value);
383 if (!strcmp((char *) key->data.scalar.value, "read"))
384 expr->acc.read = extract_int(ctx, document, value);
385 if (!strcmp((char *) key->data.scalar.value, "write"))
386 expr->acc.write = extract_int(ctx, document, value);
389 return expr;
392 /* Extract operation expression specific fields from "node" and
393 * update "expr" accordingly.
395 static struct pet_expr *extract_expr_op(isl_ctx *ctx,
396 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
398 yaml_node_pair_t *pair;
400 for (pair = node->data.mapping.pairs.start;
401 pair < node->data.mapping.pairs.top; ++pair) {
402 yaml_node_t *key, *value;
404 key = yaml_document_get_node(document, pair->key);
405 value = yaml_document_get_node(document, pair->value);
407 if (key->type != YAML_SCALAR_NODE)
408 isl_die(ctx, isl_error_invalid, "expecting scalar key",
409 return pet_expr_free(expr));
411 if (!strcmp((char *) key->data.scalar.value, "operation"))
412 expr->op = extract_op(ctx, document, value);
415 return expr;
418 /* Extract pet_expr_call specific fields from "node" and
419 * update "expr" accordingly.
421 static struct pet_expr *extract_expr_call(isl_ctx *ctx,
422 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
424 yaml_node_pair_t *pair;
426 for (pair = node->data.mapping.pairs.start;
427 pair < node->data.mapping.pairs.top; ++pair) {
428 yaml_node_t *key, *value;
430 key = yaml_document_get_node(document, pair->key);
431 value = yaml_document_get_node(document, pair->value);
433 if (key->type != YAML_SCALAR_NODE)
434 isl_die(ctx, isl_error_invalid, "expecting scalar key",
435 return pet_expr_free(expr));
437 if (!strcmp((char *) key->data.scalar.value, "name"))
438 expr->name = extract_string(ctx, document, value);
441 return expr;
444 /* Extract pet_expr_cast specific fields from "node" and
445 * update "expr" accordingly.
447 static struct pet_expr *extract_expr_cast(isl_ctx *ctx,
448 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
450 yaml_node_pair_t *pair;
452 for (pair = node->data.mapping.pairs.start;
453 pair < node->data.mapping.pairs.top; ++pair) {
454 yaml_node_t *key, *value;
456 key = yaml_document_get_node(document, pair->key);
457 value = yaml_document_get_node(document, pair->value);
459 if (key->type != YAML_SCALAR_NODE)
460 isl_die(ctx, isl_error_invalid, "expecting scalar key",
461 return pet_expr_free(expr));
463 if (!strcmp((char *) key->data.scalar.value, "type_name"))
464 expr->type_name = extract_string(ctx, document, value);
467 return expr;
470 /* Extract pet_expr_int specific fields from "node" and
471 * update "expr" accordingly.
473 static struct pet_expr *extract_expr_int(isl_ctx *ctx,
474 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
476 yaml_node_pair_t * pair;
478 for (pair = node->data.mapping.pairs.start;
479 pair < node->data.mapping.pairs.top; ++pair) {
480 yaml_node_t *key, *value;
482 key = yaml_document_get_node(document, pair->key);
483 value = yaml_document_get_node(document, pair->value);
485 if (key->type != YAML_SCALAR_NODE)
486 isl_die(ctx, isl_error_invalid, "expecting scalar key",
487 return pet_expr_free(expr));
489 if (!strcmp((char *) key->data.scalar.value, "value"))
490 expr->i = extract_val(ctx, document, value);
493 return expr;
496 /* Extract a pet_expr from "node".
498 * We first extract the type and arguments of the expression and
499 * then extract additional fields depending on the type.
501 static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document,
502 yaml_node_t *node)
504 struct pet_expr *expr;
505 yaml_node_pair_t *pair;
507 if (node->type != YAML_MAPPING_NODE)
508 isl_die(ctx, isl_error_invalid, "expecting mapping",
509 return NULL);
511 expr = isl_calloc_type(ctx, struct pet_expr);
512 if (!expr)
513 return NULL;
515 for (pair = node->data.mapping.pairs.start;
516 pair < node->data.mapping.pairs.top; ++pair) {
517 yaml_node_t *key, *value;
519 key = yaml_document_get_node(document, pair->key);
520 value = yaml_document_get_node(document, pair->value);
522 if (key->type != YAML_SCALAR_NODE)
523 isl_die(ctx, isl_error_invalid, "expecting scalar key",
524 return pet_expr_free(expr));
526 if (!strcmp((char *) key->data.scalar.value, "type"))
527 expr->type = extract_expr_type(ctx, document, value);
529 if (!strcmp((char *) key->data.scalar.value, "arguments"))
530 expr = extract_arguments(ctx, document, value, expr);
531 if (!expr)
532 return NULL;
535 switch (expr->type) {
536 case pet_expr_access:
537 expr = extract_expr_access(ctx, document, node, expr);
538 break;
539 case pet_expr_double:
540 expr = extract_expr_double(ctx, document, node, expr);
541 break;
542 case pet_expr_call:
543 expr = extract_expr_call(ctx, document, node, expr);
544 break;
545 case pet_expr_cast:
546 expr = extract_expr_cast(ctx, document, node, expr);
547 break;
548 case pet_expr_int:
549 expr = extract_expr_int(ctx, document, node, expr);
550 break;
551 case pet_expr_op:
552 expr = extract_expr_op(ctx, document, node, expr);
553 break;
556 return expr;
559 static struct pet_stmt *extract_stmt_arguments(isl_ctx *ctx,
560 yaml_document_t *document, yaml_node_t *node, struct pet_stmt *stmt)
562 int i;
563 yaml_node_item_t *item;
565 if (node->type != YAML_SEQUENCE_NODE)
566 isl_die(ctx, isl_error_invalid, "expecting sequence",
567 return pet_stmt_free(stmt));
569 stmt->n_arg = node->data.sequence.items.top
570 - node->data.sequence.items.start;
571 stmt->args = isl_calloc_array(ctx, struct pet_expr *, stmt->n_arg);
572 if (!stmt->args)
573 return pet_stmt_free(stmt);
575 for (item = node->data.sequence.items.start, i = 0;
576 item < node->data.sequence.items.top; ++item, ++i) {
577 yaml_node_t *n;
579 n = yaml_document_get_node(document, *item);
580 stmt->args[i] = extract_expr(ctx, document, n);
581 if (!stmt->args[i])
582 return pet_stmt_free(stmt);
585 return stmt;
588 static struct pet_stmt *extract_stmt(isl_ctx *ctx, yaml_document_t *document,
589 yaml_node_t *node)
591 struct pet_stmt *stmt;
592 yaml_node_pair_t * pair;
594 if (node->type != YAML_MAPPING_NODE)
595 isl_die(ctx, isl_error_invalid, "expecting mapping",
596 return NULL);
598 stmt = isl_calloc_type(ctx, struct pet_stmt);
599 if (!stmt)
600 return NULL;
602 for (pair = node->data.mapping.pairs.start;
603 pair < node->data.mapping.pairs.top; ++pair) {
604 yaml_node_t *key, *value;
606 key = yaml_document_get_node(document, pair->key);
607 value = yaml_document_get_node(document, pair->value);
609 if (key->type != YAML_SCALAR_NODE)
610 isl_die(ctx, isl_error_invalid, "expecting scalar key",
611 return pet_stmt_free(stmt));
613 if (!strcmp((char *) key->data.scalar.value, "line"))
614 stmt->line = extract_int(ctx, document, value);
615 if (!strcmp((char *) key->data.scalar.value, "domain"))
616 stmt->domain = extract_set(ctx, document, value);
617 if (!strcmp((char *) key->data.scalar.value, "schedule"))
618 stmt->schedule = extract_map(ctx, document, value);
619 if (!strcmp((char *) key->data.scalar.value, "body"))
620 stmt->body = extract_expr(ctx, document, value);
622 if (!strcmp((char *) key->data.scalar.value, "arguments"))
623 stmt = extract_stmt_arguments(ctx, document,
624 value, stmt);
625 if (!stmt)
626 return NULL;
629 return stmt;
632 static struct pet_scop *extract_statements(isl_ctx *ctx,
633 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
635 int i;
636 yaml_node_item_t *item;
638 if (node->type != YAML_SEQUENCE_NODE)
639 isl_die(ctx, isl_error_invalid, "expecting sequence",
640 return NULL);
642 scop->n_stmt = node->data.sequence.items.top
643 - node->data.sequence.items.start;
644 scop->stmts = isl_calloc_array(ctx, struct pet_stmt *, scop->n_stmt);
645 if (!scop->stmts)
646 return pet_scop_free(scop);
648 for (item = node->data.sequence.items.start, i = 0;
649 item < node->data.sequence.items.top; ++item, ++i) {
650 yaml_node_t *n;
652 n = yaml_document_get_node(document, *item);
653 scop->stmts[i] = extract_stmt(ctx, document, n);
654 if (!scop->stmts[i])
655 return pet_scop_free(scop);
658 return scop;
661 /* Extract a pet_implication from "node".
663 static struct pet_implication *extract_implication(isl_ctx *ctx,
664 yaml_document_t *document, yaml_node_t *node)
666 struct pet_implication *implication;
667 yaml_node_pair_t * pair;
669 if (node->type != YAML_MAPPING_NODE)
670 isl_die(ctx, isl_error_invalid, "expecting mapping",
671 return NULL);
673 implication = isl_calloc_type(ctx, struct pet_implication);
674 if (!implication)
675 return NULL;
677 for (pair = node->data.mapping.pairs.start;
678 pair < node->data.mapping.pairs.top; ++pair) {
679 yaml_node_t *key, *value;
681 key = yaml_document_get_node(document, pair->key);
682 value = yaml_document_get_node(document, pair->value);
684 if (key->type != YAML_SCALAR_NODE)
685 isl_die(ctx, isl_error_invalid, "expecting scalar key",
686 return pet_implication_free(implication));
688 if (!strcmp((char *) key->data.scalar.value, "satisfied"))
689 implication->satisfied =
690 extract_int(ctx, document, value);
691 if (!strcmp((char *) key->data.scalar.value, "extension"))
692 implication->extension =
693 extract_map(ctx, document, value);
696 return implication;
699 /* Extract a sequence of implications from "node" and
700 * store them in scop->implications.
702 static struct pet_scop *extract_implications(isl_ctx *ctx,
703 yaml_document_t *document, yaml_node_t *node, struct pet_scop *scop)
705 int i;
706 yaml_node_item_t *item;
708 if (node->type != YAML_SEQUENCE_NODE)
709 isl_die(ctx, isl_error_invalid, "expecting sequence",
710 return NULL);
712 scop->n_implication = node->data.sequence.items.top
713 - node->data.sequence.items.start;
714 scop->implications = isl_calloc_array(ctx, struct pet_implication *,
715 scop->n_implication);
716 if (!scop->implications)
717 return pet_scop_free(scop);
719 for (item = node->data.sequence.items.start, i = 0;
720 item < node->data.sequence.items.top; ++item, ++i) {
721 yaml_node_t *n;
723 n = yaml_document_get_node(document, *item);
724 scop->implications[i] = extract_implication(ctx, document, n);
725 if (!scop->implications[i])
726 return pet_scop_free(scop);
729 return scop;
732 static struct pet_scop *extract_scop(isl_ctx *ctx, yaml_document_t *document,
733 yaml_node_t *node)
735 struct pet_scop *scop;
736 yaml_node_pair_t * pair;
738 if (!node)
739 return NULL;
741 if (node->type != YAML_MAPPING_NODE)
742 isl_die(ctx, isl_error_invalid, "expecting mapping",
743 return NULL);
745 scop = pet_scop_alloc(ctx);
746 if (!scop)
747 return NULL;
749 for (pair = node->data.mapping.pairs.start;
750 pair < node->data.mapping.pairs.top; ++pair) {
751 yaml_node_t *key, *value;
753 key = yaml_document_get_node(document, pair->key);
754 value = yaml_document_get_node(document, pair->value);
756 if (key->type != YAML_SCALAR_NODE)
757 isl_die(ctx, isl_error_invalid, "expecting scalar key",
758 return pet_scop_free(scop));
759 if (!strcmp((char *) key->data.scalar.value, "context"))
760 scop->context = extract_set(ctx, document, value);
761 if (!strcmp((char *) key->data.scalar.value, "context_value"))
762 scop->context_value = extract_set(ctx, document, value);
763 if (!strcmp((char *) key->data.scalar.value, "types"))
764 scop = extract_types(ctx, document, value, scop);
765 if (!strcmp((char *) key->data.scalar.value, "arrays"))
766 scop = extract_arrays(ctx, document, value, scop);
767 if (!strcmp((char *) key->data.scalar.value, "statements"))
768 scop = extract_statements(ctx, document, value, scop);
769 if (!strcmp((char *) key->data.scalar.value, "implications"))
770 scop = extract_implications(ctx, document, value, scop);
771 if (!scop)
772 return NULL;
775 if (!scop->context_value) {
776 isl_space *space = isl_space_params_alloc(ctx, 0);
777 scop->context_value = isl_set_universe(space);
778 if (!scop->context_value)
779 return pet_scop_free(scop);
782 return scop;
785 /* Extract a pet_scop from the YAML description in "in".
787 struct pet_scop *pet_scop_parse(isl_ctx *ctx, FILE *in)
789 struct pet_scop *scop = NULL;
790 yaml_parser_t parser;
791 yaml_node_t *root;
792 yaml_document_t document = { 0 };
794 yaml_parser_initialize(&parser);
796 yaml_parser_set_input_file(&parser, in);
798 if (!yaml_parser_load(&parser, &document))
799 goto error;
801 root = yaml_document_get_root_node(&document);
803 scop = extract_scop(ctx, &document, root);
805 yaml_document_delete(&document);
807 yaml_parser_delete(&parser);
809 return scop;
810 error:
811 yaml_parser_delete(&parser);
812 pet_scop_free(scop);
813 return NULL;