2 * Copyright 2011 Leiden University. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY LEIDEN UNIVERSITY ''AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LEIDEN UNIVERSITY OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * The views and conclusions contained in the software and documentation
29 * are those of the authors and should not be interpreted as
30 * representing official policies, either expressed or implied, of
38 #include "scop_yaml.h"
40 static char *extract_string(isl_ctx
*ctx
, yaml_document_t
*document
,
43 if (node
->type
!= YAML_SCALAR_NODE
)
44 isl_die(ctx
, isl_error_invalid
, "expecting scalar node",
47 return strdup((char *) node
->data
.scalar
.value
);
50 static int extract_int(isl_ctx
*ctx
, yaml_document_t
*document
,
53 if (node
->type
!= YAML_SCALAR_NODE
)
54 isl_die(ctx
, isl_error_invalid
, "expecting scalar node",
57 return atoi((char *) node
->data
.scalar
.value
);
60 static double extract_double(isl_ctx
*ctx
, yaml_document_t
*document
,
63 if (node
->type
!= YAML_SCALAR_NODE
)
64 isl_die(ctx
, isl_error_invalid
, "expecting scalar node",
67 return strtod((char *) node
->data
.scalar
.value
, NULL
);
70 static enum pet_expr_type
extract_type(isl_ctx
*ctx
, yaml_document_t
*document
,
73 if (node
->type
!= YAML_SCALAR_NODE
)
74 isl_die(ctx
, isl_error_invalid
, "expecting scalar node",
77 return pet_str_type((char *) node
->data
.scalar
.value
);
80 static enum pet_op_type
extract_op(isl_ctx
*ctx
, yaml_document_t
*document
,
83 if (node
->type
!= YAML_SCALAR_NODE
)
84 isl_die(ctx
, isl_error_invalid
, "expecting scalar node",
87 return pet_str_op((char *) node
->data
.scalar
.value
);
90 static __isl_give isl_set
*extract_set(isl_ctx
*ctx
, yaml_document_t
*document
,
93 if (node
->type
!= YAML_SCALAR_NODE
)
94 isl_die(ctx
, isl_error_invalid
, "expecting scalar node",
97 return isl_set_read_from_str(ctx
, (char *) node
->data
.scalar
.value
);
100 static __isl_give isl_map
*extract_map(isl_ctx
*ctx
, yaml_document_t
*document
,
103 if (node
->type
!= YAML_SCALAR_NODE
)
104 isl_die(ctx
, isl_error_invalid
, "expecting scalar node",
107 return isl_map_read_from_str(ctx
, (char *) node
->data
.scalar
.value
);
110 static struct pet_array
*extract_array(isl_ctx
*ctx
, yaml_document_t
*document
,
113 struct pet_array
*array
;
114 yaml_node_pair_t
* pair
;
116 if (node
->type
!= YAML_MAPPING_NODE
)
117 isl_die(ctx
, isl_error_invalid
, "expecting mapping",
120 array
= isl_calloc_type(ctx
, struct pet_array
);
124 for (pair
= node
->data
.mapping
.pairs
.start
;
125 pair
< node
->data
.mapping
.pairs
.top
; ++pair
) {
126 yaml_node_t
*key
, *value
;
128 key
= yaml_document_get_node(document
, pair
->key
);
129 value
= yaml_document_get_node(document
, pair
->value
);
131 if (key
->type
!= YAML_SCALAR_NODE
)
132 isl_die(ctx
, isl_error_invalid
, "expecting scalar key",
133 return pet_array_free(array
));
135 if (!strcmp((char *) key
->data
.scalar
.value
, "context"))
136 array
->context
= extract_set(ctx
, document
, value
);
137 if (!strcmp((char *) key
->data
.scalar
.value
, "extent"))
138 array
->extent
= extract_set(ctx
, document
, value
);
139 if (!strcmp((char *) key
->data
.scalar
.value
, "value_bounds"))
140 array
->value_bounds
= extract_set(ctx
, document
, value
);
141 if (!strcmp((char *) key
->data
.scalar
.value
, "element_type"))
142 array
->element_type
=
143 extract_string(ctx
, document
, value
);
144 if (!strcmp((char *) key
->data
.scalar
.value
, "element_size"))
145 array
->element_size
= extract_int(ctx
, document
, value
);
146 if (!strcmp((char *) key
->data
.scalar
.value
, "live_out"))
147 array
->live_out
= extract_int(ctx
, document
, value
);
148 if (!strcmp((char *) key
->data
.scalar
.value
,
150 array
->uniquely_defined
=
151 extract_int(ctx
, document
, value
);
152 if (!strcmp((char *) key
->data
.scalar
.value
, "declared"))
153 array
->declared
= extract_int(ctx
, document
, value
);
154 if (!strcmp((char *) key
->data
.scalar
.value
, "exposed"))
155 array
->exposed
= extract_int(ctx
, document
, value
);
161 static struct pet_scop
*extract_arrays(isl_ctx
*ctx
, yaml_document_t
*document
,
162 yaml_node_t
*node
, struct pet_scop
*scop
)
165 yaml_node_item_t
*item
;
167 if (node
->type
!= YAML_SEQUENCE_NODE
)
168 isl_die(ctx
, isl_error_invalid
, "expecting sequence",
171 scop
->n_array
= node
->data
.sequence
.items
.top
172 - node
->data
.sequence
.items
.start
;
173 scop
->arrays
= isl_calloc_array(ctx
, struct pet_array
*, scop
->n_array
);
175 return pet_scop_free(scop
);
177 for (item
= node
->data
.sequence
.items
.start
, i
= 0;
178 item
< node
->data
.sequence
.items
.top
; ++item
, ++i
) {
181 n
= yaml_document_get_node(document
, *item
);
182 scop
->arrays
[i
] = extract_array(ctx
, document
, n
);
183 if (!scop
->arrays
[i
])
184 return pet_scop_free(scop
);
190 static struct pet_expr
*extract_expr(isl_ctx
*ctx
, yaml_document_t
*document
,
193 static struct pet_expr
*extract_arguments(isl_ctx
*ctx
,
194 yaml_document_t
*document
, yaml_node_t
*node
, struct pet_expr
*expr
)
197 yaml_node_item_t
*item
;
199 if (node
->type
!= YAML_SEQUENCE_NODE
)
200 isl_die(ctx
, isl_error_invalid
, "expecting sequence",
201 return pet_expr_free(expr
));
203 expr
->n_arg
= node
->data
.sequence
.items
.top
204 - node
->data
.sequence
.items
.start
;
205 expr
->args
= isl_calloc_array(ctx
, struct pet_expr
*, expr
->n_arg
);
207 return pet_expr_free(expr
);
209 for (item
= node
->data
.sequence
.items
.start
, i
= 0;
210 item
< node
->data
.sequence
.items
.top
; ++item
, ++i
) {
213 n
= yaml_document_get_node(document
, *item
);
214 expr
->args
[i
] = extract_expr(ctx
, document
, n
);
216 return pet_expr_free(expr
);
222 /* Extract pet_expr_double specific fields from "node" and
223 * update "expr" accordingly.
225 static struct pet_expr
*extract_expr_double(isl_ctx
*ctx
,
226 yaml_document_t
*document
, yaml_node_t
*node
, struct pet_expr
*expr
)
228 yaml_node_pair_t
*pair
;
230 for (pair
= node
->data
.mapping
.pairs
.start
;
231 pair
< node
->data
.mapping
.pairs
.top
; ++pair
) {
232 yaml_node_t
*key
, *value
;
234 key
= yaml_document_get_node(document
, pair
->key
);
235 value
= yaml_document_get_node(document
, pair
->value
);
237 if (key
->type
!= YAML_SCALAR_NODE
)
238 isl_die(ctx
, isl_error_invalid
, "expecting scalar key",
239 return pet_expr_free(expr
));
241 if (!strcmp((char *) key
->data
.scalar
.value
, "value"))
242 expr
->d
.val
= extract_double(ctx
, document
, value
);
243 if (!strcmp((char *) key
->data
.scalar
.value
, "string"))
244 expr
->d
.s
= extract_string(ctx
, document
, value
);
250 /* Extract pet_expr_access specific fields from "node" and
251 * update "expr" accordingly.
253 static struct pet_expr
*extract_expr_access(isl_ctx
*ctx
,
254 yaml_document_t
*document
, yaml_node_t
*node
, struct pet_expr
*expr
)
256 yaml_node_pair_t
*pair
;
258 for (pair
= node
->data
.mapping
.pairs
.start
;
259 pair
< node
->data
.mapping
.pairs
.top
; ++pair
) {
260 yaml_node_t
*key
, *value
;
262 key
= yaml_document_get_node(document
, pair
->key
);
263 value
= yaml_document_get_node(document
, pair
->value
);
265 if (key
->type
!= YAML_SCALAR_NODE
)
266 isl_die(ctx
, isl_error_invalid
, "expecting scalar key",
267 return pet_expr_free(expr
));
269 if (!strcmp((char *) key
->data
.scalar
.value
, "relation"))
270 expr
->acc
.access
= extract_map(ctx
, document
, value
);
271 if (!strcmp((char *) key
->data
.scalar
.value
, "read"))
272 expr
->acc
.read
= extract_int(ctx
, document
, value
);
273 if (!strcmp((char *) key
->data
.scalar
.value
, "write"))
274 expr
->acc
.write
= extract_int(ctx
, document
, value
);
280 /* Extract operation expression specific fields from "node" and
281 * update "expr" accordingly.
283 static struct pet_expr
*extract_expr_op(isl_ctx
*ctx
,
284 yaml_document_t
*document
, yaml_node_t
*node
, struct pet_expr
*expr
)
286 yaml_node_pair_t
*pair
;
288 for (pair
= node
->data
.mapping
.pairs
.start
;
289 pair
< node
->data
.mapping
.pairs
.top
; ++pair
) {
290 yaml_node_t
*key
, *value
;
292 key
= yaml_document_get_node(document
, pair
->key
);
293 value
= yaml_document_get_node(document
, pair
->value
);
295 if (key
->type
!= YAML_SCALAR_NODE
)
296 isl_die(ctx
, isl_error_invalid
, "expecting scalar key",
297 return pet_expr_free(expr
));
299 if (!strcmp((char *) key
->data
.scalar
.value
, "operation"))
300 expr
->op
= extract_op(ctx
, document
, value
);
306 /* Extract pet_expr_call specific fields from "node" and
307 * update "expr" accordingly.
309 static struct pet_expr
*extract_expr_call(isl_ctx
*ctx
,
310 yaml_document_t
*document
, yaml_node_t
*node
, struct pet_expr
*expr
)
312 yaml_node_pair_t
*pair
;
314 for (pair
= node
->data
.mapping
.pairs
.start
;
315 pair
< node
->data
.mapping
.pairs
.top
; ++pair
) {
316 yaml_node_t
*key
, *value
;
318 key
= yaml_document_get_node(document
, pair
->key
);
319 value
= yaml_document_get_node(document
, pair
->value
);
321 if (key
->type
!= YAML_SCALAR_NODE
)
322 isl_die(ctx
, isl_error_invalid
, "expecting scalar key",
323 return pet_expr_free(expr
));
325 if (!strcmp((char *) key
->data
.scalar
.value
, "name"))
326 expr
->name
= extract_string(ctx
, document
, value
);
332 /* Extract pet_expr_cast specific fields from "node" and
333 * update "expr" accordingly.
335 static struct pet_expr
*extract_expr_cast(isl_ctx
*ctx
,
336 yaml_document_t
*document
, yaml_node_t
*node
, struct pet_expr
*expr
)
338 yaml_node_pair_t
*pair
;
340 for (pair
= node
->data
.mapping
.pairs
.start
;
341 pair
< node
->data
.mapping
.pairs
.top
; ++pair
) {
342 yaml_node_t
*key
, *value
;
344 key
= yaml_document_get_node(document
, pair
->key
);
345 value
= yaml_document_get_node(document
, pair
->value
);
347 if (key
->type
!= YAML_SCALAR_NODE
)
348 isl_die(ctx
, isl_error_invalid
, "expecting scalar key",
349 return pet_expr_free(expr
));
351 if (!strcmp((char *) key
->data
.scalar
.value
, "type_name"))
352 expr
->type_name
= extract_string(ctx
, document
, value
);
358 /* Extract a pet_expr from "node".
360 * We first extract the type and arguments of the expression and
361 * then extract additional fields depending on the type.
363 static struct pet_expr
*extract_expr(isl_ctx
*ctx
, yaml_document_t
*document
,
366 struct pet_expr
*expr
;
367 yaml_node_pair_t
*pair
;
369 if (node
->type
!= YAML_MAPPING_NODE
)
370 isl_die(ctx
, isl_error_invalid
, "expecting mapping",
373 expr
= isl_calloc_type(ctx
, struct pet_expr
);
377 for (pair
= node
->data
.mapping
.pairs
.start
;
378 pair
< node
->data
.mapping
.pairs
.top
; ++pair
) {
379 yaml_node_t
*key
, *value
;
381 key
= yaml_document_get_node(document
, pair
->key
);
382 value
= yaml_document_get_node(document
, pair
->value
);
384 if (key
->type
!= YAML_SCALAR_NODE
)
385 isl_die(ctx
, isl_error_invalid
, "expecting scalar key",
386 return pet_expr_free(expr
));
388 if (!strcmp((char *) key
->data
.scalar
.value
, "type"))
389 expr
->type
= extract_type(ctx
, document
, value
);
391 if (!strcmp((char *) key
->data
.scalar
.value
, "arguments"))
392 expr
= extract_arguments(ctx
, document
, value
, expr
);
397 switch (expr
->type
) {
398 case pet_expr_access
:
399 expr
= extract_expr_access(ctx
, document
, node
, expr
);
401 case pet_expr_double
:
402 expr
= extract_expr_double(ctx
, document
, node
, expr
);
405 expr
= extract_expr_call(ctx
, document
, node
, expr
);
408 expr
= extract_expr_cast(ctx
, document
, node
, expr
);
411 case pet_expr_binary
:
412 case pet_expr_ternary
:
413 expr
= extract_expr_op(ctx
, document
, node
, expr
);
420 static struct pet_stmt
*extract_stmt_arguments(isl_ctx
*ctx
,
421 yaml_document_t
*document
, yaml_node_t
*node
, struct pet_stmt
*stmt
)
424 yaml_node_item_t
*item
;
426 if (node
->type
!= YAML_SEQUENCE_NODE
)
427 isl_die(ctx
, isl_error_invalid
, "expecting sequence",
428 return pet_stmt_free(stmt
));
430 stmt
->n_arg
= node
->data
.sequence
.items
.top
431 - node
->data
.sequence
.items
.start
;
432 stmt
->args
= isl_calloc_array(ctx
, struct pet_expr
*, stmt
->n_arg
);
434 return pet_stmt_free(stmt
);
436 for (item
= node
->data
.sequence
.items
.start
, i
= 0;
437 item
< node
->data
.sequence
.items
.top
; ++item
, ++i
) {
440 n
= yaml_document_get_node(document
, *item
);
441 stmt
->args
[i
] = extract_expr(ctx
, document
, n
);
443 return pet_stmt_free(stmt
);
449 static struct pet_stmt
*extract_stmt(isl_ctx
*ctx
, yaml_document_t
*document
,
452 struct pet_stmt
*stmt
;
453 yaml_node_pair_t
* pair
;
455 if (node
->type
!= YAML_MAPPING_NODE
)
456 isl_die(ctx
, isl_error_invalid
, "expecting mapping",
459 stmt
= isl_calloc_type(ctx
, struct pet_stmt
);
463 for (pair
= node
->data
.mapping
.pairs
.start
;
464 pair
< node
->data
.mapping
.pairs
.top
; ++pair
) {
465 yaml_node_t
*key
, *value
;
467 key
= yaml_document_get_node(document
, pair
->key
);
468 value
= yaml_document_get_node(document
, pair
->value
);
470 if (key
->type
!= YAML_SCALAR_NODE
)
471 isl_die(ctx
, isl_error_invalid
, "expecting scalar key",
472 return pet_stmt_free(stmt
));
474 if (!strcmp((char *) key
->data
.scalar
.value
, "line"))
475 stmt
->line
= extract_int(ctx
, document
, value
);
476 if (!strcmp((char *) key
->data
.scalar
.value
, "domain"))
477 stmt
->domain
= extract_set(ctx
, document
, value
);
478 if (!strcmp((char *) key
->data
.scalar
.value
, "schedule"))
479 stmt
->schedule
= extract_map(ctx
, document
, value
);
480 if (!strcmp((char *) key
->data
.scalar
.value
, "body"))
481 stmt
->body
= extract_expr(ctx
, document
, value
);
483 if (!strcmp((char *) key
->data
.scalar
.value
, "arguments"))
484 stmt
= extract_stmt_arguments(ctx
, document
,
493 static struct pet_scop
*extract_statements(isl_ctx
*ctx
,
494 yaml_document_t
*document
, yaml_node_t
*node
, struct pet_scop
*scop
)
497 yaml_node_item_t
*item
;
499 if (node
->type
!= YAML_SEQUENCE_NODE
)
500 isl_die(ctx
, isl_error_invalid
, "expecting sequence",
503 scop
->n_stmt
= node
->data
.sequence
.items
.top
504 - node
->data
.sequence
.items
.start
;
505 scop
->stmts
= isl_calloc_array(ctx
, struct pet_stmt
*, scop
->n_stmt
);
507 return pet_scop_free(scop
);
509 for (item
= node
->data
.sequence
.items
.start
, i
= 0;
510 item
< node
->data
.sequence
.items
.top
; ++item
, ++i
) {
513 n
= yaml_document_get_node(document
, *item
);
514 scop
->stmts
[i
] = extract_stmt(ctx
, document
, n
);
516 return pet_scop_free(scop
);
522 static struct pet_scop
*extract_scop(isl_ctx
*ctx
, yaml_document_t
*document
,
525 struct pet_scop
*scop
;
526 yaml_node_pair_t
* pair
;
531 if (node
->type
!= YAML_MAPPING_NODE
)
532 isl_die(ctx
, isl_error_invalid
, "expecting mapping",
535 scop
= pet_scop_alloc(ctx
);
539 for (pair
= node
->data
.mapping
.pairs
.start
;
540 pair
< node
->data
.mapping
.pairs
.top
; ++pair
) {
541 yaml_node_t
*key
, *value
;
543 key
= yaml_document_get_node(document
, pair
->key
);
544 value
= yaml_document_get_node(document
, pair
->value
);
546 if (key
->type
!= YAML_SCALAR_NODE
)
547 isl_die(ctx
, isl_error_invalid
, "expecting scalar key",
548 return pet_scop_free(scop
));
549 if (!strcmp((char *) key
->data
.scalar
.value
, "context"))
550 scop
->context
= extract_set(ctx
, document
, value
);
551 if (!strcmp((char *) key
->data
.scalar
.value
, "context_value"))
552 scop
->context_value
= extract_set(ctx
, document
, value
);
553 if (!strcmp((char *) key
->data
.scalar
.value
, "arrays"))
554 scop
= extract_arrays(ctx
, document
, value
, scop
);
555 if (!strcmp((char *) key
->data
.scalar
.value
, "statements"))
556 scop
= extract_statements(ctx
, document
, value
, scop
);
561 if (!scop
->context_value
) {
562 isl_space
*space
= isl_space_params_alloc(ctx
, 0);
563 scop
->context_value
= isl_set_universe(space
);
564 if (!scop
->context_value
)
565 return pet_scop_free(scop
);
571 /* Extract a pet_scop from the YAML description in "in".
573 struct pet_scop
*pet_scop_parse(isl_ctx
*ctx
, FILE *in
)
575 struct pet_scop
*scop
= NULL
;
576 yaml_parser_t parser
;
578 yaml_document_t document
= { 0 };
580 yaml_parser_initialize(&parser
);
582 yaml_parser_set_input_file(&parser
, in
);
584 if (!yaml_parser_load(&parser
, &document
))
587 root
= yaml_document_get_root_node(&document
);
589 scop
= extract_scop(ctx
, &document
, root
);
591 yaml_document_delete(&document
);
593 yaml_parser_delete(&parser
);
597 yaml_parser_delete(&parser
);