use super::{ASTExpr, ASTNodeList, ASTNodeType, Context, Error, Id, LibISLError, Printer};
use libc::uintptr_t;
use std::ffi::CStr;
use std::os::raw::c_char;
pub struct ASTNode {
pub ptr: uintptr_t,
pub should_free_on_drop: bool,
}
extern "C" {
fn isl_ast_node_alloc_user(expr: uintptr_t) -> uintptr_t;
fn isl_ast_node_block_from_children(list: uintptr_t) -> uintptr_t;
fn isl_ast_node_block_get_children(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_copy(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_dump(node: uintptr_t) -> ();
fn isl_ast_node_for_get_body(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_for_get_cond(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_for_get_inc(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_for_get_init(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_for_get_iterator(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_for_is_degenerate(node: uintptr_t) -> i32;
fn isl_ast_node_free(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_get_annotation(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_get_ctx(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_get_type(node: uintptr_t) -> i32;
fn isl_ast_node_if_get_cond(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_if_get_else(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_if_get_else_node(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_if_get_then(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_if_get_then_node(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_if_has_else(node: uintptr_t) -> i32;
fn isl_ast_node_if_has_else_node(node: uintptr_t) -> i32;
fn isl_ast_node_mark_get_id(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_mark_get_node(node: uintptr_t) -> uintptr_t;
fn isl_ast_node_print_macros(node: uintptr_t, p: uintptr_t) -> uintptr_t;
fn isl_ast_node_set_annotation(node: uintptr_t, annotation: uintptr_t) -> uintptr_t;
fn isl_ast_node_to_C_str(node: uintptr_t) -> *const c_char;
fn isl_ast_node_to_list(el: uintptr_t) -> uintptr_t;
fn isl_ast_node_to_str(node: uintptr_t) -> *const c_char;
fn isl_ast_node_user_from_expr(expr: uintptr_t) -> uintptr_t;
fn isl_ast_node_user_get_expr(node: uintptr_t) -> uintptr_t;
}
impl ASTNode {
pub fn alloc_user(expr: ASTExpr) -> Result<ASTNode, LibISLError> {
let isl_rs_ctx = expr.get_ctx();
let mut expr = expr;
expr.do_not_free_on_drop();
let expr = expr.ptr;
let isl_rs_result = unsafe { isl_ast_node_alloc_user(expr) };
let isl_rs_result = ASTNode { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn block_from_children(list: ASTNodeList) -> Result<ASTNode, LibISLError> {
let isl_rs_ctx = list.get_ctx();
let mut list = list;
list.do_not_free_on_drop();
let list = list.ptr;
let isl_rs_result = unsafe { isl_ast_node_block_from_children(list) };
let isl_rs_result = ASTNode { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn block_get_children(&self) -> Result<ASTNodeList, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_block_get_children(node) };
let isl_rs_result = ASTNodeList { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn copy(&self) -> Result<ASTNode, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_copy(node) };
let isl_rs_result = ASTNode { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn dump(&self) -> Result<(), LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_dump(node) };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn for_get_body(&self) -> Result<ASTNode, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_for_get_body(node) };
let isl_rs_result = ASTNode { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn for_get_cond(&self) -> Result<ASTExpr, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_for_get_cond(node) };
let isl_rs_result = ASTExpr { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn for_get_inc(&self) -> Result<ASTExpr, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_for_get_inc(node) };
let isl_rs_result = ASTExpr { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn for_get_init(&self) -> Result<ASTExpr, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_for_get_init(node) };
let isl_rs_result = ASTExpr { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn for_get_iterator(&self) -> Result<ASTExpr, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_for_get_iterator(node) };
let isl_rs_result = ASTExpr { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn for_is_degenerate(&self) -> Result<bool, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_for_is_degenerate(node) };
let isl_rs_result = match isl_rs_result {
0 => false,
1 => true,
_ => {
return Err(LibISLError::new(Error::Unknown, "Got isl_bool = -1"));
}
};
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn free(self) -> Result<ASTNode, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let mut node = node;
node.do_not_free_on_drop();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_free(node) };
let isl_rs_result = ASTNode { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn get_annotation(&self) -> Result<Id, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_get_annotation(node) };
let isl_rs_result = Id { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn get_ctx(&self) -> Context {
let node = self;
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_get_ctx(node) };
let isl_rs_result = Context { ptr: isl_rs_result,
should_free_on_drop: false };
isl_rs_result
}
pub fn get_type(&self) -> Result<ASTNodeType, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_get_type(node) };
let isl_rs_result = ASTNodeType::from_i32(isl_rs_result);
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn if_get_cond(&self) -> Result<ASTExpr, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_if_get_cond(node) };
let isl_rs_result = ASTExpr { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn if_get_else(&self) -> Result<ASTNode, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_if_get_else(node) };
let isl_rs_result = ASTNode { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn if_get_else_node(&self) -> Result<ASTNode, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_if_get_else_node(node) };
let isl_rs_result = ASTNode { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn if_get_then(&self) -> Result<ASTNode, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_if_get_then(node) };
let isl_rs_result = ASTNode { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn if_get_then_node(&self) -> Result<ASTNode, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_if_get_then_node(node) };
let isl_rs_result = ASTNode { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn if_has_else(&self) -> Result<bool, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_if_has_else(node) };
let isl_rs_result = match isl_rs_result {
0 => false,
1 => true,
_ => {
return Err(LibISLError::new(Error::Unknown, "Got isl_bool = -1"));
}
};
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn if_has_else_node(&self) -> Result<bool, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_if_has_else_node(node) };
let isl_rs_result = match isl_rs_result {
0 => false,
1 => true,
_ => {
return Err(LibISLError::new(Error::Unknown, "Got isl_bool = -1"));
}
};
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn mark_get_id(&self) -> Result<Id, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_mark_get_id(node) };
let isl_rs_result = Id { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn mark_get_node(&self) -> Result<ASTNode, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_mark_get_node(node) };
let isl_rs_result = ASTNode { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn print_macros(&self, p: Printer) -> Result<Printer, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let mut p = p;
p.do_not_free_on_drop();
let p = p.ptr;
let isl_rs_result = unsafe { isl_ast_node_print_macros(node, p) };
let isl_rs_result = Printer { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn set_annotation(self, annotation: Id) -> Result<ASTNode, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let mut node = node;
node.do_not_free_on_drop();
let node = node.ptr;
let mut annotation = annotation;
annotation.do_not_free_on_drop();
let annotation = annotation.ptr;
let isl_rs_result = unsafe { isl_ast_node_set_annotation(node, annotation) };
let isl_rs_result = ASTNode { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn to_C_str(&self) -> Result<&str, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_to_C_str(node) };
let isl_rs_result = unsafe { CStr::from_ptr(isl_rs_result) };
let isl_rs_result = isl_rs_result.to_str().unwrap();
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn to_list(self) -> Result<ASTNodeList, LibISLError> {
let el = self;
let isl_rs_ctx = el.get_ctx();
let mut el = el;
el.do_not_free_on_drop();
let el = el.ptr;
let isl_rs_result = unsafe { isl_ast_node_to_list(el) };
let isl_rs_result = ASTNodeList { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn to_str(&self) -> Result<&str, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_to_str(node) };
let isl_rs_result = unsafe { CStr::from_ptr(isl_rs_result) };
let isl_rs_result = isl_rs_result.to_str().unwrap();
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn user_from_expr(expr: ASTExpr) -> Result<ASTNode, LibISLError> {
let isl_rs_ctx = expr.get_ctx();
let mut expr = expr;
expr.do_not_free_on_drop();
let expr = expr.ptr;
let isl_rs_result = unsafe { isl_ast_node_user_from_expr(expr) };
let isl_rs_result = ASTNode { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn user_get_expr(&self) -> Result<ASTExpr, LibISLError> {
let node = self;
let isl_rs_ctx = node.get_ctx();
let node = node.ptr;
let isl_rs_result = unsafe { isl_ast_node_user_get_expr(node) };
let isl_rs_result = ASTExpr { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn do_not_free_on_drop(&mut self) {
self.should_free_on_drop = false;
}
}
impl Drop for ASTNode {
fn drop(&mut self) {
if self.should_free_on_drop {
unsafe {
isl_ast_node_free(self.ptr);
}
}
}
}