use crate::parser::*;
use super::CodeGenerator;
impl<'ast> CodeGenerator<'ast> {
pub(super) fn generate_extern_function(&self, func: &FunctionDecl) -> String {
let mut output = String::new();
output.push_str(" pub fn ");
output.push_str(&func.name);
if !func.type_params.is_empty() {
output.push('<');
output.push_str(&self.format_type_params(&func.type_params));
output.push('>');
}
output.push('(');
let mut params: Vec<String> = Vec::new();
for param in &func.parameters {
if matches!(¶m.type_, Type::Custom(name) if name == "str") {
params.push(format!("{}_ptr: *const u8", param.name));
params.push(format!("{}_len: usize", param.name));
} else if matches!(¶m.type_, Type::String)
|| matches!(¶m.type_, Type::Custom(name) if name == "string" || name == "String")
{
params.push(format!(
"{}: windjammer_runtime::ffi::FfiString",
param.name
));
} else {
params.push(format!(
"{}: {}",
param.name,
self.type_to_rust(¶m.type_)
));
}
}
output.push_str(¶ms.join(", "));
output.push(')');
if let Some(ret_type) = &func.return_type {
output.push_str(" -> ");
let rust_ret = if matches!(ret_type, Type::String)
|| matches!(ret_type, Type::Custom(name) if name == "string" || name == "String")
{
"windjammer_runtime::ffi::FfiString".to_string()
} else {
self.type_to_rust(ret_type)
};
output.push_str(&rust_ret);
}
output.push_str(";\n");
output
}
}