Simplify tuple flattening and destructuring
The `flatten_tuple` function was unnecessarily recursive. It can now simply return the elements of the tuple directly. The VM's destructuring logic has been updated to handle nested destructuring more efficiently. A new integration test case for multi-level destructuring has been added.
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
(do
|
||||||
|
(def pipe (fn [conf]
|
||||||
|
(do
|
||||||
|
(def [str s] conf)
|
||||||
|
(def [f ss] s)
|
||||||
|
["Symbol:" str "field:" f "id:" ss]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(pipe ["btc" [:close "cls"]])
|
||||||
|
)
|
||||||
@@ -308,13 +308,7 @@ impl Specializer {
|
|||||||
|
|
||||||
fn flatten_tuple(&self, node: AnalyzedNode) -> Vec<AnalyzedNode> {
|
fn flatten_tuple(&self, node: AnalyzedNode) -> Vec<AnalyzedNode> {
|
||||||
match node.kind {
|
match node.kind {
|
||||||
BoundKind::Tuple { elements } => {
|
BoundKind::Tuple { elements } => elements,
|
||||||
let mut flat = Vec::new();
|
|
||||||
for el in elements {
|
|
||||||
flat.extend(self.flatten_tuple(el));
|
|
||||||
}
|
|
||||||
flat
|
|
||||||
}
|
|
||||||
_ => vec![node],
|
_ => vec![node],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-1
@@ -416,7 +416,15 @@ impl VM {
|
|||||||
{
|
{
|
||||||
self.stack.extend(arg_vals);
|
self.stack.extend(arg_vals);
|
||||||
} else {
|
} else {
|
||||||
self.unpack(&closure.parameter_node, &arg_vals, &mut 0)?;
|
// Map each parameter pattern to the provided arguments
|
||||||
|
if let BoundKind::Tuple { elements } = &closure.parameter_node.kind {
|
||||||
|
let mut offset = 0;
|
||||||
|
for el in elements {
|
||||||
|
self.unpack(el, &arg_vals, &mut offset)?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.unpack(&closure.parameter_node, &arg_vals, &mut 0)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let result = self.eval_internal(obs, &closure.exec_node);
|
let result = self.eval_internal(obs, &closure.exec_node);
|
||||||
self.frames.pop();
|
self.frames.pop();
|
||||||
|
|||||||
@@ -369,4 +369,25 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_multi_level_destructuring() {
|
||||||
|
let env = Environment::new();
|
||||||
|
let source = "(do
|
||||||
|
(def pipe (fn [conf]
|
||||||
|
(do
|
||||||
|
(def [str s] conf)
|
||||||
|
(def [f ss] s)
|
||||||
|
[\"Symbol:\" str \"field:\" f \"id:\" ss]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(pipe [\"btc\" [:close \"cls\"]]))";
|
||||||
|
|
||||||
|
let res = env.run_script(source).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
format!("{}", res),
|
||||||
|
"[\"Symbol:\" \"btc\" \"field:\" :close \"id:\" \"cls\"]"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user