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:
@@ -1,5 +1,5 @@
|
||||
;; Benchmark: 969ns
|
||||
;; Benchmark-Repeat: 2078
|
||||
;; Benchmark: 969ns
|
||||
;; Benchmark-Repeat: 2078
|
||||
;; Comprehensive Destructuring Test
|
||||
;; Covers: Nested tuples, mixed params, dynamic passing
|
||||
|
||||
|
||||
@@ -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> {
|
||||
match node.kind {
|
||||
BoundKind::Tuple { elements } => {
|
||||
let mut flat = Vec::new();
|
||||
for el in elements {
|
||||
flat.extend(self.flatten_tuple(el));
|
||||
}
|
||||
flat
|
||||
}
|
||||
BoundKind::Tuple { elements } => elements,
|
||||
_ => vec![node],
|
||||
}
|
||||
}
|
||||
|
||||
+9
-1
@@ -416,7 +416,15 @@ impl VM {
|
||||
{
|
||||
self.stack.extend(arg_vals);
|
||||
} 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);
|
||||
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