Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ndc_stdlib/src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ fn vm_get_at_index(container: &Value, index_value: &Value, vm: &mut Vm) -> Resul
let Object::Function(f) = o.as_ref() else {
unreachable!()
};
let result = vm.call_callback(f.clone(), vec![])?;
let result = vm.call_callback(f.clone(), &[])?;
entries.borrow_mut().insert(key, result.clone());
Ok(result)
}
Expand Down
34 changes: 18 additions & 16 deletions ndc_stdlib/src/sequence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ mod inner {
if err.is_some() {
return Ordering::Equal;
}
match comp.call(vec![left.clone(), right.clone()]) {
match comp.call(&[left.clone(), right.clone()]) {
Ok(ret) => match ret.cmp_to_zero() {
Ok(ord) => ord,
Err(e) => {
Expand Down Expand Up @@ -288,7 +288,7 @@ mod inner {
if err.is_some() {
return Ordering::Equal;
}
match comp.call(vec![left.clone(), right.clone()]) {
match comp.call(&[left.clone(), right.clone()]) {
Ok(ret) => match ret.cmp_to_zero() {
Ok(ord) => ord,
Err(e) => {
Expand Down Expand Up @@ -376,7 +376,7 @@ mod inner {
.ok_or_else(|| anyhow!("filter requires a sequence"))?
{
match predicate
.call(vec![element.clone()])
.call(std::slice::from_ref(&element))
.map_err(|e| anyhow!(e))?
{
Value::Bool(true) => out.push(element),
Expand All @@ -394,7 +394,7 @@ mod inner {
.try_into_iter()
.ok_or_else(|| anyhow!("count requires a sequence"))?
{
match predicate.call(vec![element]).map_err(|e| anyhow!(e))? {
match predicate.call(&[element]).map_err(|e| anyhow!(e))? {
Value::Bool(true) => out += 1,
Value::Bool(false) => {}
_ => return Err(anyhow!("return value of predicate must be a boolean")),
Expand All @@ -410,7 +410,7 @@ mod inner {
.ok_or_else(|| anyhow!("find requires a sequence"))?
{
match predicate
.call(vec![element.clone()])
.call(std::slice::from_ref(&element))
.map_err(|e| anyhow!(e))?
{
Value::Bool(true) => return Ok(element),
Expand All @@ -428,7 +428,7 @@ mod inner {
.ok_or_else(|| anyhow!("locate requires a sequence"))?
.enumerate()
{
match predicate.call(vec![element]).map_err(|e| anyhow!(e))? {
match predicate.call(&[element]).map_err(|e| anyhow!(e))? {
Value::Bool(true) => return Ok(Value::Int(idx as i64)),
Value::Bool(false) => {}
_ => return Err(anyhow!("return value of predicate must be a boolean")),
Expand Down Expand Up @@ -458,7 +458,7 @@ mod inner {
.try_into_iter()
.ok_or_else(|| anyhow!("none requires a sequence"))?
{
match function.call(vec![item]).map_err(|e| anyhow!(e))? {
match function.call(&[item]).map_err(|e| anyhow!(e))? {
Value::Bool(true) => return Ok(Value::Bool(false)),
Value::Bool(false) => {}
v => {
Expand All @@ -479,7 +479,7 @@ mod inner {
.try_into_iter()
.ok_or_else(|| anyhow!("all requires a sequence"))?
{
match function.call(vec![item]).map_err(|e| anyhow!(e))? {
match function.call(&[item]).map_err(|e| anyhow!(e))? {
Value::Bool(true) => {}
Value::Bool(false) => return Ok(Value::Bool(false)),
v => {
Expand All @@ -499,7 +499,7 @@ mod inner {
.try_into_iter()
.ok_or_else(|| anyhow!("any requires a sequence"))?
{
match predicate.call(vec![item]).map_err(|e| anyhow!(e))? {
match predicate.call(&[item]).map_err(|e| anyhow!(e))? {
Value::Bool(true) => return Ok(Value::Bool(true)),
Value::Bool(false) => {}
v => {
Expand All @@ -521,7 +521,7 @@ mod inner {
.try_into_iter()
.ok_or_else(|| anyhow!("map requires a sequence"))?
{
out.push(function.call(vec![item]).map_err(|e| anyhow!(e))?);
out.push(function.call(&[item]).map_err(|e| anyhow!(e))?);
}
Ok(Value::list(out))
}
Expand All @@ -534,7 +534,7 @@ mod inner {
.try_into_iter()
.ok_or_else(|| anyhow!("flat_map requires a sequence"))?
{
let result = function.call(vec![item]).map_err(|e| anyhow!(e))?;
let result = function.call(&[item]).map_err(|e| anyhow!(e))?;
let inner = result
.try_into_iter()
.ok_or_else(|| anyhow!("callable argument to flat_map must return a sequence"))?;
Expand All @@ -555,7 +555,7 @@ mod inner {
if let Some(item) = seq.try_into_iter().and_then(|mut i| i.next()) {
return Ok(item);
}
default.call(vec![]).map_err(|e| anyhow!(e))
default.call(&[]).map_err(|e| anyhow!(e))
}

/// Returns the `k` sized combinations of the given sequence `seq` as a lazy iterator of tuples.
Expand Down Expand Up @@ -700,7 +700,7 @@ mod inner {
.collect();
let mut out = Vec::with_capacity(main.len().saturating_sub(1));
for (a, b) in main.into_iter().tuple_windows() {
out.push(function.call(vec![a, b]).map_err(|e| anyhow!(e))?);
out.push(function.call(&[a, b]).map_err(|e| anyhow!(e))?);
}
Ok(Value::list(out))
}
Expand Down Expand Up @@ -837,7 +837,9 @@ fn by_key(seq: Value, func: &mut VmCallable<'_>, better: Ordering) -> anyhow::Re
.try_into_iter()
.ok_or_else(|| anyhow!("sequence is required"))?
{
let new_key = func.call(vec![value.clone()]).map_err(|e| anyhow!(e))?;
let new_key = func
.call(std::slice::from_ref(&value))
.map_err(|e| anyhow!(e))?;
let is_better = match &best_key {
None => true,
Some(current_best) => {
Expand Down Expand Up @@ -865,7 +867,7 @@ fn by_comp(seq: Value, comp: &mut VmCallable<'_>, better: Ordering) -> anyhow::R
None => true,
Some(current) => {
let result = comp
.call(vec![value.clone(), current.clone()])
.call(&[value.clone(), current.clone()])
.map_err(|e| anyhow!(e))?;
result.cmp_to_zero().map_err(|e| anyhow!(e))? == better
}
Expand All @@ -884,7 +886,7 @@ fn fold_iterator(
) -> anyhow::Result<Value> {
let mut acc = initial;
for item in iter {
acc = function.call(vec![acc, item]).map_err(|e| anyhow!(e))?;
acc = function.call(&[acc, item]).map_err(|e| anyhow!(e))?;
}
Ok(acc)
}
Expand Down
18 changes: 8 additions & 10 deletions ndc_vm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ impl Vm {
/// uses `call_callback` instead, which runs inline on the parent VM.
pub fn call_function(
func: Function,
args: Vec<Value>,
args: &[Value],
globals: Vec<Value>,
) -> Result<Value, VmError> {
let mut vm = Self {
Expand All @@ -713,17 +713,17 @@ impl Vm {
/// Call a function inline on this VM, without spawning a child VM.
/// Used by `VmCallable::call` so stdlib HOFs run their predicates/mappers
/// directly on the parent stack — zero allocation per callback invocation.
pub fn call_callback(&mut self, func: Function, args: Vec<Value>) -> Result<Value, VmError> {
pub fn call_callback(&mut self, func: Function, args: &[Value]) -> Result<Value, VmError> {
if let Function::Native(native) = func {
match &native.func {
NativeFunc::Simple(f) => f(&args),
NativeFunc::WithVm(f) => f(&args, self),
NativeFunc::Simple(f) => f(args),
NativeFunc::WithVm(f) => f(args, self),
}
} else {
let depth = self.frames.len();
let n = args.len();
self.stack.push(Value::unit()); // dummy callee slot
self.stack.extend(args);
self.stack.extend(args.iter().cloned());
self.dispatch_call_with_memo(func, n, None)?;
self.run_to_depth(depth)?;
Ok(self.stack.pop().expect("callback must produce a value"))
Expand Down Expand Up @@ -945,8 +945,7 @@ impl Vm {
f
};

let call_args = std::mem::replace(&mut elem_args, Vec::with_capacity(args));
let result = self.call_callback(scalar, call_args).map_err(|mut e| {
let result = self.call_callback(scalar, &elem_args).map_err(|mut e| {
let prefix = match &callee_name {
Some(name) => format!("while vectorising '{name}' at index {i}: "),
None => format!("while vectorising at index {i}: "),
Expand Down Expand Up @@ -1028,8 +1027,7 @@ impl Vm {
found.clone()
};

let call_args = std::mem::replace(&mut elem_args, Vec::with_capacity(args));
let result = self.call_callback(scalar, call_args).map_err(|mut e| {
let result = self.call_callback(scalar, &elem_args).map_err(|mut e| {
let prefix = match &callee_name {
Some(name) => format!("while vectorising '{name}' at index {i}: "),
None => format!("while vectorising at index {i}: "),
Expand Down Expand Up @@ -1202,7 +1200,7 @@ pub struct VmCallable<'a> {
impl VmCallable<'_> {
/// Call this function with the given arguments, running inline on the
/// parent VM.
pub fn call(&mut self, args: Vec<Value>) -> Result<Value, VmError> {
pub fn call(&mut self, args: &[Value]) -> Result<Value, VmError> {
self.vm.call_callback(self.function.clone(), args)
}
}
Loading