1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use crate::*;
#[cfg(feature = "stdlib")]
use crate::function::table::*;
use hashbrown::{HashSet, HashMap};
#[derive(Clone, Debug)]
pub struct UserFunction {
pub name: u64,
pub inputs: HashMap<u64,ValueKind>,
pub outputs: HashMap<u64,ValueKind>,
pub transformations: Vec<Transformation>,
}
impl UserFunction {
pub fn new() -> UserFunction {
UserFunction {
name: 0,
inputs: HashMap::new(),
outputs: HashMap::new(),
transformations: Vec::new(),
}
}
pub fn compile(&self, block: &mut Block, arguments: &Vec<Argument>, out: &Out) -> Result<CompiledUserFunction,MechError> {
let mut fxn_block = Block::new();
fxn_block.functions = block.functions.clone();
fxn_block.user_functions = block.user_functions.clone();
for (arg_name, arg_table_id, indices) in arguments {
match self.inputs.get(arg_name) {
Some(kind) => {
let table_ref = block.get_table(arg_table_id)?;
let block_id = {table_ref.borrow().id.clone()};
fxn_block.tables.insert_table_ref(table_ref.clone());
let tfm = Transformation::TableAlias{
table_id: TableId::Local(block_id),
alias: *arg_name,
};
fxn_block.add_tfm(tfm);
},
_ => (),
}
}
let mut tfms = self.transformations.clone();
tfms.sort();
tfms.dedup();
for tfm in &tfms {
fxn_block.add_tfm(tfm.clone());
}
for (name,kind) in self.outputs.iter() {
let (out_table_id, _, _) = out;
let out_table_ref = block.get_table(out_table_id)?;
fxn_block.tables.insert_table_ref(out_table_ref.clone());
#[cfg(feature = "stdlib")]
fxn_block.add_tfm(Transformation::Function{
name: *TABLE_HORIZONTAL__CONCATENATE,
arguments: vec![(0,TableId::Local(*name),vec![(TableIndex::All,TableIndex::All)])],
out: (*out_table_id,TableIndex::All,TableIndex::All),
});
}
fxn_block.id = hash_str(&format!("{:?}{:?}{:?}",block.id,self.name,self.inputs));
let compiled_fxn = CompiledUserFunction{
name: self.name,
inputs: self.inputs.clone(),
outputs: self.outputs.clone(),
block: fxn_block
};
Ok(compiled_fxn)
}
}
#[derive(Clone, Debug)]
pub struct CompiledUserFunction {
pub name: u64,
pub inputs: HashMap<u64,ValueKind>,
pub outputs: HashMap<u64,ValueKind>,
pub block: Block,
}
impl MechFunction for CompiledUserFunction {
fn solve(&self) {
self.block.solve();
}
fn to_string(&self) -> String {
format!("{:?}", self.block)
}
}