Skip to content

Commit 228894d

Browse files
committed
change how bracket packs work
1 parent 2215933 commit 228894d

File tree

5 files changed

+43
-35
lines changed

5 files changed

+43
-35
lines changed

src/check.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,8 +375,10 @@ impl VirtualEnv {
375375
self.handle_args_outputs(f.args().max(g.args()), f.outputs() + g.outputs());
376376
}
377377
Bracket => {
378-
let [f, g] = get_args(args)?;
379-
self.handle_args_outputs(f.args() + g.args(), f.outputs() + g.outputs());
378+
let (args, outputs) = args.iter().fold((0, 0), |(a, o), sn| {
379+
(a + sn.sig.args(), o + sn.sig.outputs())
380+
});
381+
self.handle_args_outputs(args, outputs);
380382
}
381383
Both => {
382384
let [f] = get_args_nodes(args)?;
@@ -490,8 +492,10 @@ impl VirtualEnv {
490492
}
491493
UnFill | SidedFill(_) => self.fill(args)?,
492494
UnBracket => {
493-
let [f, g] = get_args(args)?;
494-
self.handle_args_outputs(f.args() + g.args(), f.outputs() + g.outputs());
495+
let (args, outputs) = args.iter().fold((0, 0), |(a, o), sn| {
496+
(a + sn.sig.args(), o + sn.sig.outputs())
497+
});
498+
self.handle_args_outputs(args, outputs);
495499
}
496500
BothImpl(sub) | UnBothImpl(sub) => {
497501
let [f] = get_args(args)?;

src/compile/data.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,8 @@ impl Compiler {
360360
.map(|f| f.init.as_ref().map(|sn| sn.sig.args()).unwrap_or(1))
361361
.sum();
362362
let mut node = if has_fields {
363-
let mut inner = Node::default();
364-
let mut sig = Signature::new(0, 0);
365-
for field in fields.iter().rev() {
363+
let mut field_nodes = EcoVec::with_capacity(fields.len());
364+
for field in &fields {
366365
let mut arg = if let Some(sn) = &field.init {
367366
sn.clone()
368367
} else {
@@ -378,18 +377,11 @@ impl Compiler {
378377
Node::ImplPrim(ImplPrimitive::ValidateNonBoxedVariant, field.span).into(),
379378
));
380379
}
381-
if !inner.is_empty() {
382-
for _ in 0..arg.sig.args() {
383-
inner = Node::Mod(Primitive::Dip, eco_vec![SigNode::new(sig, inner)], span);
384-
}
385-
}
386-
sig.update_args(|a| a + arg.sig.args());
387-
sig.update_outputs(|o| o + arg.sig.outputs());
388-
inner.push(arg.node);
380+
field_nodes.push(arg);
389381
}
390382
let mut node = Node::Array {
391383
len: fields.len(),
392-
inner: inner.into(),
384+
inner: Node::Mod(Primitive::Bracket, field_nodes, span).into(),
393385
boxed,
394386
allow_ext: true,
395387
prim: None,

src/compile/invert/un.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -465,10 +465,12 @@ inverse!(
465465
}
466466
);
467467

468-
inverse!(BracketPat, input, asm, Bracket, span, [f, g], {
469-
let f_inv = f.un_inverse(asm)?;
470-
let g_inv = g.un_inverse(asm)?;
471-
Ok((input, ImplMod(UnBracket, eco_vec![f_inv, g_inv], span)))
468+
inverse!(BracketPat, input, asm, Bracket, span, args, {
469+
let mut inv_args = EcoVec::with_capacity(args.len());
470+
for sn in args {
471+
inv_args.push(sn.un_inverse(asm)?);
472+
}
473+
Ok((input, ImplMod(UnBracket, inv_args, span)))
472474
});
473475

474476
inverse!(OnPat, input, asm, On, span, [f], {

src/compile/modifier.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,7 @@ impl Compiler {
9999
}
100100
self.modified_impl(new, subscript)
101101
}
102-
Modifier::Primitive(
103-
Primitive::Fork | Primitive::Bracket | Primitive::Try | Primitive::Fill,
104-
) => {
102+
Modifier::Primitive(Primitive::Fork | Primitive::Try | Primitive::Fill) => {
105103
let mut branches = pack.lexical_order().cloned().rev();
106104
let mut new = Modified {
107105
modifier: modifier.clone(),
@@ -402,6 +400,7 @@ impl Compiler {
402400
}
403401
} else {
404402
let strict_args = match &modified.modifier.value {
403+
Modifier::Primitive(Primitive::Bracket) => false,
405404
Modifier::Primitive(_) => true,
406405
Modifier::Macro(..) => false,
407406
Modifier::Ref(name) => self
@@ -641,7 +640,7 @@ impl Compiler {
641640
modified.modifier.span.clone().merge(sub.span),
642641
format!(
643642
"Sided {}'s functions must both have 2 arguments, \
644-
but their signatures are {} and {}.",
643+
but their signatures are {} and {}.",
645644
Primitive::Bracket.format(),
646645
a.sig,
647646
b.sig

src/run_prim.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
use ecow::EcoVec;
66
use regex::Regex;
7+
use smallvec::SmallVec;
78

89
use core::str;
910
use std::{
@@ -350,7 +351,7 @@ pub fn run_prim_func(prim: &Primitive, env: &mut Uiua) -> UiuaResult {
350351
Ok(())
351352
}
352353
/// Execute a primitive as a modifier
353-
pub fn run_prim_mod(prim: &Primitive, ops: Ops, env: &mut Uiua) -> UiuaResult {
354+
pub fn run_prim_mod(prim: &Primitive, mut ops: Ops, env: &mut Uiua) -> UiuaResult {
354355
match prim {
355356
// Looping
356357
Primitive::Reduce => reduce::reduce(ops, 0, env)?,
@@ -388,11 +389,17 @@ pub fn run_prim_mod(prim: &Primitive, ops: Ops, env: &mut Uiua) -> UiuaResult {
388389
env.exec(f)?;
389390
}
390391
Primitive::Bracket => {
391-
let [f, g] = get_ops(ops, env)?;
392-
let vals = env.pop_n(f.sig.args())?;
393-
env.exec(g)?;
394-
env.push_all(vals);
395-
env.exec(f)?;
392+
let mut args: SmallVec<[Vec<Value>; 3]> = SmallVec::new();
393+
for sn in ops.iter().rev().skip(1).rev() {
394+
args.push(env.pop_n(sn.sig.args())?);
395+
}
396+
if let Some(last) = ops.pop() {
397+
env.exec(last)?;
398+
}
399+
for (sn, args) in ops.into_iter().zip(args).rev() {
400+
env.push_all(args);
401+
env.exec(sn)?;
402+
}
396403
}
397404
Primitive::Both => {
398405
let [f] = get_ops(ops, env)?;
@@ -1305,11 +1312,15 @@ impl ImplPrimitive {
13051312
&ImplPrimitive::SidedFill(side) => fill!(ops, side, env, with_fill, without_fill_but),
13061313
ImplPrimitive::ReduceTable => table::reduce_table(ops, env)?,
13071314
ImplPrimitive::UnBracket => {
1308-
let [f, g] = get_ops(ops, env)?;
1309-
env.exec(f.node)?;
1310-
let f_outputs = env.pop_n(f.sig.outputs())?;
1311-
env.exec(g.node)?;
1312-
env.push_all(f_outputs);
1315+
let mut outputs: SmallVec<[Vec<Value>; 3]> = SmallVec::new();
1316+
for sn in ops {
1317+
let o = sn.sig.outputs();
1318+
env.exec(sn)?;
1319+
outputs.push(env.pop_n(o)?);
1320+
}
1321+
for outputs in outputs.into_iter().rev() {
1322+
env.push_all(outputs);
1323+
}
13131324
}
13141325
ImplPrimitive::SplitByScalar => {
13151326
let [f] = get_ops(ops, env)?;

0 commit comments

Comments
 (0)