5 #include <isl_stream.h>
6 #include <barvinok/barvinok.h>
8 typedef void *(*isc_bin_op_fn
)(void *lhs
, void *rhs
);
10 enum isl_token_type op
;
17 struct isc_bin_op bin_ops
[] = {
18 { '+', isl_obj_set
, isl_obj_set
,
20 (isc_bin_op_fn
) &isl_set_union
},
21 { '+', isl_obj_map
, isl_obj_map
,
23 (isc_bin_op_fn
) &isl_map_union
},
24 { '-', isl_obj_set
, isl_obj_set
,
26 (isc_bin_op_fn
) &isl_set_subtract
},
27 { '-', isl_obj_map
, isl_obj_map
,
29 (isc_bin_op_fn
) &isl_map_subtract
},
30 { '*', isl_obj_set
, isl_obj_set
,
32 (isc_bin_op_fn
) &isl_set_intersect
},
33 { '*', isl_obj_map
, isl_obj_map
,
35 (isc_bin_op_fn
) &isl_map_intersect
},
36 { '+', isl_obj_pw_qpolynomial
, isl_obj_pw_qpolynomial
,
37 isl_obj_pw_qpolynomial
,
38 (isc_bin_op_fn
) &isl_pw_qpolynomial_add
},
39 { '-', isl_obj_pw_qpolynomial
, isl_obj_pw_qpolynomial
,
40 isl_obj_pw_qpolynomial
,
41 (isc_bin_op_fn
) &isl_pw_qpolynomial_sub
},
42 { '*', isl_obj_pw_qpolynomial
, isl_obj_pw_qpolynomial
,
43 isl_obj_pw_qpolynomial
,
44 (isc_bin_op_fn
) &isl_pw_qpolynomial_mul
},
48 __isl_give isl_set
*set_sample(__isl_take isl_set
*set
)
50 return isl_set_from_basic_set(isl_set_sample(set
));
53 __isl_give isl_map
*map_sample(__isl_take isl_map
*map
)
55 return isl_map_from_basic_map(isl_map_sample(map
));
58 typedef void *(*isc_un_op_fn
)(void *arg
);
60 enum isl_token_type op
;
65 struct isc_named_un_op
{
69 struct isc_named_un_op named_un_ops
[] = {
70 {"card", { -1, isl_obj_set
, isl_obj_pw_qpolynomial
,
71 (isc_un_op_fn
) &isl_set_card
} },
72 {"card", { -1, isl_obj_map
, isl_obj_pw_qpolynomial
,
73 (isc_un_op_fn
) &isl_map_card
} },
74 {"dom", { -1, isl_obj_map
, isl_obj_set
,
75 (isc_un_op_fn
) &isl_map_domain
} },
76 {"ran", { -1, isl_obj_map
, isl_obj_set
,
77 (isc_un_op_fn
) &isl_map_range
} },
78 {"lexmin", { -1, isl_obj_map
, isl_obj_map
,
79 (isc_un_op_fn
) &isl_map_lexmin
} },
80 {"lexmax", { -1, isl_obj_map
, isl_obj_map
,
81 (isc_un_op_fn
) &isl_map_lexmax
} },
82 {"lexmin", { -1, isl_obj_set
, isl_obj_set
,
83 (isc_un_op_fn
) &isl_set_lexmin
} },
84 {"lexmax", { -1, isl_obj_set
, isl_obj_set
,
85 (isc_un_op_fn
) &isl_set_lexmax
} },
86 {"sample", { -1, isl_obj_set
, isl_obj_set
,
87 (isc_un_op_fn
) &set_sample
} },
88 {"sample", { -1, isl_obj_map
, isl_obj_map
,
89 (isc_un_op_fn
) &map_sample
} },
93 struct isl_named_obj
{
98 static void free_obj(struct isl_obj obj
)
100 obj
.type
->free(obj
.v
);
103 static int same_name(const void *entry
, const void *val
)
105 const struct isl_named_obj
*named
= (const struct isl_named_obj
*)entry
;
107 return !strcmp(named
->name
, val
);
110 static int do_assign(struct isl_ctx
*ctx
, struct isl_hash_table
*table
,
111 char *name
, struct isl_obj obj
)
113 struct isl_hash_table_entry
*entry
;
115 struct isl_named_obj
*named
;
117 name_hash
= isl_hash_string(isl_hash_init(), name
);
118 entry
= isl_hash_table_find(ctx
, table
, name_hash
, same_name
, name
, 1);
123 free_obj(named
->obj
);
126 named
= isl_alloc_type(ctx
, struct isl_named_obj
);
141 static struct isl_obj
stored_obj(struct isl_ctx
*ctx
,
142 struct isl_hash_table
*table
, char *name
)
144 struct isl_obj obj
= { isl_obj_none
, NULL
};
145 struct isl_hash_table_entry
*entry
;
148 name_hash
= isl_hash_string(isl_hash_init(), name
);
149 entry
= isl_hash_table_find(ctx
, table
, name_hash
, same_name
, name
, 0);
151 struct isl_named_obj
*named
;
157 obj
.v
= obj
.type
->copy(obj
.v
);
161 static struct isc_bin_op
*read_bin_op_if_available(struct isl_stream
*s
,
165 struct isl_token
*tok
;
167 tok
= isl_stream_next_token(s
);
174 if (bin_ops
[i
].op
!= tok
->type
)
176 if (bin_ops
[i
].lhs
!= lhs
)
183 isl_stream_push_token(s
, tok
);
188 static struct isc_un_op
*read_prefix_un_op_if_available(struct isl_stream
*s
)
191 struct isl_token
*tok
;
193 tok
= isl_stream_next_token(s
);
198 if (!named_un_ops
[i
].op
.op
)
200 if (named_un_ops
[i
].op
.op
!= tok
->type
)
204 return &named_un_ops
[i
].op
;
207 isl_stream_push_token(s
, tok
);
212 static struct isc_un_op
*find_matching_un_op(struct isc_un_op
*like
,
218 if (!named_un_ops
[i
].op
.op
)
220 if (named_un_ops
[i
].op
.op
!= like
->op
)
222 if (named_un_ops
[i
].op
.arg
!= arg
)
225 return &named_un_ops
[i
].op
;
231 static int is_assign(struct isl_stream
*s
)
233 struct isl_token
*tok
;
234 struct isl_token
*tok2
;
237 tok
= isl_stream_next_token(s
);
240 if (tok
->type
!= ISL_TOKEN_IDENT
) {
241 isl_stream_push_token(s
, tok
);
245 tok2
= isl_stream_next_token(s
);
247 isl_stream_push_token(s
, tok
);
250 assign
= tok2
->type
== ISL_TOKEN_DEF
;
251 isl_stream_push_token(s
, tok2
);
252 isl_stream_push_token(s
, tok
);
257 static struct isl_obj
read_obj(struct isl_stream
*s
,
258 struct isl_hash_table
*table
);
259 static struct isl_obj
read_expr(struct isl_stream
*s
,
260 struct isl_hash_table
*table
);
262 static struct isl_obj
read_un_op_expr(struct isl_stream
*s
,
263 struct isl_hash_table
*table
, struct isc_un_op
*op
)
265 struct isl_obj obj
= { isl_obj_none
, NULL
};
267 obj
= read_obj(s
, table
);
269 op
= find_matching_un_op(op
, obj
.type
);
271 isl_assert(s
->ctx
, op
, goto error
);
272 obj
.v
= op
->fn(obj
.v
);
278 obj
.type
= isl_obj_none
;
283 static struct isl_obj
read_obj(struct isl_stream
*s
,
284 struct isl_hash_table
*table
)
286 struct isl_obj obj
= { isl_obj_none
, NULL
};
288 struct isc_un_op
*op
= NULL
;
290 if (isl_stream_eat_if_available(s
, '(')) {
291 obj
= read_expr(s
, table
);
292 if (isl_stream_eat(s
, ')'))
297 op
= read_prefix_un_op_if_available(s
);
299 return read_un_op_expr(s
, table
, op
);
301 name
= isl_stream_read_ident_if_available(s
);
303 obj
= stored_obj(s
->ctx
, table
, name
);
305 obj
= isl_stream_read_obj(s
);
312 obj
.type
= isl_obj_none
;
317 static struct isl_obj
read_expr(struct isl_stream
*s
,
318 struct isl_hash_table
*table
)
320 struct isl_obj obj
= { isl_obj_none
, NULL
};
321 struct isl_obj right_obj
= { isl_obj_none
, NULL
};
323 obj
= read_obj(s
, table
);
325 struct isc_bin_op
*op
= NULL
;
327 op
= read_bin_op_if_available(s
, obj
.type
);
331 right_obj
= read_obj(s
, table
);
333 isl_assert(s
->ctx
, right_obj
.type
== op
->rhs
, goto error
);
334 obj
.v
= op
->fn(obj
.v
, right_obj
.v
);
342 obj
.type
= isl_obj_none
;
347 static void read_line(struct isl_stream
*s
, struct isl_hash_table
*table
)
349 struct isl_obj obj
= { isl_obj_none
, NULL
};
352 struct isc_bin_op
*op
= NULL
;
354 if (isl_stream_is_empty(s
))
357 assign
= is_assign(s
);
359 lhs
= isl_stream_read_ident_if_available(s
);
360 if (isl_stream_eat(s
, ISL_TOKEN_DEF
))
364 obj
= read_expr(s
, table
);
365 if (obj
.type
== isl_obj_none
|| obj
.v
== NULL
)
367 if (isl_stream_eat(s
, ';'))
371 if (do_assign(s
->ctx
, table
, lhs
, obj
))
374 obj
.type
->print(obj
.v
, stdout
);
384 int free_cb(void *entry
)
386 struct isl_named_obj
*named
= entry
;
388 free_obj(named
->obj
);
395 static void register_named_ops(struct isl_stream
*s
)
400 if (!named_un_ops
[i
].name
)
402 named_un_ops
[i
].op
.op
= isl_stream_register_keyword(s
,
403 named_un_ops
[i
].name
);
404 assert(named_un_ops
[i
].op
.op
!= ISL_TOKEN_ERROR
);
408 int main(int argc
, char **argv
)
411 struct isl_stream
*s
;
412 struct isl_hash_table
*table
;
414 ctx
= isl_ctx_alloc();
415 s
= isl_stream_new_file(ctx
, stdin
);
417 table
= isl_hash_table_alloc(ctx
, 10);
420 register_named_ops(s
);
422 while (!feof(stdin
)) {
426 isl_hash_table_foreach(ctx
, table
, free_cb
);
427 isl_hash_table_free(ctx
, table
);