5 #include <isl_stream.h>
6 #include <isl_vertices.h>
7 #include <isl_obj_list.h>
8 #include <isl_obj_str.h>
9 #include <barvinok/barvinok.h>
14 #include <cloog/isl/cloog.h>
17 static int isl_bool_false
= 0;
18 static int isl_bool_true
= 1;
19 static int isl_bool_error
= -1;
21 enum iscc_op
{ ISCC_READ
, ISCC_SOURCE
, ISCC_VERTICES
,
22 ISCC_LAST
, ISCC_ANY
, ISCC_BEFORE
, ISCC_UNDER
, ISCC_N_OP
};
23 static const char *op_name
[ISCC_N_OP
] = {
24 "read", "source", "vertices", "last", "any", "before", "under" };
25 static enum isl_token_type iscc_op
[ISCC_N_OP
];
27 struct isl_arg_choice iscc_format
[] = {
28 {"isl", ISL_FORMAT_ISL
},
29 {"omega", ISL_FORMAT_OMEGA
},
30 {"polylib", ISL_FORMAT_POLYLIB
},
31 {"latex", ISL_FORMAT_LATEX
},
37 struct barvinok_options
*barvinok
;
41 struct isl_arg iscc_options_arg
[] = {
42 ISL_ARG_CHILD(struct iscc_options
, barvinok
, "barvinok", barvinok_options_arg
,
44 ISL_ARG_CHOICE(struct iscc_options
, format
, 0, "format", \
45 iscc_format
, ISL_FORMAT_ISL
, "output format")
49 ISL_ARG_DEF(iscc_options
, struct iscc_options
, iscc_options_arg
)
51 static void *isl_obj_bool_copy(void *v
)
56 static void isl_obj_bool_free(void *v
)
60 static __isl_give isl_printer
*isl_obj_bool_print(__isl_take isl_printer
*p
,
63 if (v
== &isl_bool_true
)
64 return isl_printer_print_str(p
, "True");
65 else if (v
== &isl_bool_false
)
66 return isl_printer_print_str(p
, "False");
68 return isl_printer_print_str(p
, "Error");
71 static void *isl_obj_bool_add(void *v1
, void *v2
)
76 struct isl_obj_vtable isl_obj_bool_vtable
= {
82 #define isl_obj_bool (&isl_obj_bool_vtable)
84 int *isl_bool_from_int(int res
)
86 return res
< 0 ? &isl_bool_error
: res
? &isl_bool_true
: &isl_bool_false
;
89 int *union_map_is_equal(__isl_take isl_union_map
*map1
,
90 __isl_take isl_union_map
*map2
)
92 int res
= isl_union_map_is_equal(map1
, map2
);
93 isl_union_map_free(map1
);
94 isl_union_map_free(map2
);
95 return isl_bool_from_int(res
);
97 int *union_set_is_equal(__isl_take isl_union_set
*set1
,
98 __isl_take isl_union_set
*set2
)
100 return union_map_is_equal((isl_union_map
*)set1
, (isl_union_map
*)set2
);
103 int *union_map_is_subset(__isl_take isl_union_map
*map1
,
104 __isl_take isl_union_map
*map2
)
106 int res
= isl_union_map_is_subset(map1
, map2
);
107 isl_union_map_free(map1
);
108 isl_union_map_free(map2
);
109 return isl_bool_from_int(res
);
111 int *union_set_is_subset(__isl_take isl_union_set
*set1
,
112 __isl_take isl_union_set
*set2
)
114 return union_map_is_subset((isl_union_map
*)set1
, (isl_union_map
*)set2
);
117 int *union_map_is_strict_subset(__isl_take isl_union_map
*map1
,
118 __isl_take isl_union_map
*map2
)
120 int res
= isl_union_map_is_strict_subset(map1
, map2
);
121 isl_union_map_free(map1
);
122 isl_union_map_free(map2
);
123 return isl_bool_from_int(res
);
125 int *union_set_is_strict_subset(__isl_take isl_union_set
*set1
,
126 __isl_take isl_union_set
*set2
)
128 return union_map_is_strict_subset((isl_union_map
*)set1
,
129 (isl_union_map
*)set2
);
132 int *union_map_is_superset(__isl_take isl_union_map
*map1
,
133 __isl_take isl_union_map
*map2
)
135 return union_map_is_subset(map2
, map1
);
137 int *union_set_is_superset(__isl_take isl_union_set
*set1
,
138 __isl_take isl_union_set
*set2
)
140 return union_set_is_subset(set2
, set1
);
143 int *union_map_is_strict_superset(__isl_take isl_union_map
*map1
,
144 __isl_take isl_union_map
*map2
)
146 return union_map_is_strict_subset(map2
, map1
);
148 int *union_set_is_strict_superset(__isl_take isl_union_set
*set1
,
149 __isl_take isl_union_set
*set2
)
151 return union_set_is_strict_subset(set2
, set1
);
154 extern struct isl_obj_vtable isl_obj_list_vtable
;
155 #define isl_obj_list (&isl_obj_list_vtable)
157 typedef void *(*isc_bin_op_fn
)(void *lhs
, void *rhs
);
159 enum isl_token_type op
;
165 struct isc_named_bin_op
{
167 struct isc_bin_op op
;
171 isl_union_pw_qpolynomial
*upwqp
;
172 isl_union_pw_qpolynomial
*res
;
175 static int eval_at(__isl_take isl_point
*pnt
, void *user
)
177 struct iscc_at
*at
= (struct iscc_at
*) user
;
181 set
= isl_set_from_point(isl_point_copy(pnt
));
182 qp
= isl_union_pw_qpolynomial_eval(
183 isl_union_pw_qpolynomial_copy(at
->upwqp
), pnt
);
185 at
->res
= isl_union_pw_qpolynomial_add(at
->res
,
186 isl_union_pw_qpolynomial_from_pw_qpolynomial(
187 isl_pw_qpolynomial_alloc(set
, qp
)));
192 __isl_give isl_union_pw_qpolynomial
*isl_union_pw_qpolynomial_at(
193 __isl_take isl_union_pw_qpolynomial
*upwqp
,
194 __isl_take isl_union_set
*uset
)
199 at
.res
= isl_union_pw_qpolynomial_zero(isl_union_set_get_dim(uset
));
201 isl_union_set_foreach_point(uset
, eval_at
, &at
);
203 isl_union_pw_qpolynomial_free(upwqp
);
204 isl_union_set_free(uset
);
209 struct iscc_fold_at
{
210 isl_union_pw_qpolynomial_fold
*upwf
;
211 isl_union_pw_qpolynomial
*res
;
214 static int eval_fold_at(__isl_take isl_point
*pnt
, void *user
)
216 struct iscc_fold_at
*at
= (struct iscc_fold_at
*) user
;
220 set
= isl_set_from_point(isl_point_copy(pnt
));
221 qp
= isl_union_pw_qpolynomial_fold_eval(
222 isl_union_pw_qpolynomial_fold_copy(at
->upwf
), pnt
);
224 at
->res
= isl_union_pw_qpolynomial_add(at
->res
,
225 isl_union_pw_qpolynomial_from_pw_qpolynomial(
226 isl_pw_qpolynomial_alloc(set
, qp
)));
231 __isl_give isl_union_pw_qpolynomial
*isl_union_pw_qpolynomial_fold_at(
232 __isl_take isl_union_pw_qpolynomial_fold
*upwf
,
233 __isl_take isl_union_set
*uset
)
235 struct iscc_fold_at at
;
238 at
.res
= isl_union_pw_qpolynomial_zero(isl_union_set_get_dim(uset
));
240 isl_union_set_foreach_point(uset
, eval_fold_at
, &at
);
242 isl_union_pw_qpolynomial_fold_free(upwf
);
243 isl_union_set_free(uset
);
248 static __isl_give isl_union_pw_qpolynomial_fold
*union_pw_qpolynomial_add_union_pw_qpolynomial_fold(
249 __isl_take isl_union_pw_qpolynomial
*upwqp
,
250 __isl_take isl_union_pw_qpolynomial_fold
*upwf
)
252 return isl_union_pw_qpolynomial_fold_add_union_pw_qpolynomial(upwf
,
256 static __isl_give
struct isl_list
*union_map_apply_union_pw_qpolynomial_fold(
257 __isl_take isl_union_map
*umap
,
258 __isl_take isl_union_pw_qpolynomial_fold
*upwf
)
261 struct isl_list
*list
;
264 ctx
= isl_union_map_get_ctx(umap
);
265 list
= isl_list_alloc(ctx
, 2);
269 list
->obj
[0].type
= isl_obj_union_pw_qpolynomial_fold
;
270 list
->obj
[0].v
= isl_union_map_apply_union_pw_qpolynomial_fold(umap
,
272 list
->obj
[1].type
= isl_obj_bool
;
273 list
->obj
[1].v
= tight
? &isl_bool_true
: &isl_bool_false
;
274 if (tight
< 0 || !list
->obj
[0].v
)
279 isl_union_map_free(umap
);
280 isl_union_pw_qpolynomial_fold_free(upwf
);
286 struct isc_bin_op bin_ops
[] = {
287 { '+', isl_obj_union_set
, isl_obj_union_set
,
289 (isc_bin_op_fn
) &isl_union_set_union
},
290 { '+', isl_obj_union_map
, isl_obj_union_map
,
292 (isc_bin_op_fn
) &isl_union_map_union
},
293 { '-', isl_obj_union_set
, isl_obj_union_set
,
295 (isc_bin_op_fn
) &isl_union_set_subtract
},
296 { '-', isl_obj_union_map
, isl_obj_union_map
,
298 (isc_bin_op_fn
) &isl_union_map_subtract
},
299 { '*', isl_obj_union_set
, isl_obj_union_set
,
301 (isc_bin_op_fn
) &isl_union_set_intersect
},
302 { '*', isl_obj_union_map
, isl_obj_union_map
,
304 (isc_bin_op_fn
) &isl_union_map_intersect
},
305 { '*', isl_obj_union_map
, isl_obj_union_set
,
307 (isc_bin_op_fn
) &isl_union_map_intersect_domain
},
308 { '.', isl_obj_union_map
, isl_obj_union_map
,
310 (isc_bin_op_fn
) &isl_union_map_apply_range
},
311 { '.', isl_obj_union_map
, isl_obj_union_pw_qpolynomial
,
312 isl_obj_union_pw_qpolynomial
,
313 (isc_bin_op_fn
) &isl_union_map_apply_union_pw_qpolynomial
},
314 { '.', isl_obj_union_map
, isl_obj_union_pw_qpolynomial_fold
,
316 (isc_bin_op_fn
) &union_map_apply_union_pw_qpolynomial_fold
},
317 { ISL_TOKEN_TO
, isl_obj_union_set
, isl_obj_union_set
,
319 (isc_bin_op_fn
) &isl_union_map_from_domain_and_range
},
320 { '=', isl_obj_union_set
, isl_obj_union_set
, isl_obj_bool
,
321 (isc_bin_op_fn
) &union_set_is_equal
},
322 { '=', isl_obj_union_map
, isl_obj_union_map
, isl_obj_bool
,
323 (isc_bin_op_fn
) &union_map_is_equal
},
324 { ISL_TOKEN_LE
, isl_obj_union_set
, isl_obj_union_set
,
325 isl_obj_bool
, (isc_bin_op_fn
) &union_set_is_subset
},
326 { ISL_TOKEN_LE
, isl_obj_union_map
, isl_obj_union_map
,
327 isl_obj_bool
, (isc_bin_op_fn
) &union_map_is_subset
},
328 { ISL_TOKEN_LT
, isl_obj_union_set
, isl_obj_union_set
,
329 isl_obj_bool
, (isc_bin_op_fn
) &union_set_is_strict_subset
},
330 { ISL_TOKEN_LT
, isl_obj_union_map
, isl_obj_union_map
,
331 isl_obj_bool
, (isc_bin_op_fn
) &union_map_is_strict_subset
},
332 { ISL_TOKEN_GE
, isl_obj_union_set
, isl_obj_union_set
,
333 isl_obj_bool
, (isc_bin_op_fn
) &union_set_is_superset
},
334 { ISL_TOKEN_GE
, isl_obj_union_map
, isl_obj_union_map
,
335 isl_obj_bool
, (isc_bin_op_fn
) &union_map_is_superset
},
336 { ISL_TOKEN_GT
, isl_obj_union_set
, isl_obj_union_set
,
337 isl_obj_bool
, (isc_bin_op_fn
) &union_set_is_strict_superset
},
338 { ISL_TOKEN_GT
, isl_obj_union_map
, isl_obj_union_map
,
339 isl_obj_bool
, (isc_bin_op_fn
) &union_map_is_strict_superset
},
340 { ISL_TOKEN_LEX_LE
, isl_obj_union_set
, isl_obj_union_set
,
342 (isc_bin_op_fn
) &isl_union_set_lex_le_union_set
},
343 { ISL_TOKEN_LEX_LT
, isl_obj_union_set
, isl_obj_union_set
,
345 (isc_bin_op_fn
) &isl_union_set_lex_lt_union_set
},
346 { ISL_TOKEN_LEX_GE
, isl_obj_union_set
, isl_obj_union_set
,
348 (isc_bin_op_fn
) &isl_union_set_lex_ge_union_set
},
349 { ISL_TOKEN_LEX_GT
, isl_obj_union_set
, isl_obj_union_set
,
351 (isc_bin_op_fn
) &isl_union_set_lex_gt_union_set
},
352 { ISL_TOKEN_LEX_LE
, isl_obj_union_map
, isl_obj_union_map
,
354 (isc_bin_op_fn
) &isl_union_map_lex_le_union_map
},
355 { ISL_TOKEN_LEX_LT
, isl_obj_union_map
, isl_obj_union_map
,
357 (isc_bin_op_fn
) &isl_union_map_lex_lt_union_map
},
358 { ISL_TOKEN_LEX_GE
, isl_obj_union_map
, isl_obj_union_map
,
360 (isc_bin_op_fn
) &isl_union_map_lex_ge_union_map
},
361 { ISL_TOKEN_LEX_GT
, isl_obj_union_map
, isl_obj_union_map
,
363 (isc_bin_op_fn
) &isl_union_map_lex_gt_union_map
},
364 { '.', isl_obj_union_pw_qpolynomial_fold
,
365 isl_obj_union_pw_qpolynomial_fold
,
366 isl_obj_union_pw_qpolynomial_fold
,
367 (isc_bin_op_fn
) &isl_union_pw_qpolynomial_fold_fold
},
368 { '+', isl_obj_union_pw_qpolynomial
, isl_obj_union_pw_qpolynomial
,
369 isl_obj_union_pw_qpolynomial
,
370 (isc_bin_op_fn
) &isl_union_pw_qpolynomial_add
},
371 { '+', isl_obj_union_pw_qpolynomial
,
372 isl_obj_union_pw_qpolynomial_fold
,
373 isl_obj_union_pw_qpolynomial_fold
,
374 (isc_bin_op_fn
) &union_pw_qpolynomial_add_union_pw_qpolynomial_fold
},
375 { '+', isl_obj_union_pw_qpolynomial_fold
,
376 isl_obj_union_pw_qpolynomial
,
377 isl_obj_union_pw_qpolynomial_fold
,
378 (isc_bin_op_fn
) &isl_union_pw_qpolynomial_fold_add_union_pw_qpolynomial
},
379 { '-', isl_obj_union_pw_qpolynomial
, isl_obj_union_pw_qpolynomial
,
380 isl_obj_union_pw_qpolynomial
,
381 (isc_bin_op_fn
) &isl_union_pw_qpolynomial_sub
},
382 { '*', isl_obj_union_pw_qpolynomial
, isl_obj_union_pw_qpolynomial
,
383 isl_obj_union_pw_qpolynomial
,
384 (isc_bin_op_fn
) &isl_union_pw_qpolynomial_mul
},
385 { '*', isl_obj_union_pw_qpolynomial
, isl_obj_union_set
,
386 isl_obj_union_pw_qpolynomial
,
387 (isc_bin_op_fn
) &isl_union_pw_qpolynomial_intersect_domain
},
388 { '*', isl_obj_union_pw_qpolynomial_fold
, isl_obj_union_set
,
389 isl_obj_union_pw_qpolynomial_fold
,
390 (isc_bin_op_fn
) &isl_union_pw_qpolynomial_fold_intersect_domain
},
391 { '@', isl_obj_union_pw_qpolynomial
, isl_obj_union_set
,
392 isl_obj_union_pw_qpolynomial
,
393 (isc_bin_op_fn
) &isl_union_pw_qpolynomial_at
},
394 { '@', isl_obj_union_pw_qpolynomial_fold
, isl_obj_union_set
,
395 isl_obj_union_pw_qpolynomial
,
396 (isc_bin_op_fn
) &isl_union_pw_qpolynomial_fold_at
},
397 { '%', isl_obj_union_set
, isl_obj_union_set
,
399 (isc_bin_op_fn
) &isl_union_set_gist
},
400 { '%', isl_obj_union_map
, isl_obj_union_map
,
402 (isc_bin_op_fn
) &isl_union_map_gist
},
403 { '%', isl_obj_union_pw_qpolynomial
, isl_obj_union_set
,
404 isl_obj_union_pw_qpolynomial
,
405 (isc_bin_op_fn
) &isl_union_pw_qpolynomial_gist
},
406 { '%', isl_obj_union_pw_qpolynomial_fold
, isl_obj_union_set
,
407 isl_obj_union_pw_qpolynomial_fold
,
408 (isc_bin_op_fn
) &isl_union_pw_qpolynomial_fold_gist
},
409 { '+', isl_obj_str
, isl_obj_str
, isl_obj_str
,
410 (isc_bin_op_fn
) &isl_str_concat
},
413 struct isc_named_bin_op named_bin_ops
[] = {
414 { "cross", { -1, isl_obj_union_set
, isl_obj_union_set
,
416 (isc_bin_op_fn
) &isl_union_set_product
} },
417 { "cross", { -1, isl_obj_union_map
, isl_obj_union_map
,
419 (isc_bin_op_fn
) &isl_union_map_product
} },
423 __isl_give isl_set
*union_set_sample(__isl_take isl_union_set
*uset
)
425 return isl_set_from_basic_set(isl_union_set_sample(uset
));
428 __isl_give isl_map
*union_map_sample(__isl_take isl_union_map
*umap
)
430 return isl_map_from_basic_map(isl_union_map_sample(umap
));
433 static __isl_give
struct isl_list
*union_pw_qpolynomial_upper_bound(
434 __isl_take isl_union_pw_qpolynomial
*upwqp
)
437 struct isl_list
*list
;
440 ctx
= isl_union_pw_qpolynomial_get_ctx(upwqp
);
441 list
= isl_list_alloc(ctx
, 2);
445 list
->obj
[0].type
= isl_obj_union_pw_qpolynomial_fold
;
446 list
->obj
[0].v
= isl_union_pw_qpolynomial_bound(upwqp
,
447 isl_fold_max
, &tight
);
448 list
->obj
[1].type
= isl_obj_bool
;
449 list
->obj
[1].v
= tight
? &isl_bool_true
: &isl_bool_false
;
450 if (tight
< 0 || !list
->obj
[0].v
)
455 isl_union_pw_qpolynomial_free(upwqp
);
462 void *map_codegen(void *arg
)
465 isl_union_map
*umap
= (isl_union_map
*)arg
;
466 isl_ctx
*ctx
= isl_union_map_get_ctx(umap
);
468 CloogOptions
*options
;
469 CloogDomain
*context
;
470 CloogUnionDomain
*ud
;
472 struct clast_stmt
*stmt
;
474 state
= cloog_isl_state_malloc(ctx
);
475 options
= cloog_options_malloc(state
);
476 options
->language
= LANGUAGE_C
;
477 options
->strides
= 1;
479 ud
= cloog_union_domain_from_isl_union_map(isl_union_map_copy(umap
));
481 dim
= isl_union_map_get_dim(umap
);
482 context
= cloog_domain_from_isl_set(isl_set_universe(dim
));
484 input
= cloog_input_alloc(context
, ud
);
486 stmt
= cloog_clast_create_from_input(input
, options
);
487 clast_pprint(stdout
, stmt
, 0, options
);
488 cloog_clast_free(stmt
);
491 cloog_options_free(options
);
492 cloog_state_free(state
);
493 isl_union_map_free(umap
);
497 void *set_codegen(void *arg
)
500 isl_union_set
*uset
= (isl_union_set
*)arg
;
501 isl_ctx
*ctx
= isl_union_set_get_ctx(uset
);
503 CloogOptions
*options
;
504 CloogDomain
*context
;
505 CloogUnionDomain
*ud
;
507 struct clast_stmt
*stmt
;
509 state
= cloog_isl_state_malloc(ctx
);
510 options
= cloog_options_malloc(state
);
511 options
->language
= LANGUAGE_C
;
512 options
->strides
= 1;
514 ud
= cloog_union_domain_from_isl_union_set(isl_union_set_copy(uset
));
516 dim
= isl_union_set_get_dim(uset
);
517 context
= cloog_domain_from_isl_set(isl_set_universe(dim
));
519 input
= cloog_input_alloc(context
, ud
);
521 stmt
= cloog_clast_create_from_input(input
, options
);
522 clast_pprint(stdout
, stmt
, 0, options
);
523 cloog_clast_free(stmt
);
526 cloog_options_free(options
);
527 cloog_state_free(state
);
528 isl_union_set_free(uset
);
533 typedef void *(*isc_un_op_fn
)(void *arg
);
535 enum isl_token_type op
;
540 struct isc_named_un_op
{
544 struct isc_named_un_op named_un_ops
[] = {
545 {"aff", { -1, isl_obj_union_map
, isl_obj_union_map
,
546 (isc_un_op_fn
) &isl_union_map_affine_hull
} },
547 {"aff", { -1, isl_obj_union_set
, isl_obj_union_set
,
548 (isc_un_op_fn
) &isl_union_set_affine_hull
} },
549 {"card", { -1, isl_obj_union_set
,
550 isl_obj_union_pw_qpolynomial
,
551 (isc_un_op_fn
) &isl_union_set_card
} },
552 {"card", { -1, isl_obj_union_map
,
553 isl_obj_union_pw_qpolynomial
,
554 (isc_un_op_fn
) &isl_union_map_card
} },
555 {"coalesce", { -1, isl_obj_union_set
, isl_obj_union_set
,
556 (isc_un_op_fn
) &isl_union_set_coalesce
} },
557 {"coalesce", { -1, isl_obj_union_map
, isl_obj_union_map
,
558 (isc_un_op_fn
) &isl_union_map_coalesce
} },
559 {"coalesce", { -1, isl_obj_union_pw_qpolynomial
,
560 isl_obj_union_pw_qpolynomial
,
561 (isc_un_op_fn
) &isl_union_pw_qpolynomial_coalesce
} },
562 {"coalesce", { -1, isl_obj_union_pw_qpolynomial_fold
,
563 isl_obj_union_pw_qpolynomial_fold
,
564 (isc_un_op_fn
) &isl_union_pw_qpolynomial_fold_coalesce
} },
566 {"codegen", { -1, isl_obj_union_set
, isl_obj_none
,
568 {"codegen", { -1, isl_obj_union_map
, isl_obj_none
,
571 {"deltas", { -1, isl_obj_union_map
, isl_obj_union_set
,
572 (isc_un_op_fn
) &isl_union_map_deltas
} },
573 {"dom", { -1, isl_obj_union_map
, isl_obj_union_set
,
574 (isc_un_op_fn
) &isl_union_map_domain
} },
575 {"dom", { -1, isl_obj_union_pw_qpolynomial
, isl_obj_union_set
,
576 (isc_un_op_fn
) &isl_union_pw_qpolynomial_domain
} },
577 {"dom", { -1, isl_obj_union_pw_qpolynomial_fold
,
579 (isc_un_op_fn
) &isl_union_pw_qpolynomial_fold_domain
} },
580 {"ran", { -1, isl_obj_union_map
, isl_obj_union_set
,
581 (isc_un_op_fn
) &isl_union_map_range
} },
582 {"lexmin", { -1, isl_obj_union_map
, isl_obj_union_map
,
583 (isc_un_op_fn
) &isl_union_map_lexmin
} },
584 {"lexmax", { -1, isl_obj_union_map
, isl_obj_union_map
,
585 (isc_un_op_fn
) &isl_union_map_lexmax
} },
586 {"lexmin", { -1, isl_obj_union_set
, isl_obj_union_set
,
587 (isc_un_op_fn
) &isl_union_set_lexmin
} },
588 {"lexmax", { -1, isl_obj_union_set
, isl_obj_union_set
,
589 (isc_un_op_fn
) &isl_union_set_lexmax
} },
590 {"sample", { -1, isl_obj_union_set
, isl_obj_set
,
591 (isc_un_op_fn
) &union_set_sample
} },
592 {"sample", { -1, isl_obj_union_map
, isl_obj_map
,
593 (isc_un_op_fn
) &union_map_sample
} },
594 {"sum", { -1, isl_obj_union_pw_qpolynomial
,
595 isl_obj_union_pw_qpolynomial
,
596 (isc_un_op_fn
) &isl_union_pw_qpolynomial_sum
} },
597 {"ub", { -1, isl_obj_union_pw_qpolynomial
, isl_obj_list
,
598 (isc_un_op_fn
) &union_pw_qpolynomial_upper_bound
} },
599 {"unwrap", { -1, isl_obj_union_set
, isl_obj_union_map
,
600 (isc_un_op_fn
) &isl_union_set_unwrap
} },
601 {"wrap", { -1, isl_obj_union_map
, isl_obj_union_set
,
602 (isc_un_op_fn
) &isl_union_map_wrap
} },
606 struct isl_named_obj
{
611 static void free_obj(struct isl_obj obj
)
613 obj
.type
->free(obj
.v
);
616 static int same_name(const void *entry
, const void *val
)
618 const struct isl_named_obj
*named
= (const struct isl_named_obj
*)entry
;
620 return !strcmp(named
->name
, val
);
623 static int do_assign(struct isl_ctx
*ctx
, struct isl_hash_table
*table
,
624 char *name
, struct isl_obj obj
)
626 struct isl_hash_table_entry
*entry
;
628 struct isl_named_obj
*named
;
630 name_hash
= isl_hash_string(isl_hash_init(), name
);
631 entry
= isl_hash_table_find(ctx
, table
, name_hash
, same_name
, name
, 1);
636 free_obj(named
->obj
);
639 named
= isl_alloc_type(ctx
, struct isl_named_obj
);
654 static struct isl_obj
stored_obj(struct isl_ctx
*ctx
,
655 struct isl_hash_table
*table
, char *name
)
657 struct isl_obj obj
= { isl_obj_none
, NULL
};
658 struct isl_hash_table_entry
*entry
;
661 name_hash
= isl_hash_string(isl_hash_init(), name
);
662 entry
= isl_hash_table_find(ctx
, table
, name_hash
, same_name
, name
, 0);
664 struct isl_named_obj
*named
;
668 fprintf(stderr
, "unknown identifier '%s'\n", name
);
671 obj
.v
= obj
.type
->copy(obj
.v
);
675 static int is_subtype(struct isl_obj obj
, isl_obj_type super
)
677 if (obj
.type
== super
)
679 if (obj
.type
== isl_obj_map
&& super
== isl_obj_union_map
)
681 if (obj
.type
== isl_obj_set
&& super
== isl_obj_union_set
)
683 if (obj
.type
== isl_obj_pw_qpolynomial
&&
684 super
== isl_obj_union_pw_qpolynomial
)
686 if (obj
.type
== isl_obj_pw_qpolynomial_fold
&&
687 super
== isl_obj_union_pw_qpolynomial_fold
)
689 if (obj
.type
== isl_obj_union_set
&& isl_union_set_is_empty(obj
.v
))
691 if (obj
.type
== isl_obj_list
) {
692 struct isl_list
*list
= obj
.v
;
693 if (list
->n
== 2 && list
->obj
[1].type
== isl_obj_bool
)
694 return is_subtype(list
->obj
[0], super
);
696 if (super
== isl_obj_str
)
701 static struct isl_obj
obj_at(struct isl_obj obj
, int i
)
703 struct isl_list
*list
= obj
.v
;
706 obj
.v
= obj
.type
->copy(obj
.v
);
713 static struct isl_obj
convert(isl_ctx
*ctx
, struct isl_obj obj
,
716 if (obj
.type
== type
)
718 if (obj
.type
== isl_obj_map
&& type
== isl_obj_union_map
) {
719 obj
.type
= isl_obj_union_map
;
720 obj
.v
= isl_union_map_from_map(obj
.v
);
723 if (obj
.type
== isl_obj_set
&& type
== isl_obj_union_set
) {
724 obj
.type
= isl_obj_union_set
;
725 obj
.v
= isl_union_set_from_set(obj
.v
);
728 if (obj
.type
== isl_obj_pw_qpolynomial
&&
729 type
== isl_obj_union_pw_qpolynomial
) {
730 obj
.type
= isl_obj_union_pw_qpolynomial
;
731 obj
.v
= isl_union_pw_qpolynomial_from_pw_qpolynomial(obj
.v
);
734 if (obj
.type
== isl_obj_pw_qpolynomial_fold
&&
735 type
== isl_obj_union_pw_qpolynomial_fold
) {
736 obj
.type
= isl_obj_union_pw_qpolynomial_fold
;
737 obj
.v
= isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold(obj
.v
);
740 if (obj
.type
== isl_obj_union_set
&& isl_union_set_is_empty(obj
.v
)) {
741 if (type
== isl_obj_union_map
) {
742 obj
.type
= isl_obj_union_map
;
745 if (type
== isl_obj_union_pw_qpolynomial
) {
746 isl_dim
*dim
= isl_union_set_get_dim(obj
.v
);
747 isl_union_set_free(obj
.v
);
748 obj
.v
= isl_union_pw_qpolynomial_zero(dim
);
749 obj
.type
= isl_obj_union_pw_qpolynomial
;
752 if (type
== isl_obj_union_pw_qpolynomial_fold
) {
753 isl_dim
*dim
= isl_union_set_get_dim(obj
.v
);
754 isl_union_set_free(obj
.v
);
755 obj
.v
= isl_union_pw_qpolynomial_fold_zero(dim
,
757 obj
.type
= isl_obj_union_pw_qpolynomial_fold
;
761 if (obj
.type
== isl_obj_list
) {
762 struct isl_list
*list
= obj
.v
;
763 if (list
->n
== 2 && list
->obj
[1].type
== isl_obj_bool
)
764 return convert(ctx
, obj_at(obj
, 0), type
);
766 if (type
== isl_obj_str
) {
771 p
= isl_printer_to_str(ctx
);
774 p
= obj
.type
->print(p
, obj
.v
);
775 s
= isl_printer_get_str(p
);
778 str
= isl_str_alloc(ctx
);
786 obj
.type
= isl_obj_str
;
792 obj
.type
= isl_obj_none
;
797 static struct isc_bin_op
*read_bin_op_if_available(struct isl_stream
*s
,
801 struct isl_token
*tok
;
803 tok
= isl_stream_next_token(s
);
810 if (bin_ops
[i
].op
!= tok
->type
)
812 if (!is_subtype(lhs
, bin_ops
[i
].lhs
))
820 if (!named_bin_ops
[i
].name
)
822 if (named_bin_ops
[i
].op
.op
!= tok
->type
)
824 if (!is_subtype(lhs
, named_bin_ops
[i
].op
.lhs
))
828 return &named_bin_ops
[i
].op
;
831 isl_stream_push_token(s
, tok
);
836 static struct isc_un_op
*read_prefix_un_op_if_available(struct isl_stream
*s
)
839 struct isl_token
*tok
;
841 tok
= isl_stream_next_token(s
);
846 if (!named_un_ops
[i
].name
)
848 if (named_un_ops
[i
].op
.op
!= tok
->type
)
852 return &named_un_ops
[i
].op
;
855 isl_stream_push_token(s
, tok
);
860 static struct isc_un_op
*find_matching_un_op(struct isc_un_op
*like
,
866 if (!named_un_ops
[i
].name
)
868 if (named_un_ops
[i
].op
.op
!= like
->op
)
870 if (!is_subtype(arg
, named_un_ops
[i
].op
.arg
))
873 return &named_un_ops
[i
].op
;
879 static int is_assign(struct isl_stream
*s
)
881 struct isl_token
*tok
;
882 struct isl_token
*tok2
;
885 tok
= isl_stream_next_token(s
);
888 if (tok
->type
!= ISL_TOKEN_IDENT
) {
889 isl_stream_push_token(s
, tok
);
893 tok2
= isl_stream_next_token(s
);
895 isl_stream_push_token(s
, tok
);
898 assign
= tok2
->type
== ISL_TOKEN_DEF
;
899 isl_stream_push_token(s
, tok2
);
900 isl_stream_push_token(s
, tok
);
905 static struct isl_obj
read_obj(struct isl_stream
*s
,
906 struct isl_hash_table
*table
);
907 static struct isl_obj
read_expr(struct isl_stream
*s
,
908 struct isl_hash_table
*table
);
910 static struct isl_obj
read_un_op_expr(struct isl_stream
*s
,
911 struct isl_hash_table
*table
, struct isc_un_op
*op
)
913 struct isl_obj obj
= { isl_obj_none
, NULL
};
915 obj
= read_obj(s
, table
);
919 op
= find_matching_un_op(op
, obj
);
921 isl_assert(s
->ctx
, op
, goto error
);
922 obj
= convert(s
->ctx
, obj
, op
->arg
);
923 obj
.v
= op
->fn(obj
.v
);
929 obj
.type
= isl_obj_none
;
934 static struct isl_obj
transitive_closure(struct isl_ctx
*ctx
, struct isl_obj obj
)
936 struct isl_list
*list
;
939 if (obj
.type
!= isl_obj_union_map
)
940 obj
= convert(ctx
, obj
, isl_obj_union_map
);
941 isl_assert(ctx
, obj
.type
== isl_obj_union_map
, goto error
);
942 list
= isl_list_alloc(ctx
, 2);
946 list
->obj
[0].type
= isl_obj_union_map
;
947 list
->obj
[0].v
= isl_union_map_transitive_closure(obj
.v
, &exact
);
948 list
->obj
[1].type
= isl_obj_bool
;
949 list
->obj
[1].v
= exact
? &isl_bool_true
: &isl_bool_false
;
951 obj
.type
= isl_obj_list
;
952 if (exact
< 0 || !list
->obj
[0].v
)
958 obj
.type
= isl_obj_none
;
963 static struct isl_obj
obj_at_index(struct isl_stream
*s
, struct isl_obj obj
)
965 struct isl_list
*list
= obj
.v
;
966 struct isl_token
*tok
;
969 tok
= isl_stream_next_token(s
);
970 if (!tok
|| tok
->type
!= ISL_TOKEN_VALUE
) {
971 isl_stream_error(s
, tok
, "expecting index");
973 isl_stream_push_token(s
, tok
);
976 i
= isl_int_get_si(tok
->u
.v
);
978 isl_assert(s
->ctx
, i
< list
->n
, goto error
);
979 if (isl_stream_eat(s
, ']'))
982 return obj_at(obj
, i
);
985 obj
.type
= isl_obj_none
;
990 static struct isl_obj
apply(struct isl_stream
*s
, __isl_take isl_union_map
*umap
,
991 struct isl_hash_table
*table
)
995 obj
= read_expr(s
, table
);
996 isl_assert(s
->ctx
, is_subtype(obj
, isl_obj_union_set
) ||
997 is_subtype(obj
, isl_obj_union_map
), goto error
);
999 if (obj
.type
== isl_obj_list
) {
1000 struct isl_list
*list
= obj
.v
;
1001 if (list
->n
== 2 && list
->obj
[1].type
== isl_obj_bool
)
1002 obj
= obj_at(obj
, 0);
1004 if (obj
.type
== isl_obj_set
)
1005 obj
= convert(s
->ctx
, obj
, isl_obj_union_set
);
1006 else if (obj
.type
== isl_obj_map
)
1007 obj
= convert(s
->ctx
, obj
, isl_obj_union_map
);
1008 if (obj
.type
== isl_obj_union_set
) {
1009 obj
.v
= isl_union_set_apply(obj
.v
, umap
);
1011 obj
.v
= isl_union_map_apply_range(obj
.v
, umap
);
1015 if (isl_stream_eat(s
, ')'))
1020 isl_union_map_free(umap
);
1023 obj
.type
= isl_obj_none
;
1028 static struct isl_obj
apply_fun(struct isl_stream
*s
,
1029 struct isl_obj obj
, struct isl_hash_table
*table
)
1033 arg
= read_expr(s
, table
);
1034 isl_assert(s
->ctx
, is_subtype(arg
, isl_obj_union_map
), goto error
);
1036 if (arg
.type
== isl_obj_list
) {
1037 struct isl_list
*list
= arg
.v
;
1038 if (list
->n
== 2 && list
->obj
[1].type
== isl_obj_bool
)
1039 arg
= obj_at(arg
, 0);
1041 if (arg
.type
== isl_obj_map
)
1042 arg
= convert(s
->ctx
, arg
, isl_obj_union_map
);
1043 if (obj
.type
== isl_obj_union_pw_qpolynomial
) {
1044 obj
.v
= isl_union_map_apply_union_pw_qpolynomial(arg
.v
, obj
.v
);
1046 obj
.type
= isl_obj_list
;
1047 obj
.v
= union_map_apply_union_pw_qpolynomial_fold(arg
.v
, obj
.v
);
1052 if (isl_stream_eat(s
, ')'))
1060 obj
.type
= isl_obj_none
;
1065 struct add_vertex_data
{
1066 struct isl_list
*list
;
1070 static int add_vertex(__isl_take isl_vertex
*vertex
, void *user
)
1072 struct add_vertex_data
*data
= (struct add_vertex_data
*)user
;
1073 isl_basic_set
*expr
;
1075 expr
= isl_vertex_get_expr(vertex
);
1077 data
->list
->obj
[data
->i
].type
= isl_obj_set
;
1078 data
->list
->obj
[data
->i
].v
= isl_set_from_basic_set(expr
);
1081 isl_vertex_free(vertex
);
1086 static int set_vertices(__isl_take isl_set
*set
, void *user
)
1089 isl_basic_set
*hull
;
1090 isl_vertices
*vertices
= NULL
;
1091 struct isl_list
*list
= NULL
;
1093 struct add_vertex_data
*data
= (struct add_vertex_data
*)user
;
1095 set
= isl_set_remove_divs(set
);
1096 hull
= isl_set_convex_hull(set
);
1097 vertices
= isl_basic_set_compute_vertices(hull
);
1098 isl_basic_set_free(hull
);
1102 ctx
= isl_vertices_get_ctx(vertices
);
1103 data
->list
= isl_list_alloc(ctx
, isl_vertices_get_n_vertices(vertices
));
1108 r
= isl_vertices_foreach_vertex(vertices
, &add_vertex
, user
);
1110 data
->list
= isl_list_concat(list
, data
->list
);
1112 isl_vertices_free(vertices
);
1117 isl_vertices_free(vertices
);
1121 static struct isl_obj
vertices(struct isl_stream
*s
,
1122 struct isl_hash_table
*table
)
1126 struct isl_list
*list
= NULL
;
1127 isl_union_set
*uset
;
1128 struct add_vertex_data data
= { NULL
};
1130 obj
= read_expr(s
, table
);
1131 obj
= convert(s
->ctx
, obj
, isl_obj_union_set
);
1132 isl_assert(s
->ctx
, obj
.type
== isl_obj_union_set
, goto error
);
1136 ctx
= isl_union_set_get_ctx(uset
);
1137 list
= isl_list_alloc(ctx
, 0);
1143 if (isl_union_set_foreach_set(uset
, &set_vertices
, &data
) < 0)
1146 isl_union_set_free(uset
);
1148 obj
.type
= isl_obj_list
;
1153 isl_union_set_free(uset
);
1154 isl_list_free(data
.list
);
1156 obj
.type
= isl_obj_none
;
1161 static __isl_give isl_union_map
*read_map(struct isl_stream
*s
,
1162 struct isl_hash_table
*table
)
1166 obj
= read_expr(s
, table
);
1167 obj
= convert(s
->ctx
, obj
, isl_obj_union_map
);
1168 isl_assert(s
->ctx
, obj
.type
== isl_obj_union_map
, goto error
);
1175 static struct isl_obj
last_any(struct isl_stream
*s
,
1176 struct isl_hash_table
*table
, __isl_take isl_union_map
*must_source
,
1177 __isl_take isl_union_map
*may_source
)
1179 struct isl_obj obj
= { isl_obj_none
, NULL
};
1180 isl_union_map
*sink
= NULL
;
1181 isl_union_map
*schedule
= NULL
;
1182 isl_union_map
*may_dep
;
1183 isl_union_map
*must_dep
;
1185 if (isl_stream_eat(s
, iscc_op
[ISCC_BEFORE
]))
1188 sink
= read_map(s
, table
);
1192 if (isl_stream_eat(s
, iscc_op
[ISCC_UNDER
]))
1195 schedule
= read_map(s
, table
);
1199 if (isl_union_map_compute_flow(sink
, must_source
, may_source
,
1200 schedule
, &must_dep
, &may_dep
,
1204 obj
.type
= isl_obj_union_map
;
1205 obj
.v
= isl_union_map_union(must_dep
, may_dep
);
1209 isl_union_map_free(may_source
);
1210 isl_union_map_free(must_source
);
1211 isl_union_map_free(sink
);
1212 isl_union_map_free(schedule
);
1214 obj
.type
= isl_obj_none
;
1219 static struct isl_obj
any(struct isl_stream
*s
, struct isl_hash_table
*table
)
1221 struct isl_obj obj
= { isl_obj_none
, NULL
};
1222 isl_union_map
*must_source
= NULL
;
1223 isl_union_map
*may_source
= NULL
;
1224 isl_union_map
*sink
= NULL
;
1225 isl_union_map
*schedule
= NULL
;
1226 isl_union_map
*may_dep
;
1228 may_source
= read_map(s
, table
);
1232 if (isl_stream_eat_if_available(s
, iscc_op
[ISCC_LAST
])) {
1233 must_source
= read_map(s
, table
);
1236 return last_any(s
, table
, must_source
, may_source
);
1239 if (isl_stream_eat(s
, iscc_op
[ISCC_BEFORE
]))
1242 sink
= read_map(s
, table
);
1246 if (isl_stream_eat(s
, iscc_op
[ISCC_UNDER
]))
1249 schedule
= read_map(s
, table
);
1253 must_source
= isl_union_map_empty(isl_union_map_get_dim(sink
));
1254 if (isl_union_map_compute_flow(sink
, must_source
, may_source
,
1255 schedule
, NULL
, &may_dep
,
1259 obj
.type
= isl_obj_union_map
;
1264 isl_union_map_free(may_source
);
1265 isl_union_map_free(must_source
);
1266 isl_union_map_free(sink
);
1267 isl_union_map_free(schedule
);
1269 obj
.type
= isl_obj_none
;
1274 static struct isl_obj
last(struct isl_stream
*s
, struct isl_hash_table
*table
)
1276 struct isl_obj obj
= { isl_obj_none
, NULL
};
1277 struct isl_list
*list
= NULL
;
1278 isl_union_map
*must_source
= NULL
;
1279 isl_union_map
*may_source
= NULL
;
1280 isl_union_map
*sink
= NULL
;
1281 isl_union_map
*schedule
= NULL
;
1282 isl_union_map
*must_dep
;
1283 isl_union_set
*must_no_source
;
1285 must_source
= read_map(s
, table
);
1289 if (isl_stream_eat_if_available(s
, iscc_op
[ISCC_ANY
])) {
1290 may_source
= read_map(s
, table
);
1293 return last_any(s
, table
, must_source
, may_source
);
1296 list
= isl_list_alloc(s
->ctx
, 2);
1300 if (isl_stream_eat(s
, iscc_op
[ISCC_BEFORE
]))
1303 sink
= read_map(s
, table
);
1307 if (isl_stream_eat(s
, iscc_op
[ISCC_UNDER
]))
1310 schedule
= read_map(s
, table
);
1314 may_source
= isl_union_map_empty(isl_union_map_get_dim(sink
));
1315 if (isl_union_map_compute_flow(sink
, must_source
, may_source
,
1316 schedule
, &must_dep
, NULL
,
1317 &must_no_source
, NULL
) < 0)
1320 list
->obj
[0].type
= isl_obj_union_map
;
1321 list
->obj
[0].v
= must_dep
;
1322 list
->obj
[1].type
= isl_obj_union_set
;
1323 list
->obj
[1].v
= must_no_source
;
1326 obj
.type
= isl_obj_list
;
1330 isl_list_free(list
);
1331 isl_union_map_free(may_source
);
1332 isl_union_map_free(must_source
);
1333 isl_union_map_free(sink
);
1334 isl_union_map_free(schedule
);
1336 obj
.type
= isl_obj_none
;
1341 static struct isl_obj
power(struct isl_stream
*s
, struct isl_obj obj
)
1343 struct isl_token
*tok
;
1345 if (isl_stream_eat_if_available(s
, '+'))
1346 return transitive_closure(s
->ctx
, obj
);
1348 tok
= isl_stream_next_token(s
);
1349 if (!tok
|| tok
->type
!= ISL_TOKEN_VALUE
|| isl_int_cmp_si(tok
->u
.v
, -1)) {
1350 isl_stream_error(s
, tok
, "expecting -1");
1352 isl_stream_push_token(s
, tok
);
1355 isl_token_free(tok
);
1356 isl_assert(s
->ctx
, is_subtype(obj
, isl_obj_union_map
), goto error
);
1357 if (obj
.type
!= isl_obj_union_map
)
1358 obj
= convert(s
->ctx
, obj
, isl_obj_union_map
);
1360 obj
.v
= isl_union_map_reverse(obj
.v
);
1367 obj
.type
= isl_obj_none
;
1372 static struct isl_obj
read_from_file(struct isl_stream
*s
)
1375 struct isl_token
*tok
;
1376 struct isl_stream
*s_file
;
1379 tok
= isl_stream_next_token(s
);
1380 if (!tok
|| tok
->type
!= ISL_TOKEN_STRING
) {
1381 isl_stream_error(s
, tok
, "expecting filename");
1382 isl_token_free(tok
);
1386 file
= fopen(tok
->u
.s
, "r");
1387 isl_token_free(tok
);
1388 isl_assert(s
->ctx
, file
, goto error
);
1390 s_file
= isl_stream_new_file(s
->ctx
, file
);
1396 obj
= isl_stream_read_obj(s_file
);
1398 isl_stream_free(s_file
);
1403 obj
.type
= isl_obj_none
;
1408 static struct isl_obj
read_string_if_available(struct isl_stream
*s
)
1410 struct isl_token
*tok
;
1411 struct isl_obj obj
= { isl_obj_none
, NULL
};
1413 tok
= isl_stream_next_token(s
);
1416 if (tok
->type
== ISL_TOKEN_STRING
) {
1418 str
= isl_str_alloc(s
->ctx
);
1421 str
->s
= strdup(tok
->u
.s
);
1422 isl_token_free(tok
);
1424 obj
.type
= isl_obj_str
;
1426 isl_stream_push_token(s
, tok
);
1429 isl_token_free(tok
);
1433 static struct isl_obj
read_obj(struct isl_stream
*s
,
1434 struct isl_hash_table
*table
)
1436 struct isl_obj obj
= { isl_obj_none
, NULL
};
1438 struct isc_un_op
*op
= NULL
;
1440 obj
= read_string_if_available(s
);
1443 if (isl_stream_eat_if_available(s
, '(')) {
1444 obj
= read_expr(s
, table
);
1445 if (!obj
.v
|| isl_stream_eat(s
, ')'))
1448 op
= read_prefix_un_op_if_available(s
);
1450 return read_un_op_expr(s
, table
, op
);
1452 if (isl_stream_eat_if_available(s
, iscc_op
[ISCC_READ
]))
1453 return read_from_file(s
);
1454 if (isl_stream_eat_if_available(s
, iscc_op
[ISCC_VERTICES
]))
1455 return vertices(s
, table
);
1456 if (isl_stream_eat_if_available(s
, iscc_op
[ISCC_ANY
]))
1457 return any(s
, table
);
1458 if (isl_stream_eat_if_available(s
, iscc_op
[ISCC_LAST
]))
1459 return last(s
, table
);
1461 name
= isl_stream_read_ident_if_available(s
);
1463 obj
= stored_obj(s
->ctx
, table
, name
);
1465 obj
= isl_stream_read_obj(s
);
1470 if (isl_stream_eat_if_available(s
, '^'))
1471 obj
= power(s
, obj
);
1472 else if (obj
.type
== isl_obj_list
&& isl_stream_eat_if_available(s
, '['))
1473 obj
= obj_at_index(s
, obj
);
1474 else if (is_subtype(obj
, isl_obj_union_map
) &&
1475 isl_stream_eat_if_available(s
, '(')) {
1476 obj
= convert(s
->ctx
, obj
, isl_obj_union_map
);
1477 obj
= apply(s
, obj
.v
, table
);
1478 } else if (is_subtype(obj
, isl_obj_union_pw_qpolynomial
) &&
1479 isl_stream_eat_if_available(s
, '(')) {
1480 obj
= convert(s
->ctx
, obj
, isl_obj_union_pw_qpolynomial
);
1481 obj
= apply_fun(s
, obj
, table
);
1482 } else if (is_subtype(obj
, isl_obj_union_pw_qpolynomial_fold
) &&
1483 isl_stream_eat_if_available(s
, '(')) {
1484 obj
= convert(s
->ctx
, obj
, isl_obj_union_pw_qpolynomial_fold
);
1485 obj
= apply_fun(s
, obj
, table
);
1491 obj
.type
= isl_obj_none
;
1496 static struct isc_bin_op
*find_matching_bin_op(struct isc_bin_op
*like
,
1497 struct isl_obj lhs
, struct isl_obj rhs
)
1501 for (i
= 0; ; ++i
) {
1504 if (bin_ops
[i
].op
!= like
->op
)
1506 if (!is_subtype(lhs
, bin_ops
[i
].lhs
))
1508 if (!is_subtype(rhs
, bin_ops
[i
].rhs
))
1514 for (i
= 0; ; ++i
) {
1515 if (!named_bin_ops
[i
].name
)
1517 if (named_bin_ops
[i
].op
.op
!= like
->op
)
1519 if (!is_subtype(lhs
, named_bin_ops
[i
].op
.lhs
))
1521 if (!is_subtype(rhs
, named_bin_ops
[i
].op
.rhs
))
1524 return &named_bin_ops
[i
].op
;
1530 static struct isl_obj
read_expr(struct isl_stream
*s
,
1531 struct isl_hash_table
*table
)
1533 struct isl_obj obj
= { isl_obj_none
, NULL
};
1534 struct isl_obj right_obj
= { isl_obj_none
, NULL
};
1536 obj
= read_obj(s
, table
);
1538 struct isc_bin_op
*op
= NULL
;
1540 op
= read_bin_op_if_available(s
, obj
);
1544 right_obj
= read_obj(s
, table
);
1546 op
= find_matching_bin_op(op
, obj
, right_obj
);
1548 isl_assert(s
->ctx
, op
, goto error
);
1549 obj
= convert(s
->ctx
, obj
, op
->lhs
);
1550 right_obj
= convert(s
->ctx
, right_obj
, op
->rhs
);
1551 obj
.v
= op
->fn(obj
.v
, right_obj
.v
);
1557 free_obj(right_obj
);
1559 obj
.type
= isl_obj_none
;
1564 static __isl_give isl_printer
*source_file(struct isl_stream
*s
,
1565 struct isl_hash_table
*table
, __isl_take isl_printer
*p
);
1567 static __isl_give isl_printer
*read_line(struct isl_stream
*s
,
1568 struct isl_hash_table
*table
, __isl_take isl_printer
*p
)
1570 struct isl_obj obj
= { isl_obj_none
, NULL
};
1573 struct isc_bin_op
*op
= NULL
;
1577 if (isl_stream_is_empty(s
))
1580 if (isl_stream_eat_if_available(s
, iscc_op
[ISCC_SOURCE
]))
1581 return source_file(s
, table
, p
);
1583 assign
= is_assign(s
);
1585 lhs
= isl_stream_read_ident_if_available(s
);
1586 if (isl_stream_eat(s
, ISL_TOKEN_DEF
))
1590 obj
= read_expr(s
, table
);
1591 if (obj
.type
== isl_obj_none
|| obj
.v
== NULL
)
1593 if (isl_stream_eat(s
, ';'))
1597 if (do_assign(s
->ctx
, table
, lhs
, obj
))
1600 p
= obj
.type
->print(p
, obj
.v
);
1601 p
= isl_printer_end_line(p
);
1607 isl_stream_flush_tokens(s
);
1608 isl_stream_skip_line(s
);
1614 int free_cb(void **entry
, void *user
)
1616 struct isl_named_obj
*named
= *entry
;
1618 free_obj(named
->obj
);
1625 static void register_named_ops(struct isl_stream
*s
)
1629 for (i
= 0; i
< ISCC_N_OP
; ++i
) {
1630 iscc_op
[i
] = isl_stream_register_keyword(s
, op_name
[i
]);
1631 assert(iscc_op
[i
] != ISL_TOKEN_ERROR
);
1634 for (i
= 0; ; ++i
) {
1635 if (!named_un_ops
[i
].name
)
1637 named_un_ops
[i
].op
.op
= isl_stream_register_keyword(s
,
1638 named_un_ops
[i
].name
);
1639 assert(named_un_ops
[i
].op
.op
!= ISL_TOKEN_ERROR
);
1642 for (i
= 0; ; ++i
) {
1643 if (!named_bin_ops
[i
].name
)
1645 named_bin_ops
[i
].op
.op
= isl_stream_register_keyword(s
,
1646 named_bin_ops
[i
].name
);
1647 assert(named_bin_ops
[i
].op
.op
!= ISL_TOKEN_ERROR
);
1651 static __isl_give isl_printer
*source_file(struct isl_stream
*s
,
1652 struct isl_hash_table
*table
, __isl_take isl_printer
*p
)
1654 struct isl_token
*tok
;
1655 struct isl_stream
*s_file
;
1658 tok
= isl_stream_next_token(s
);
1659 if (!tok
|| tok
->type
!= ISL_TOKEN_STRING
) {
1660 isl_stream_error(s
, tok
, "expecting filename");
1661 isl_token_free(tok
);
1665 file
= fopen(tok
->u
.s
, "r");
1666 isl_token_free(tok
);
1667 isl_assert(s
->ctx
, file
, return p
);
1669 s_file
= isl_stream_new_file(s
->ctx
, file
);
1675 register_named_ops(s_file
);
1677 while (!s_file
->eof
)
1678 p
= read_line(s_file
, table
, p
);
1680 isl_stream_free(s_file
);
1683 isl_stream_eat(s
, ';');
1688 int main(int argc
, char **argv
)
1690 struct isl_ctx
*ctx
;
1691 struct isl_stream
*s
;
1692 struct isl_hash_table
*table
;
1693 struct iscc_options
*options
;
1696 options
= iscc_options_new_with_defaults();
1698 argc
= iscc_options_parse(options
, argc
, argv
, ISL_ARG_ALL
);
1700 ctx
= isl_ctx_alloc_with_options(iscc_options_arg
, options
);
1701 s
= isl_stream_new_file(ctx
, stdin
);
1703 table
= isl_hash_table_alloc(ctx
, 10);
1705 p
= isl_printer_to_file(ctx
, stdout
);
1706 p
= isl_printer_set_output_format(p
, options
->format
);
1709 register_named_ops(s
);
1712 p
= read_line(s
, table
, p
);
1715 isl_printer_free(p
);
1716 isl_hash_table_foreach(ctx
, table
, free_cb
, NULL
);
1717 isl_hash_table_free(ctx
, table
);