1mod builtin_functins;
11pub mod codegen_combinators;
12mod system_plugin;
13
14#[cfg(not(target_arch = "wasm32"))]
15pub mod loader;
16
17pub use builtin_functins::get_builtin_fns_as_plugins;
18use std::{cell::RefCell, rc::Rc};
19
20pub use system_plugin::{
21 DynSystemPlugin, SysPluginSignature, SystemPlugin, SystemPluginAudioWorker, SystemPluginFnType,
22 SystemPluginMacroType,
23};
24
25use crate::{
26 compiler::EvalStage,
27 interner::{Symbol, TypeNodeId},
28 interpreter::Value,
29 vm::{Machine, ReturnCode},
30};
31trait EvalStageT {
32 fn get_stage() -> EvalStage;
33}
34trait MacroStageT {}
35trait MachineStageT {}
36trait PersistentStageT: MacroStageT + MachineStageT {}
37trait ExternalFunction {
38 fn get_type_info(&self) -> TypeNodeId;
40 fn get_name(&self) -> Symbol;
41 type Stage: EvalStageT;
42}
43struct MacroStage {}
44impl EvalStageT for MacroStage {
45 fn get_stage() -> EvalStage {
46 EvalStage::Stage(0)
47 }
48}
49impl MacroStageT for MacroStage {}
50struct MachineStage;
51impl EvalStageT for MachineStage {
52 fn get_stage() -> EvalStage {
53 EvalStage::Stage(1)
54 }
55}
56impl MachineStageT for MachineStage {}
57struct PersistentStage;
58impl EvalStageT for PersistentStage {
59 fn get_stage() -> EvalStage {
60 EvalStage::Persistent
61 }
62}
63impl MacroStageT for PersistentStage {}
64impl MachineStageT for PersistentStage {}
65impl PersistentStageT for PersistentStage {}
66pub type MacroFunType = Rc<RefCell<dyn Fn(&[(Value, TypeNodeId)]) -> Value>>;
67
68pub trait MacroFunction {
69 fn get_name(&self) -> Symbol;
71 fn get_type(&self) -> TypeNodeId;
72 fn get_fn(&self) -> MacroFunType;
74}
75pub type ExtFunType = fn(&mut Machine) -> ReturnCode;
76pub type ExtClsType = Rc<RefCell<dyn FnMut(&mut Machine) -> ReturnCode>>;
77pub trait MachineFunction {
78 fn get_name(&self) -> Symbol;
80 fn get_fn(&self) -> ExtClsType;
82}
83#[derive(Clone)]
84pub struct MacroInfo {
85 pub name: Symbol,
86 pub ty: TypeNodeId,
87 pub fun: MacroFunType,
88}
89impl MacroInfo {
90 pub fn new(name: Symbol, ty: TypeNodeId, fun: MacroFunType) -> Self {
91 Self { name, ty, fun }
92 }
93}
94impl ExternalFunction for MacroInfo {
95 type Stage = MacroStage;
96 fn get_type_info(&self) -> TypeNodeId {
97 self.ty
98 }
99 fn get_name(&self) -> Symbol {
100 self.name
101 }
102}
103impl MacroFunction for MacroInfo {
104 fn get_name(&self) -> Symbol {
105 self.name
106 }
107 fn get_type(&self) -> TypeNodeId {
108 self.ty
109 }
110 fn get_fn(&self) -> MacroFunType {
111 self.fun.clone()
112 }
113}
114
115#[derive(Clone, Debug)]
116pub struct ExtFunInfo {
117 pub name: Symbol,
118 pub ty: TypeNodeId,
119 pub fun: ExtFunType,
120}
121impl ExtFunInfo {
122 pub fn new(name: Symbol, ty: TypeNodeId, fun: ExtFunType) -> Self {
123 Self { name, ty, fun }
124 }
125}
126impl ExternalFunction for ExtFunInfo {
127 type Stage = MachineStage;
128 fn get_type_info(&self) -> TypeNodeId {
129 self.ty
130 }
131 fn get_name(&self) -> Symbol {
132 self.name
133 }
134}
135impl MachineFunction for ExtFunInfo {
136 fn get_name(&self) -> Symbol {
137 self.name
138 }
139 fn get_fn(&self) -> ExtClsType {
140 Rc::new(RefCell::new(self.fun))
141 }
142}
143
144#[derive(Clone)]
145pub struct ExtClsInfo {
146 pub name: Symbol,
147 pub ty: TypeNodeId,
148 pub fun: ExtClsType,
149}
150impl ExtClsInfo {
151 pub fn new(name: Symbol, ty: TypeNodeId, fun: ExtClsType) -> Self {
152 Self { name, ty, fun }
153 }
154}
155impl From<ExtClsInfo> for ExtFunTypeInfo {
156 fn from(info: ExtClsInfo) -> Self {
157 ExtFunTypeInfo {
158 name: info.name,
159 ty: info.ty,
160 stage: MachineStage::get_stage(),
161 }
162 }
163}
164impl From<ExtFunInfo> for ExtFunTypeInfo {
165 fn from(info: ExtFunInfo) -> Self {
166 ExtFunTypeInfo {
167 name: info.name,
168 ty: info.ty,
169 stage: MachineStage::get_stage(),
170 }
171 }
172}
173impl ExternalFunction for ExtClsInfo {
174 type Stage = MachineStage;
175 fn get_type_info(&self) -> TypeNodeId {
176 self.ty
177 }
178 fn get_name(&self) -> Symbol {
179 self.name
180 }
181}
182impl MachineFunction for ExtClsInfo {
183 fn get_name(&self) -> Symbol {
184 self.name
185 }
186 fn get_fn(&self) -> ExtClsType {
187 self.fun.clone()
188 }
189}
190
191#[derive(Clone)]
192pub struct CommonFunction {
193 name: Symbol,
194 ty: TypeNodeId,
195 macro_fun: fn(&[(Value, TypeNodeId)]) -> Value,
196 fun: ExtFunType,
197}
198impl ExternalFunction for CommonFunction {
199 type Stage = PersistentStage;
200 fn get_type_info(&self) -> TypeNodeId {
201 self.ty
202 }
203 fn get_name(&self) -> Symbol {
204 self.name
205 }
206}
207impl MachineFunction for CommonFunction {
208 fn get_name(&self) -> Symbol {
209 self.name
210 }
211 fn get_fn(&self) -> ExtClsType {
212 Rc::new(RefCell::new(self.fun))
213 }
214}
215impl MacroFunction for CommonFunction {
216 fn get_name(&self) -> Symbol {
217 self.name
218 }
219 fn get_type(&self) -> TypeNodeId {
220 self.ty
221 }
222 fn get_fn(&self) -> MacroFunType {
223 Rc::new(RefCell::new(self.macro_fun))
224 }
225}
226#[derive(Clone, Copy)]
227pub struct ExtFunTypeInfo {
228 pub name: Symbol,
229 pub ty: TypeNodeId,
230 pub stage: EvalStage,
231}
232impl ExtFunTypeInfo {
233 pub fn new(name: Symbol, ty: TypeNodeId, stage: EvalStage) -> Self {
234 Self { name, ty, stage }
235 }
236}
237pub trait Plugin {
238 fn get_macro_functions(&self) -> Vec<Box<dyn MacroFunction>>;
239 fn get_ext_closures(&self) -> Vec<Box<dyn MachineFunction>>;
240
241 fn get_type_infos(&self) -> Vec<ExtFunTypeInfo>;
243}
244
245#[derive(Clone)]
246pub struct InstantPlugin {
247 pub macros: Vec<MacroInfo>,
248 pub extcls: Vec<ExtClsInfo>,
249 pub commonfns: Vec<CommonFunction>,
250}
251impl Plugin for InstantPlugin {
252 fn get_macro_functions(&self) -> Vec<Box<dyn MacroFunction>> {
256 let macros = self
257 .macros
258 .clone()
259 .into_iter()
260 .map(|m| Box::new(m) as Box<dyn MacroFunction>);
261 let commons = self
262 .commonfns
263 .clone()
264 .into_iter()
265 .map(|c| Box::new(c) as Box<dyn MacroFunction>);
266 macros.chain(commons).collect()
267 }
268
269 fn get_ext_closures(&self) -> Vec<Box<dyn MachineFunction>> {
270 let extfns = self
271 .extcls
272 .clone()
273 .into_iter()
274 .map(|e| Box::new(e) as Box<dyn MachineFunction>);
275 let commons = self
276 .commonfns
277 .clone()
278 .into_iter()
279 .map(|c| Box::new(c) as Box<dyn MachineFunction>);
280 extfns.chain(commons).collect()
281 }
282
283 fn get_type_infos(&self) -> Vec<ExtFunTypeInfo> {
284 let extcls_names: std::collections::HashSet<crate::interner::Symbol> =
288 self.extcls.iter().map(|e| e.name).collect();
289 let commons_names: std::collections::HashSet<crate::interner::Symbol> =
290 self.commonfns.iter().map(|c| c.name).collect();
291 let macros = self
292 .macros
293 .iter()
294 .filter(|m| !extcls_names.contains(&m.name) && !commons_names.contains(&m.name))
295 .map(|m| ExtFunTypeInfo::new(m.name, m.ty, MacroStage::get_stage()));
296 let extcls = self
297 .extcls
298 .iter()
299 .map(|e| ExtFunTypeInfo::new(e.name, e.ty, MachineStage::get_stage()));
300 let commons = self
301 .commonfns
302 .iter()
303 .map(|c| ExtFunTypeInfo::new(c.name, c.ty, PersistentStage::get_stage()));
304 macros.chain(extcls).chain(commons).collect()
305 }
306}
307
308pub trait UGenPlugin {
310 type InitParam;
311 type Args;
312 type Ret;
313 fn new(param: Self::InitParam) -> Self;
314 fn on_sample(&mut self, arg: Self::Args) -> Self::Ret;
315}
316pub fn get_extfun_types(plugins: &[Box<dyn Plugin>]) -> impl Iterator<Item = ExtFunTypeInfo> + '_ {
321 plugins
322 .iter()
323 .flat_map(|plugin| plugin.get_type_infos().into_iter())
324}
325
326pub fn get_macro_functions(
327 plugins: &[Box<dyn Plugin>],
328) -> impl Iterator<Item = Box<dyn MacroFunction>> + '_ {
329 plugins
330 .iter()
331 .flat_map(|plugin| plugin.get_macro_functions().into_iter())
332}
333pub fn get_ext_closures(
334 plugins: &[Box<dyn Plugin>],
335) -> impl Iterator<Item = Box<dyn MachineFunction>> + '_ {
336 plugins
337 .iter()
338 .flat_map(|plugin| plugin.get_ext_closures().into_iter())
339}
340
341pub(crate) type MonomorphizedExtFnNameResolver =
342 fn(Symbol, TypeNodeId, TypeNodeId) -> Option<Symbol>;
343
344const MONOMORPHIZED_EXT_FN_NAME_RESOLVERS: [MonomorphizedExtFnNameResolver; 1] =
345 [builtin_functins::try_get_monomorphized_ext_fn_name];
346
347pub(crate) fn resolve_monomorphized_ext_fn_name(
348 fn_name: Symbol,
349 concrete_arg_ty: TypeNodeId,
350 concrete_ret_ty: TypeNodeId,
351) -> Option<Symbol> {
352 MONOMORPHIZED_EXT_FN_NAME_RESOLVERS
353 .iter()
354 .find_map(|resolver| resolver(fn_name, concrete_arg_ty, concrete_ret_ty))
355}
356
357pub(crate) type SpecializedExtClsResolver = fn(Symbol, TypeNodeId) -> Option<ExtClsInfo>;
358
359const SPECIALIZED_EXTCLS_RESOLVERS: [SpecializedExtClsResolver; 1] =
360 [builtin_functins::try_make_specialized_extcls];
361
362pub(crate) fn try_make_specialized_extcls(name: Symbol, ty: TypeNodeId) -> Option<ExtClsInfo> {
363 SPECIALIZED_EXTCLS_RESOLVERS
364 .iter()
365 .find_map(|resolver| resolver(name, ty))
366}