1use super::{ASTExpr, ASTNodeList, ASTNodeType, Context, Error, Id, LibISLError, Printer};
5use libc::uintptr_t;
6use std::ffi::CStr;
7use std::os::raw::c_char;
8
9pub struct ASTNode {
11 pub ptr: uintptr_t,
12 pub should_free_on_drop: bool,
13}
14
15extern "C" {
16
17 fn isl_ast_node_alloc_user(expr: uintptr_t) -> uintptr_t;
18
19 fn isl_ast_node_block_from_children(list: uintptr_t) -> uintptr_t;
20
21 fn isl_ast_node_block_get_children(node: uintptr_t) -> uintptr_t;
22
23 fn isl_ast_node_copy(node: uintptr_t) -> uintptr_t;
24
25 fn isl_ast_node_dump(node: uintptr_t) -> ();
26
27 fn isl_ast_node_for_get_body(node: uintptr_t) -> uintptr_t;
28
29 fn isl_ast_node_for_get_cond(node: uintptr_t) -> uintptr_t;
30
31 fn isl_ast_node_for_get_inc(node: uintptr_t) -> uintptr_t;
32
33 fn isl_ast_node_for_get_init(node: uintptr_t) -> uintptr_t;
34
35 fn isl_ast_node_for_get_iterator(node: uintptr_t) -> uintptr_t;
36
37 fn isl_ast_node_for_is_degenerate(node: uintptr_t) -> i32;
38
39 fn isl_ast_node_free(node: uintptr_t) -> uintptr_t;
40
41 fn isl_ast_node_get_annotation(node: uintptr_t) -> uintptr_t;
42
43 fn isl_ast_node_get_ctx(node: uintptr_t) -> uintptr_t;
44
45 fn isl_ast_node_get_type(node: uintptr_t) -> i32;
46
47 fn isl_ast_node_if_get_cond(node: uintptr_t) -> uintptr_t;
48
49 fn isl_ast_node_if_get_else(node: uintptr_t) -> uintptr_t;
50
51 fn isl_ast_node_if_get_else_node(node: uintptr_t) -> uintptr_t;
52
53 fn isl_ast_node_if_get_then(node: uintptr_t) -> uintptr_t;
54
55 fn isl_ast_node_if_get_then_node(node: uintptr_t) -> uintptr_t;
56
57 fn isl_ast_node_if_has_else(node: uintptr_t) -> i32;
58
59 fn isl_ast_node_if_has_else_node(node: uintptr_t) -> i32;
60
61 fn isl_ast_node_mark_get_id(node: uintptr_t) -> uintptr_t;
62
63 fn isl_ast_node_mark_get_node(node: uintptr_t) -> uintptr_t;
64
65 fn isl_ast_node_print_macros(node: uintptr_t, p: uintptr_t) -> uintptr_t;
66
67 fn isl_ast_node_set_annotation(node: uintptr_t, annotation: uintptr_t) -> uintptr_t;
68
69 fn isl_ast_node_to_C_str(node: uintptr_t) -> *const c_char;
70
71 fn isl_ast_node_to_list(el: uintptr_t) -> uintptr_t;
72
73 fn isl_ast_node_to_str(node: uintptr_t) -> *const c_char;
74
75 fn isl_ast_node_user_from_expr(expr: uintptr_t) -> uintptr_t;
76
77 fn isl_ast_node_user_get_expr(node: uintptr_t) -> uintptr_t;
78
79}
80
81impl ASTNode {
82 pub fn alloc_user(expr: ASTExpr) -> Result<ASTNode, LibISLError> {
84 let isl_rs_ctx = expr.get_ctx();
85 let mut expr = expr;
86 expr.do_not_free_on_drop();
87 let expr = expr.ptr;
88 let isl_rs_result = unsafe { isl_ast_node_alloc_user(expr) };
89 let isl_rs_result = ASTNode { ptr: isl_rs_result,
90 should_free_on_drop: true };
91 let err = isl_rs_ctx.last_error();
92 if err != Error::None_ {
93 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
94 }
95 Ok(isl_rs_result)
96 }
97
98 pub fn block_from_children(list: ASTNodeList) -> Result<ASTNode, LibISLError> {
100 let isl_rs_ctx = list.get_ctx();
101 let mut list = list;
102 list.do_not_free_on_drop();
103 let list = list.ptr;
104 let isl_rs_result = unsafe { isl_ast_node_block_from_children(list) };
105 let isl_rs_result = ASTNode { ptr: isl_rs_result,
106 should_free_on_drop: true };
107 let err = isl_rs_ctx.last_error();
108 if err != Error::None_ {
109 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
110 }
111 Ok(isl_rs_result)
112 }
113
114 pub fn block_get_children(&self) -> Result<ASTNodeList, LibISLError> {
116 let node = self;
117 let isl_rs_ctx = node.get_ctx();
118 let node = node.ptr;
119 let isl_rs_result = unsafe { isl_ast_node_block_get_children(node) };
120 let isl_rs_result = ASTNodeList { ptr: isl_rs_result,
121 should_free_on_drop: true };
122 let err = isl_rs_ctx.last_error();
123 if err != Error::None_ {
124 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
125 }
126 Ok(isl_rs_result)
127 }
128
129 pub fn copy(&self) -> Result<ASTNode, LibISLError> {
131 let node = self;
132 let isl_rs_ctx = node.get_ctx();
133 let node = node.ptr;
134 let isl_rs_result = unsafe { isl_ast_node_copy(node) };
135 let isl_rs_result = ASTNode { ptr: isl_rs_result,
136 should_free_on_drop: true };
137 let err = isl_rs_ctx.last_error();
138 if err != Error::None_ {
139 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
140 }
141 Ok(isl_rs_result)
142 }
143
144 pub fn dump(&self) -> Result<(), LibISLError> {
146 let node = self;
147 let isl_rs_ctx = node.get_ctx();
148 let node = node.ptr;
149 let isl_rs_result = unsafe { isl_ast_node_dump(node) };
150 let err = isl_rs_ctx.last_error();
151 if err != Error::None_ {
152 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
153 }
154 Ok(isl_rs_result)
155 }
156
157 pub fn for_get_body(&self) -> Result<ASTNode, LibISLError> {
159 let node = self;
160 let isl_rs_ctx = node.get_ctx();
161 let node = node.ptr;
162 let isl_rs_result = unsafe { isl_ast_node_for_get_body(node) };
163 let isl_rs_result = ASTNode { ptr: isl_rs_result,
164 should_free_on_drop: true };
165 let err = isl_rs_ctx.last_error();
166 if err != Error::None_ {
167 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
168 }
169 Ok(isl_rs_result)
170 }
171
172 pub fn for_get_cond(&self) -> Result<ASTExpr, LibISLError> {
174 let node = self;
175 let isl_rs_ctx = node.get_ctx();
176 let node = node.ptr;
177 let isl_rs_result = unsafe { isl_ast_node_for_get_cond(node) };
178 let isl_rs_result = ASTExpr { ptr: isl_rs_result,
179 should_free_on_drop: true };
180 let err = isl_rs_ctx.last_error();
181 if err != Error::None_ {
182 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
183 }
184 Ok(isl_rs_result)
185 }
186
187 pub fn for_get_inc(&self) -> Result<ASTExpr, LibISLError> {
189 let node = self;
190 let isl_rs_ctx = node.get_ctx();
191 let node = node.ptr;
192 let isl_rs_result = unsafe { isl_ast_node_for_get_inc(node) };
193 let isl_rs_result = ASTExpr { ptr: isl_rs_result,
194 should_free_on_drop: true };
195 let err = isl_rs_ctx.last_error();
196 if err != Error::None_ {
197 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
198 }
199 Ok(isl_rs_result)
200 }
201
202 pub fn for_get_init(&self) -> Result<ASTExpr, LibISLError> {
204 let node = self;
205 let isl_rs_ctx = node.get_ctx();
206 let node = node.ptr;
207 let isl_rs_result = unsafe { isl_ast_node_for_get_init(node) };
208 let isl_rs_result = ASTExpr { ptr: isl_rs_result,
209 should_free_on_drop: true };
210 let err = isl_rs_ctx.last_error();
211 if err != Error::None_ {
212 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
213 }
214 Ok(isl_rs_result)
215 }
216
217 pub fn for_get_iterator(&self) -> Result<ASTExpr, LibISLError> {
219 let node = self;
220 let isl_rs_ctx = node.get_ctx();
221 let node = node.ptr;
222 let isl_rs_result = unsafe { isl_ast_node_for_get_iterator(node) };
223 let isl_rs_result = ASTExpr { ptr: isl_rs_result,
224 should_free_on_drop: true };
225 let err = isl_rs_ctx.last_error();
226 if err != Error::None_ {
227 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
228 }
229 Ok(isl_rs_result)
230 }
231
232 pub fn for_is_degenerate(&self) -> Result<bool, LibISLError> {
234 let node = self;
235 let isl_rs_ctx = node.get_ctx();
236 let node = node.ptr;
237 let isl_rs_result = unsafe { isl_ast_node_for_is_degenerate(node) };
238 let isl_rs_result = match isl_rs_result {
239 0 => false,
240 1 => true,
241 _ => panic!("Got isl_bool = -1"),
242 };
243 let err = isl_rs_ctx.last_error();
244 if err != Error::None_ {
245 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
246 }
247 Ok(isl_rs_result)
248 }
249
250 pub fn free(self) -> Result<ASTNode, LibISLError> {
252 let node = self;
253 let isl_rs_ctx = node.get_ctx();
254 let mut node = node;
255 node.do_not_free_on_drop();
256 let node = node.ptr;
257 let isl_rs_result = unsafe { isl_ast_node_free(node) };
258 let isl_rs_result = ASTNode { ptr: isl_rs_result,
259 should_free_on_drop: true };
260 let err = isl_rs_ctx.last_error();
261 if err != Error::None_ {
262 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
263 }
264 Ok(isl_rs_result)
265 }
266
267 pub fn get_annotation(&self) -> Result<Id, LibISLError> {
269 let node = self;
270 let isl_rs_ctx = node.get_ctx();
271 let node = node.ptr;
272 let isl_rs_result = unsafe { isl_ast_node_get_annotation(node) };
273 let isl_rs_result = Id { ptr: isl_rs_result,
274 should_free_on_drop: true };
275 let err = isl_rs_ctx.last_error();
276 if err != Error::None_ {
277 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
278 }
279 Ok(isl_rs_result)
280 }
281
282 pub fn get_ctx(&self) -> Context {
284 let node = self;
285 let node = node.ptr;
286 let isl_rs_result = unsafe { isl_ast_node_get_ctx(node) };
287 let isl_rs_result = Context { ptr: isl_rs_result,
288 should_free_on_drop: false };
289 isl_rs_result
290 }
291
292 pub fn get_type(&self) -> Result<ASTNodeType, LibISLError> {
294 let node = self;
295 let isl_rs_ctx = node.get_ctx();
296 let node = node.ptr;
297 let isl_rs_result = unsafe { isl_ast_node_get_type(node) };
298 let isl_rs_result = ASTNodeType::from_i32(isl_rs_result);
299 let err = isl_rs_ctx.last_error();
300 if err != Error::None_ {
301 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
302 }
303 Ok(isl_rs_result)
304 }
305
306 pub fn if_get_cond(&self) -> Result<ASTExpr, LibISLError> {
308 let node = self;
309 let isl_rs_ctx = node.get_ctx();
310 let node = node.ptr;
311 let isl_rs_result = unsafe { isl_ast_node_if_get_cond(node) };
312 let isl_rs_result = ASTExpr { ptr: isl_rs_result,
313 should_free_on_drop: true };
314 let err = isl_rs_ctx.last_error();
315 if err != Error::None_ {
316 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
317 }
318 Ok(isl_rs_result)
319 }
320
321 pub fn if_get_else(&self) -> Result<ASTNode, LibISLError> {
323 let node = self;
324 let isl_rs_ctx = node.get_ctx();
325 let node = node.ptr;
326 let isl_rs_result = unsafe { isl_ast_node_if_get_else(node) };
327 let isl_rs_result = ASTNode { ptr: isl_rs_result,
328 should_free_on_drop: true };
329 let err = isl_rs_ctx.last_error();
330 if err != Error::None_ {
331 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
332 }
333 Ok(isl_rs_result)
334 }
335
336 pub fn if_get_else_node(&self) -> Result<ASTNode, LibISLError> {
338 let node = self;
339 let isl_rs_ctx = node.get_ctx();
340 let node = node.ptr;
341 let isl_rs_result = unsafe { isl_ast_node_if_get_else_node(node) };
342 let isl_rs_result = ASTNode { ptr: isl_rs_result,
343 should_free_on_drop: true };
344 let err = isl_rs_ctx.last_error();
345 if err != Error::None_ {
346 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
347 }
348 Ok(isl_rs_result)
349 }
350
351 pub fn if_get_then(&self) -> Result<ASTNode, LibISLError> {
353 let node = self;
354 let isl_rs_ctx = node.get_ctx();
355 let node = node.ptr;
356 let isl_rs_result = unsafe { isl_ast_node_if_get_then(node) };
357 let isl_rs_result = ASTNode { ptr: isl_rs_result,
358 should_free_on_drop: true };
359 let err = isl_rs_ctx.last_error();
360 if err != Error::None_ {
361 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
362 }
363 Ok(isl_rs_result)
364 }
365
366 pub fn if_get_then_node(&self) -> Result<ASTNode, LibISLError> {
368 let node = self;
369 let isl_rs_ctx = node.get_ctx();
370 let node = node.ptr;
371 let isl_rs_result = unsafe { isl_ast_node_if_get_then_node(node) };
372 let isl_rs_result = ASTNode { ptr: isl_rs_result,
373 should_free_on_drop: true };
374 let err = isl_rs_ctx.last_error();
375 if err != Error::None_ {
376 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
377 }
378 Ok(isl_rs_result)
379 }
380
381 pub fn if_has_else(&self) -> Result<bool, LibISLError> {
383 let node = self;
384 let isl_rs_ctx = node.get_ctx();
385 let node = node.ptr;
386 let isl_rs_result = unsafe { isl_ast_node_if_has_else(node) };
387 let isl_rs_result = match isl_rs_result {
388 0 => false,
389 1 => true,
390 _ => panic!("Got isl_bool = -1"),
391 };
392 let err = isl_rs_ctx.last_error();
393 if err != Error::None_ {
394 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
395 }
396 Ok(isl_rs_result)
397 }
398
399 pub fn if_has_else_node(&self) -> Result<bool, LibISLError> {
401 let node = self;
402 let isl_rs_ctx = node.get_ctx();
403 let node = node.ptr;
404 let isl_rs_result = unsafe { isl_ast_node_if_has_else_node(node) };
405 let isl_rs_result = match isl_rs_result {
406 0 => false,
407 1 => true,
408 _ => panic!("Got isl_bool = -1"),
409 };
410 let err = isl_rs_ctx.last_error();
411 if err != Error::None_ {
412 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
413 }
414 Ok(isl_rs_result)
415 }
416
417 pub fn mark_get_id(&self) -> Result<Id, LibISLError> {
419 let node = self;
420 let isl_rs_ctx = node.get_ctx();
421 let node = node.ptr;
422 let isl_rs_result = unsafe { isl_ast_node_mark_get_id(node) };
423 let isl_rs_result = Id { ptr: isl_rs_result,
424 should_free_on_drop: true };
425 let err = isl_rs_ctx.last_error();
426 if err != Error::None_ {
427 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
428 }
429 Ok(isl_rs_result)
430 }
431
432 pub fn mark_get_node(&self) -> Result<ASTNode, LibISLError> {
434 let node = self;
435 let isl_rs_ctx = node.get_ctx();
436 let node = node.ptr;
437 let isl_rs_result = unsafe { isl_ast_node_mark_get_node(node) };
438 let isl_rs_result = ASTNode { ptr: isl_rs_result,
439 should_free_on_drop: true };
440 let err = isl_rs_ctx.last_error();
441 if err != Error::None_ {
442 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
443 }
444 Ok(isl_rs_result)
445 }
446
447 pub fn print_macros(&self, p: Printer) -> Result<Printer, LibISLError> {
449 let node = self;
450 let isl_rs_ctx = node.get_ctx();
451 let node = node.ptr;
452 let mut p = p;
453 p.do_not_free_on_drop();
454 let p = p.ptr;
455 let isl_rs_result = unsafe { isl_ast_node_print_macros(node, p) };
456 let isl_rs_result = Printer { ptr: isl_rs_result,
457 should_free_on_drop: true };
458 let err = isl_rs_ctx.last_error();
459 if err != Error::None_ {
460 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
461 }
462 Ok(isl_rs_result)
463 }
464
465 pub fn set_annotation(self, annotation: Id) -> Result<ASTNode, LibISLError> {
467 let node = self;
468 let isl_rs_ctx = node.get_ctx();
469 let mut node = node;
470 node.do_not_free_on_drop();
471 let node = node.ptr;
472 let mut annotation = annotation;
473 annotation.do_not_free_on_drop();
474 let annotation = annotation.ptr;
475 let isl_rs_result = unsafe { isl_ast_node_set_annotation(node, annotation) };
476 let isl_rs_result = ASTNode { ptr: isl_rs_result,
477 should_free_on_drop: true };
478 let err = isl_rs_ctx.last_error();
479 if err != Error::None_ {
480 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
481 }
482 Ok(isl_rs_result)
483 }
484
485 pub fn to_C_str(&self) -> Result<&str, LibISLError> {
487 let node = self;
488 let isl_rs_ctx = node.get_ctx();
489 let node = node.ptr;
490 let isl_rs_result = unsafe { isl_ast_node_to_C_str(node) };
491 let isl_rs_result = unsafe { CStr::from_ptr(isl_rs_result) };
492 let isl_rs_result = isl_rs_result.to_str().unwrap();
493 let err = isl_rs_ctx.last_error();
494 if err != Error::None_ {
495 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
496 }
497 Ok(isl_rs_result)
498 }
499
500 pub fn to_list(self) -> Result<ASTNodeList, LibISLError> {
502 let el = self;
503 let isl_rs_ctx = el.get_ctx();
504 let mut el = el;
505 el.do_not_free_on_drop();
506 let el = el.ptr;
507 let isl_rs_result = unsafe { isl_ast_node_to_list(el) };
508 let isl_rs_result = ASTNodeList { ptr: isl_rs_result,
509 should_free_on_drop: true };
510 let err = isl_rs_ctx.last_error();
511 if err != Error::None_ {
512 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
513 }
514 Ok(isl_rs_result)
515 }
516
517 pub fn to_str(&self) -> Result<&str, LibISLError> {
519 let node = self;
520 let isl_rs_ctx = node.get_ctx();
521 let node = node.ptr;
522 let isl_rs_result = unsafe { isl_ast_node_to_str(node) };
523 let isl_rs_result = unsafe { CStr::from_ptr(isl_rs_result) };
524 let isl_rs_result = isl_rs_result.to_str().unwrap();
525 let err = isl_rs_ctx.last_error();
526 if err != Error::None_ {
527 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
528 }
529 Ok(isl_rs_result)
530 }
531
532 pub fn user_from_expr(expr: ASTExpr) -> Result<ASTNode, LibISLError> {
534 let isl_rs_ctx = expr.get_ctx();
535 let mut expr = expr;
536 expr.do_not_free_on_drop();
537 let expr = expr.ptr;
538 let isl_rs_result = unsafe { isl_ast_node_user_from_expr(expr) };
539 let isl_rs_result = ASTNode { ptr: isl_rs_result,
540 should_free_on_drop: true };
541 let err = isl_rs_ctx.last_error();
542 if err != Error::None_ {
543 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
544 }
545 Ok(isl_rs_result)
546 }
547
548 pub fn user_get_expr(&self) -> Result<ASTExpr, LibISLError> {
550 let node = self;
551 let isl_rs_ctx = node.get_ctx();
552 let node = node.ptr;
553 let isl_rs_result = unsafe { isl_ast_node_user_get_expr(node) };
554 let isl_rs_result = ASTExpr { ptr: isl_rs_result,
555 should_free_on_drop: true };
556 let err = isl_rs_ctx.last_error();
557 if err != Error::None_ {
558 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
559 }
560 Ok(isl_rs_result)
561 }
562
563 pub fn do_not_free_on_drop(&mut self) {
566 self.should_free_on_drop = false;
567 }
568}
569
570impl Drop for ASTNode {
571 fn drop(&mut self) {
572 if self.should_free_on_drop {
573 unsafe {
574 isl_ast_node_free(self.ptr);
575 }
576 }
577 }
578}