|
1 |
| -use crate::{SigNode, Uiua, UiuaResult, Value}; |
| 1 | +use crate::{Primitive, SigNode, Uiua, UiuaResult, Value}; |
2 | 2 |
|
3 | 3 | pub fn recur(is_leaf: SigNode, children: SigNode, combine: SigNode, env: &mut Uiua) -> UiuaResult {
|
4 | 4 | // Signature validation
|
@@ -26,23 +26,27 @@ pub fn recur(is_leaf: SigNode, children: SigNode, combine: SigNode, env: &mut Ui
|
26 | 26 | children.sig
|
27 | 27 | )));
|
28 | 28 | }
|
29 |
| - if combine.sig.args() == 0 { |
30 |
| - return Err(env.error(format!( |
31 |
| - "Combine function must have at least 1 argument, but its signature is {}", |
32 |
| - combine.sig |
33 |
| - ))); |
34 |
| - } |
35 |
| - if combine.sig.outputs() != 1 { |
36 |
| - return Err(env.error(format!( |
37 |
| - "Combine function must have 1 output, but its signature is {}", |
38 |
| - combine.sig |
39 |
| - ))); |
| 29 | + if combine.sig != (0, 0) { |
| 30 | + if combine.sig.args() == 0 { |
| 31 | + return Err(env.error(format!( |
| 32 | + "Combine function must have at least 1 argument, but its signature is {}", |
| 33 | + combine.sig |
| 34 | + ))); |
| 35 | + } |
| 36 | + if combine.sig.outputs() != 1 { |
| 37 | + return Err(env.error(format!( |
| 38 | + "Combine function must have 1 output, but its signature is {}", |
| 39 | + combine.sig |
| 40 | + ))); |
| 41 | + } |
40 | 42 | }
|
| 43 | + let call_combine = |
| 44 | + !(combine.node.is_empty() || combine.node.as_primitive() == Some(Primitive::Identity)); |
41 | 45 |
|
42 | 46 | // State initialization
|
43 | 47 | let arg_count = (is_leaf.sig.args())
|
44 | 48 | .max(children.sig.args())
|
45 |
| - .max(combine.sig.args() - 1); |
| 49 | + .max(combine.sig.args().saturating_sub(1)); |
46 | 50 | let const_count = arg_count - 1;
|
47 | 51 | let initial = env.pop(1)?;
|
48 | 52 | let mut consts = Vec::with_capacity(const_count);
|
@@ -99,12 +103,16 @@ pub fn recur(is_leaf: SigNode, children: SigNode, combine: SigNode, env: &mut Ui
|
99 | 103 | } else {
|
100 | 104 | Value::from_row_values(child_nodes, env)?
|
101 | 105 | };
|
102 |
| - env.push(children_value); |
103 |
| - if combine.sig.args() > 1 { |
104 |
| - env.push(value); |
| 106 | + if call_combine { |
| 107 | + env.push(children_value); |
| 108 | + if combine.sig.args() > 1 { |
| 109 | + env.push(value); |
| 110 | + } |
| 111 | + env.exec(combine.clone())?; |
| 112 | + value = env.pop("combined")?; |
| 113 | + } else { |
| 114 | + value = children_value; |
105 | 115 | }
|
106 |
| - env.exec(combine.clone())?; |
107 |
| - value = env.pop("combined")?; |
108 | 116 | if let Some(parent) = parent {
|
109 | 117 | stack[parent].child_nodes.as_mut().unwrap().push(value);
|
110 | 118 | } else {
|
|
0 commit comments