use syn::Expr;
mod convert;
#[cfg(test)]
mod tests;
#[cfg(feature = "opencl")]
pub mod opencl;
use convert::*;
pub fn rs_to_c_function(source: &str) -> String {
let c_sig = rs_to_c_signature(&get_fn_signature(source));
let expr = syn::parse_str::<Expr>(&get_fn_block(source)).unwrap();
let c_block = convert_expr(expr).to_string();
format!("{} {}", c_sig, c_block)
}
fn rs_to_c_signature(sig: &str) -> String {
let c_return_type = match sig.split("->").nth(1) {
Some(rs_return_type) => convert_to_c_type(rs_return_type).unwrap(),
None => "void".to_string(),
};
let fn_name: String = sig.split('(').next().expect("msg").replace("fn", "").replace([' ', '\t', '\n'], "");
let args: Vec<&str> = sig.split('(').nth(1).expect("msg").split(')').next().expect("msg").split(',').collect();
let mut c_args = String::new();
for (i, arg) in args.iter().enumerate() {
let name = arg.split(':').next().expect("msg").trim().to_string();
let is_const = !arg.split(':').nth(1).expect("msg").contains("mut ");
let c_type = convert_to_c_type(&arg.split(':').nth(1).expect("msg").replace("mut ", "")).unwrap();
if is_const {
c_args += "const ";
}
if c_type.contains("arrname") {
c_args += &c_type.replace("arrname", &name);
} else {
c_args += &format!("{} {}", c_type, name);
}
if i != args.len()-1 {
c_args += ", ";
}
}
let c_sig = format!("{} {}({})", c_return_type, fn_name, c_args);
c_sig
}
fn get_fn_block(source: &str) -> String {
let block = "{".to_string() + source.split_once('{').expect("msg").1;
block
}
fn get_fn_signature(source: &str) -> String {
let signature = source.split('{').next().expect("String should contain signature").trim();
signature.to_string()
}
pub fn indent_c(source: &str) -> String {
let lines: Vec<&str> = source.split('\n').collect();
let mut new_source = String::new();
let mut ind = 0;
for line in lines {
if line.trim().chars().next() == Some('}') {
for _ in 1..ind {new_source += " ";}
} else {
for _ in 0..ind {new_source += " ";}
}
new_source += line;
new_source += "\n";
ind += line.matches('{').count();
ind -= line.matches('}').count()
}
new_source.trim().to_string()
}