take into account that unsigned iterators may wrap
[pet.git] / parse.c
blob93c672a07fb98ee4554f7364e9ca9df96d1f6a20
1 #include <stdlib.h>
2 #include <yaml.h>
4 #include "scop.h"
5 #include "scop_yaml.h"
7 static char *extract_string(isl_ctx *ctx, yaml_document_t *document,
8 yaml_node_t *node)
10 if (node->type != YAML_SCALAR_NODE)
11 isl_die(ctx, isl_error_invalid, "expecting scalar node",
12 return NULL);
14 return strdup((char *) node->data.scalar.value);
17 static int extract_int(isl_ctx *ctx, yaml_document_t *document,
18 yaml_node_t *node)
20 if (node->type != YAML_SCALAR_NODE)
21 isl_die(ctx, isl_error_invalid, "expecting scalar node",
22 return -1);
24 return atoi((char *) node->data.scalar.value);
27 static int extract_double(isl_ctx *ctx, yaml_document_t *document,
28 yaml_node_t *node)
30 if (node->type != YAML_SCALAR_NODE)
31 isl_die(ctx, isl_error_invalid, "expecting scalar node",
32 return -1);
34 return strtod((char *) node->data.scalar.value, NULL);
37 static enum pet_expr_type extract_type(isl_ctx *ctx, yaml_document_t *document,
38 yaml_node_t *node)
40 if (node->type != YAML_SCALAR_NODE)
41 isl_die(ctx, isl_error_invalid, "expecting scalar node",
42 return -1);
44 return pet_str_type((char *) node->data.scalar.value);
47 static enum pet_op_type extract_op(isl_ctx *ctx, yaml_document_t *document,
48 yaml_node_t *node)
50 if (node->type != YAML_SCALAR_NODE)
51 isl_die(ctx, isl_error_invalid, "expecting scalar node",
52 return -1);
54 return pet_str_op((char *) node->data.scalar.value);
57 static __isl_give isl_set *extract_set(isl_ctx *ctx, yaml_document_t *document,
58 yaml_node_t *node)
60 if (node->type != YAML_SCALAR_NODE)
61 isl_die(ctx, isl_error_invalid, "expecting scalar node",
62 return NULL);
64 return isl_set_read_from_str(ctx, (char *) node->data.scalar.value, -1);
67 static __isl_give isl_map *extract_map(isl_ctx *ctx, yaml_document_t *document,
68 yaml_node_t *node)
70 if (node->type != YAML_SCALAR_NODE)
71 isl_die(ctx, isl_error_invalid, "expecting scalar node",
72 return NULL);
74 return isl_map_read_from_str(ctx, (char *) node->data.scalar.value, -1);
77 static struct pet_array *extract_array(isl_ctx *ctx, yaml_document_t *document,
78 yaml_node_t *node)
80 struct pet_array *array;
81 yaml_node_pair_t * pair;
83 if (node->type != YAML_MAPPING_NODE)
84 isl_die(ctx, isl_error_invalid, "expecting mapping",
85 return NULL);
87 array = isl_calloc_type(ctx, struct pet_array);
88 if (!array)
89 return NULL;
91 for (pair = node->data.mapping.pairs.start;
92 pair < node->data.mapping.pairs.top; ++pair) {
93 yaml_node_t *key, *value;
95 key = yaml_document_get_node(document, pair->key);
96 value = yaml_document_get_node(document, pair->value);
98 if (key->type != YAML_SCALAR_NODE)
99 isl_die(ctx, isl_error_invalid, "expecting scalar key",
100 return pet_array_free(array));
102 if (!strcmp((char *) key->data.scalar.value, "context"))
103 array->context = extract_set(ctx, document, value);
104 if (!strcmp((char *) key->data.scalar.value, "extent"))
105 array->extent = extract_set(ctx, document, value);
106 if (!strcmp((char *) key->data.scalar.value, "value_bounds"))
107 array->value_bounds = extract_set(ctx, document, value);
108 if (!strcmp((char *) key->data.scalar.value, "element_type"))
109 array->element_type =
110 extract_string(ctx, document, value);
113 return array;
116 static struct pet_scop *extract_arrays(isl_ctx *ctx, yaml_document_t *document,
117 yaml_node_t *node, struct pet_scop *scop)
119 int i;
120 yaml_node_item_t *item;
122 if (node->type != YAML_SEQUENCE_NODE)
123 isl_die(ctx, isl_error_invalid, "expecting sequence",
124 return NULL);
126 scop->n_array = node->data.sequence.items.top
127 - node->data.sequence.items.start;
128 scop->arrays = isl_calloc_array(ctx, struct pet_array *, scop->n_array);
129 if (!scop->arrays)
130 return pet_scop_free(scop);
132 for (item = node->data.sequence.items.start, i = 0;
133 item < node->data.sequence.items.top; ++item, ++i) {
134 yaml_node_t *n;
136 n = yaml_document_get_node(document, *item);
137 scop->arrays[i] = extract_array(ctx, document, n);
138 if (!scop->arrays[i])
139 return pet_scop_free(scop);
142 return scop;
145 static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document,
146 yaml_node_t *node);
148 static struct pet_expr *extract_arguments(isl_ctx *ctx,
149 yaml_document_t *document, yaml_node_t *node, struct pet_expr *expr)
151 int i;
152 yaml_node_item_t *item;
154 if (node->type != YAML_SEQUENCE_NODE)
155 isl_die(ctx, isl_error_invalid, "expecting sequence",
156 return NULL);
158 expr->n_arg = node->data.sequence.items.top
159 - node->data.sequence.items.start;
160 expr->args = isl_calloc_array(ctx, struct pet_expr *, expr->n_arg);
161 if (!expr->args)
162 return pet_expr_free(expr);
164 for (item = node->data.sequence.items.start, i = 0;
165 item < node->data.sequence.items.top; ++item, ++i) {
166 yaml_node_t *n;
168 n = yaml_document_get_node(document, *item);
169 expr->args[i] = extract_expr(ctx, document, n);
170 if (!expr->args[i])
171 return pet_expr_free(expr);
174 return expr;
177 static struct pet_expr *extract_expr(isl_ctx *ctx, yaml_document_t *document,
178 yaml_node_t *node)
180 struct pet_expr *expr;
181 yaml_node_pair_t * pair;
183 if (node->type != YAML_MAPPING_NODE)
184 isl_die(ctx, isl_error_invalid, "expecting mapping",
185 return NULL);
187 expr = isl_calloc_type(ctx, struct pet_expr);
188 if (!expr)
189 return NULL;
191 for (pair = node->data.mapping.pairs.start;
192 pair < node->data.mapping.pairs.top; ++pair) {
193 yaml_node_t *key, *value;
195 key = yaml_document_get_node(document, pair->key);
196 value = yaml_document_get_node(document, pair->value);
198 if (key->type != YAML_SCALAR_NODE)
199 isl_die(ctx, isl_error_invalid, "expecting scalar key",
200 return pet_expr_free(expr));
202 if (!strcmp((char *) key->data.scalar.value, "type"))
203 expr->type = extract_type(ctx, document, value);
205 if (!strcmp((char *) key->data.scalar.value, "value"))
206 expr->d = extract_double(ctx, document, value);
208 if (!strcmp((char *) key->data.scalar.value, "relation"))
209 expr->acc.access = extract_map(ctx, document, value);
210 if (!strcmp((char *) key->data.scalar.value, "read"))
211 expr->acc.read = extract_int(ctx, document, value);
212 if (!strcmp((char *) key->data.scalar.value, "write"))
213 expr->acc.write = extract_int(ctx, document, value);
215 if (!strcmp((char *) key->data.scalar.value, "operation"))
216 expr->op = extract_op(ctx, document, value);
218 if (!strcmp((char *) key->data.scalar.value, "name"))
219 expr->name = extract_string(ctx, document, value);
221 if (!strcmp((char *) key->data.scalar.value, "arguments"))
222 expr = extract_arguments(ctx, document, value, expr);
223 if (!expr)
224 return NULL;
227 return expr;
230 static struct pet_stmt *extract_stmt(isl_ctx *ctx, yaml_document_t *document,
231 yaml_node_t *node)
233 struct pet_stmt *stmt;
234 yaml_node_pair_t * pair;
236 if (node->type != YAML_MAPPING_NODE)
237 isl_die(ctx, isl_error_invalid, "expecting mapping",
238 return NULL);
240 stmt = isl_calloc_type(ctx, struct pet_stmt);
241 if (!stmt)
242 return NULL;
244 for (pair = node->data.mapping.pairs.start;
245 pair < node->data.mapping.pairs.top; ++pair) {
246 yaml_node_t *key, *value;
248 key = yaml_document_get_node(document, pair->key);
249 value = yaml_document_get_node(document, pair->value);
251 if (key->type != YAML_SCALAR_NODE)
252 isl_die(ctx, isl_error_invalid, "expecting scalar key",
253 return pet_stmt_free(stmt));
255 if (!strcmp((char *) key->data.scalar.value, "line"))
256 stmt->line = extract_int(ctx, document, value);
257 if (!strcmp((char *) key->data.scalar.value, "domain"))
258 stmt->domain = extract_set(ctx, document, value);
259 if (!strcmp((char *) key->data.scalar.value, "schedule"))
260 stmt->schedule = extract_map(ctx, document, value);
261 if (!strcmp((char *) key->data.scalar.value, "body"))
262 stmt->body = extract_expr(ctx, document, value);
265 return stmt;
268 static struct pet_scop *extract_statements(isl_ctx *ctx,
269 yaml_document_t *document, 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_stmt = node->data.sequence.items.top
279 - node->data.sequence.items.start;
280 scop->stmts = isl_calloc_array(ctx, struct pet_stmt *, scop->n_stmt);
281 if (!scop->stmts)
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->stmts[i] = extract_stmt(ctx, document, n);
290 if (!scop->stmts[i])
291 return pet_scop_free(scop);
294 return scop;
297 static struct pet_scop *extract_scop(isl_ctx *ctx, yaml_document_t *document,
298 yaml_node_t *node)
300 struct pet_scop *scop;
301 yaml_node_pair_t * pair;
303 if (!node)
304 return NULL;
306 if (node->type != YAML_MAPPING_NODE)
307 isl_die(ctx, isl_error_invalid, "expecting mapping",
308 return NULL);
310 scop = isl_calloc_type(ctx, struct pet_scop);
311 if (!scop)
312 return NULL;
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_scop_free(scop));
324 if (!strcmp((char *) key->data.scalar.value, "context"))
325 scop->context = extract_set(ctx, document, value);
326 if (!strcmp((char *) key->data.scalar.value, "arrays"))
327 scop = extract_arrays(ctx, document, value, scop);
328 if (!strcmp((char *) key->data.scalar.value, "statements"))
329 scop = extract_statements(ctx, document, value, scop);
330 if (!scop)
331 return NULL;
334 return scop;
337 /* Extract a pet_scop from the YAML description in "in".
339 struct pet_scop *pet_scop_parse(isl_ctx *ctx, FILE *in)
341 struct pet_scop *scop = NULL;
342 yaml_parser_t parser;
343 yaml_node_t *root;
344 yaml_document_t document = { 0 };
346 yaml_parser_initialize(&parser);
348 yaml_parser_set_input_file(&parser, in);
350 if (!yaml_parser_load(&parser, &document))
351 goto error;
353 root = yaml_document_get_root_node(&document);
355 scop = extract_scop(ctx, &document, root);
357 yaml_document_delete(&document);
359 yaml_parser_delete(&parser);
361 return scop;
362 error:
363 yaml_parser_delete(&parser);
364 pet_scop_free(scop);
365 return NULL;