use wasm_encoder::ValType;
pub struct AbiImport {
pub effect: &'static str,
pub import_name: &'static str,
pub params: &'static [ValType],
pub results: &'static [ValType],
}
pub const ABI_MODULE: &str = "aver";
pub const ABI_TABLE: &[AbiImport] = &[
AbiImport {
effect: "Args._len",
import_name: "args_len",
params: &[],
results: &[ValType::I32],
},
AbiImport {
effect: "Args._get",
import_name: "args_get",
params: &[ValType::I32],
results: &[ValType::I32, ValType::I32],
},
AbiImport {
effect: "Console.print",
import_name: "console_print",
params: &[ValType::I32, ValType::I32], results: &[],
},
AbiImport {
effect: "Console.error",
import_name: "console_error",
params: &[ValType::I32, ValType::I32],
results: &[],
},
AbiImport {
effect: "Console.readLine",
import_name: "console_readLine",
params: &[],
results: &[ValType::I32, ValType::I32], },
AbiImport {
effect: "Terminal.enableRawMode",
import_name: "terminal_enableRawMode",
params: &[],
results: &[],
},
AbiImport {
effect: "Terminal.disableRawMode",
import_name: "terminal_disableRawMode",
params: &[],
results: &[],
},
AbiImport {
effect: "Terminal.clear",
import_name: "terminal_clear",
params: &[],
results: &[],
},
AbiImport {
effect: "Terminal.moveTo",
import_name: "terminal_moveTo",
params: &[ValType::I32, ValType::I32],
results: &[],
},
AbiImport {
effect: "Terminal.print",
import_name: "terminal_print",
params: &[ValType::I32, ValType::I32],
results: &[],
},
AbiImport {
effect: "Terminal.setColor",
import_name: "terminal_setColor",
params: &[ValType::I32, ValType::I32],
results: &[],
},
AbiImport {
effect: "Terminal.resetColor",
import_name: "terminal_resetColor",
params: &[],
results: &[],
},
AbiImport {
effect: "Terminal.readKey",
import_name: "terminal_readKey",
params: &[],
results: &[ValType::I32, ValType::I32], },
AbiImport {
effect: "Terminal.size",
import_name: "terminal_size",
params: &[],
results: &[ValType::I32, ValType::I32], },
AbiImport {
effect: "Terminal.hideCursor",
import_name: "terminal_hideCursor",
params: &[],
results: &[],
},
AbiImport {
effect: "Terminal.showCursor",
import_name: "terminal_showCursor",
params: &[],
results: &[],
},
AbiImport {
effect: "Terminal.flush",
import_name: "terminal_flush",
params: &[],
results: &[],
},
AbiImport {
effect: "Random.int",
import_name: "random_int",
params: &[ValType::I64, ValType::I64], results: &[ValType::I64],
},
AbiImport {
effect: "Time.unixMs",
import_name: "time_unixMs",
params: &[],
results: &[ValType::I64],
},
AbiImport {
effect: "Time.sleep",
import_name: "time_sleep",
params: &[ValType::I64], results: &[],
},
AbiImport {
effect: "Time.now",
import_name: "time_now",
params: &[],
results: &[ValType::I32, ValType::I32], },
AbiImport {
effect: "Print.value",
import_name: "print_value",
params: &[ValType::I32, ValType::I64], results: &[],
},
AbiImport {
effect: "Format.value",
import_name: "format_value",
params: &[ValType::I32, ValType::I64], results: &[ValType::I32, ValType::I32], },
AbiImport {
effect: "Float.sin",
import_name: "math_sin",
params: &[ValType::F64],
results: &[ValType::F64],
},
AbiImport {
effect: "Float.cos",
import_name: "math_cos",
params: &[ValType::F64],
results: &[ValType::F64],
},
AbiImport {
effect: "Float.atan2",
import_name: "math_atan2",
params: &[ValType::F64, ValType::F64],
results: &[ValType::F64],
},
AbiImport {
effect: "Float.pow",
import_name: "math_pow",
params: &[ValType::F64, ValType::F64],
results: &[ValType::F64],
},
];
pub fn lookup(effect: &str) -> Option<&'static AbiImport> {
ABI_TABLE.iter().find(|e| e.effect == effect)
}
pub fn collect_needed_imports(
fn_sigs: &std::collections::HashMap<
String,
(Vec<crate::types::Type>, crate::types::Type, Vec<String>),
>,
user_fn_names: &[&str],
host_call_names: &std::collections::HashSet<String>,
) -> Vec<&'static AbiImport> {
let mut seen = std::collections::HashSet::new();
let mut imports = Vec::new();
let mut add_effect = |effect: &str| {
if effect == "Args.get" {
for hidden in ["Args._len", "Args._get"] {
if seen.insert(hidden.to_string())
&& let Some(abi) = lookup(hidden)
{
imports.push(abi);
}
}
return;
}
if seen.insert(effect.to_string())
&& let Some(abi) = lookup(effect)
{
imports.push(abi);
}
};
for name in user_fn_names {
if let Some((_, _, effects)) = fn_sigs.get(*name) {
for effect in effects {
add_effect(effect);
}
}
}
for call_name in host_call_names {
add_effect(call_name);
}
imports.sort_by_key(|a| a.import_name);
imports.dedup_by_key(|a| a.import_name);
imports
}