mod builtin_functins;
pub mod codegen_combinators;
mod system_plugin;
#[cfg(not(target_arch = "wasm32"))]
pub mod loader;
pub use builtin_functins::get_builtin_fns_as_plugins;
use std::{cell::RefCell, rc::Rc};
pub use system_plugin::{
DynSystemPlugin, SysPluginSignature, SystemPlugin, SystemPluginAudioWorker, SystemPluginFnType,
SystemPluginMacroType,
};
use crate::{
compiler::EvalStage,
interner::{Symbol, TypeNodeId},
interpreter::Value,
vm::{Machine, ReturnCode},
};
trait EvalStageT {
fn get_stage() -> EvalStage;
}
trait MacroStageT {}
trait MachineStageT {}
trait PersistentStageT: MacroStageT + MachineStageT {}
trait ExternalFunction {
fn get_type_info(&self) -> TypeNodeId;
fn get_name(&self) -> Symbol;
type Stage: EvalStageT;
}
struct MacroStage {}
impl EvalStageT for MacroStage {
fn get_stage() -> EvalStage {
EvalStage::Stage(0)
}
}
impl MacroStageT for MacroStage {}
struct MachineStage;
impl EvalStageT for MachineStage {
fn get_stage() -> EvalStage {
EvalStage::Stage(1)
}
}
impl MachineStageT for MachineStage {}
struct PersistentStage;
impl EvalStageT for PersistentStage {
fn get_stage() -> EvalStage {
EvalStage::Persistent
}
}
impl MacroStageT for PersistentStage {}
impl MachineStageT for PersistentStage {}
impl PersistentStageT for PersistentStage {}
pub type MacroFunType = Rc<RefCell<dyn Fn(&[(Value, TypeNodeId)]) -> Value>>;
pub trait MacroFunction {
fn get_name(&self) -> Symbol;
fn get_type(&self) -> TypeNodeId;
fn get_fn(&self) -> MacroFunType;
}
pub type ExtFunType = fn(&mut Machine) -> ReturnCode;
pub type ExtClsType = Rc<RefCell<dyn FnMut(&mut Machine) -> ReturnCode>>;
pub trait MachineFunction {
fn get_name(&self) -> Symbol;
fn get_fn(&self) -> ExtClsType;
}
#[derive(Clone)]
pub struct MacroInfo {
pub name: Symbol,
pub ty: TypeNodeId,
pub fun: MacroFunType,
}
impl MacroInfo {
pub fn new(name: Symbol, ty: TypeNodeId, fun: MacroFunType) -> Self {
Self { name, ty, fun }
}
}
impl ExternalFunction for MacroInfo {
type Stage = MacroStage;
fn get_type_info(&self) -> TypeNodeId {
self.ty
}
fn get_name(&self) -> Symbol {
self.name
}
}
impl MacroFunction for MacroInfo {
fn get_name(&self) -> Symbol {
self.name
}
fn get_type(&self) -> TypeNodeId {
self.ty
}
fn get_fn(&self) -> MacroFunType {
self.fun.clone()
}
}
#[derive(Clone, Debug)]
pub struct ExtFunInfo {
pub name: Symbol,
pub ty: TypeNodeId,
pub fun: ExtFunType,
}
impl ExtFunInfo {
pub fn new(name: Symbol, ty: TypeNodeId, fun: ExtFunType) -> Self {
Self { name, ty, fun }
}
}
impl ExternalFunction for ExtFunInfo {
type Stage = MachineStage;
fn get_type_info(&self) -> TypeNodeId {
self.ty
}
fn get_name(&self) -> Symbol {
self.name
}
}
impl MachineFunction for ExtFunInfo {
fn get_name(&self) -> Symbol {
self.name
}
fn get_fn(&self) -> ExtClsType {
Rc::new(RefCell::new(self.fun))
}
}
#[derive(Clone)]
pub struct ExtClsInfo {
pub name: Symbol,
pub ty: TypeNodeId,
pub fun: ExtClsType,
}
impl ExtClsInfo {
pub fn new(name: Symbol, ty: TypeNodeId, fun: ExtClsType) -> Self {
Self { name, ty, fun }
}
}
impl From<ExtClsInfo> for ExtFunTypeInfo {
fn from(info: ExtClsInfo) -> Self {
ExtFunTypeInfo {
name: info.name,
ty: info.ty,
stage: MachineStage::get_stage(),
}
}
}
impl From<ExtFunInfo> for ExtFunTypeInfo {
fn from(info: ExtFunInfo) -> Self {
ExtFunTypeInfo {
name: info.name,
ty: info.ty,
stage: MachineStage::get_stage(),
}
}
}
impl ExternalFunction for ExtClsInfo {
type Stage = MachineStage;
fn get_type_info(&self) -> TypeNodeId {
self.ty
}
fn get_name(&self) -> Symbol {
self.name
}
}
impl MachineFunction for ExtClsInfo {
fn get_name(&self) -> Symbol {
self.name
}
fn get_fn(&self) -> ExtClsType {
self.fun.clone()
}
}
#[derive(Clone)]
pub struct CommonFunction {
name: Symbol,
ty: TypeNodeId,
macro_fun: fn(&[(Value, TypeNodeId)]) -> Value,
fun: ExtFunType,
}
impl ExternalFunction for CommonFunction {
type Stage = PersistentStage;
fn get_type_info(&self) -> TypeNodeId {
self.ty
}
fn get_name(&self) -> Symbol {
self.name
}
}
impl MachineFunction for CommonFunction {
fn get_name(&self) -> Symbol {
self.name
}
fn get_fn(&self) -> ExtClsType {
Rc::new(RefCell::new(self.fun))
}
}
impl MacroFunction for CommonFunction {
fn get_name(&self) -> Symbol {
self.name
}
fn get_type(&self) -> TypeNodeId {
self.ty
}
fn get_fn(&self) -> MacroFunType {
Rc::new(RefCell::new(self.macro_fun))
}
}
#[derive(Clone, Copy)]
pub struct ExtFunTypeInfo {
pub name: Symbol,
pub ty: TypeNodeId,
pub stage: EvalStage,
}
impl ExtFunTypeInfo {
pub fn new(name: Symbol, ty: TypeNodeId, stage: EvalStage) -> Self {
Self { name, ty, stage }
}
}
pub trait Plugin {
fn get_macro_functions(&self) -> Vec<Box<dyn MacroFunction>>;
fn get_ext_closures(&self) -> Vec<Box<dyn MachineFunction>>;
fn get_type_infos(&self) -> Vec<ExtFunTypeInfo>;
}
#[derive(Clone)]
pub struct InstantPlugin {
pub macros: Vec<MacroInfo>,
pub extcls: Vec<ExtClsInfo>,
pub commonfns: Vec<CommonFunction>,
}
impl Plugin for InstantPlugin {
fn get_macro_functions(&self) -> Vec<Box<dyn MacroFunction>> {
let macros = self
.macros
.clone()
.into_iter()
.map(|m| Box::new(m) as Box<dyn MacroFunction>);
let commons = self
.commonfns
.clone()
.into_iter()
.map(|c| Box::new(c) as Box<dyn MacroFunction>);
macros.chain(commons).collect()
}
fn get_ext_closures(&self) -> Vec<Box<dyn MachineFunction>> {
let extfns = self
.extcls
.clone()
.into_iter()
.map(|e| Box::new(e) as Box<dyn MachineFunction>);
let commons = self
.commonfns
.clone()
.into_iter()
.map(|c| Box::new(c) as Box<dyn MachineFunction>);
extfns.chain(commons).collect()
}
fn get_type_infos(&self) -> Vec<ExtFunTypeInfo> {
let extcls_names: std::collections::HashSet<crate::interner::Symbol> =
self.extcls.iter().map(|e| e.name).collect();
let commons_names: std::collections::HashSet<crate::interner::Symbol> =
self.commonfns.iter().map(|c| c.name).collect();
let macros = self
.macros
.iter()
.filter(|m| !extcls_names.contains(&m.name) && !commons_names.contains(&m.name))
.map(|m| ExtFunTypeInfo::new(m.name, m.ty, MacroStage::get_stage()));
let extcls = self
.extcls
.iter()
.map(|e| ExtFunTypeInfo::new(e.name, e.ty, MachineStage::get_stage()));
let commons = self
.commonfns
.iter()
.map(|c| ExtFunTypeInfo::new(c.name, c.ty, PersistentStage::get_stage()));
macros.chain(extcls).chain(commons).collect()
}
}
pub trait UGenPlugin {
type InitParam;
type Args;
type Ret;
fn new(param: Self::InitParam) -> Self;
fn on_sample(&mut self, arg: Self::Args) -> Self::Ret;
}
pub fn get_extfun_types(plugins: &[Box<dyn Plugin>]) -> impl Iterator<Item = ExtFunTypeInfo> + '_ {
plugins
.iter()
.flat_map(|plugin| plugin.get_type_infos().into_iter())
}
pub fn get_macro_functions(
plugins: &[Box<dyn Plugin>],
) -> impl Iterator<Item = Box<dyn MacroFunction>> + '_ {
plugins
.iter()
.flat_map(|plugin| plugin.get_macro_functions().into_iter())
}
pub fn get_ext_closures(
plugins: &[Box<dyn Plugin>],
) -> impl Iterator<Item = Box<dyn MachineFunction>> + '_ {
plugins
.iter()
.flat_map(|plugin| plugin.get_ext_closures().into_iter())
}
pub(crate) type MonomorphizedExtFnNameResolver =
fn(Symbol, TypeNodeId, TypeNodeId) -> Option<Symbol>;
const MONOMORPHIZED_EXT_FN_NAME_RESOLVERS: [MonomorphizedExtFnNameResolver; 1] =
[builtin_functins::try_get_monomorphized_ext_fn_name];
pub(crate) fn resolve_monomorphized_ext_fn_name(
fn_name: Symbol,
concrete_arg_ty: TypeNodeId,
concrete_ret_ty: TypeNodeId,
) -> Option<Symbol> {
MONOMORPHIZED_EXT_FN_NAME_RESOLVERS
.iter()
.find_map(|resolver| resolver(fn_name, concrete_arg_ty, concrete_ret_ty))
}
pub(crate) type SpecializedExtClsResolver = fn(Symbol, TypeNodeId) -> Option<ExtClsInfo>;
const SPECIALIZED_EXTCLS_RESOLVERS: [SpecializedExtClsResolver; 1] =
[builtin_functins::try_make_specialized_extcls];
pub(crate) fn try_make_specialized_extcls(name: Symbol, ty: TypeNodeId) -> Option<ExtClsInfo> {
SPECIALIZED_EXTCLS_RESOLVERS
.iter()
.find_map(|resolver| resolver(name, ty))
}