Skip to content

Commit fde8387

Browse files
committed
WIP: adding back vectorization for the 12th time
1 parent e112950 commit fde8387

4 files changed

Lines changed: 73 additions & 25 deletions

File tree

ndc_lib/src/interpreter/evaluate/mod.rs

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ pub(crate) fn evaluate_expression(
120120
);
121121
};
122122
// (&func, &mut arguments, environment, span)
123-
let result = match func.borrow().call_checked(&mut arguments, environment) {
123+
let result = match func.call_checked(&mut arguments, environment) {
124124
Err(FunctionCarrier::FunctionTypeMismatch)
125125
if operations_to_try.peek().is_none() =>
126126
{
@@ -190,7 +190,7 @@ pub(crate) fn evaluate_expression(
190190
);
191191
};
192192

193-
let result = match func.borrow().call_checked(
193+
let result = match func.call_checked(
194194
&mut [value_at_index.clone(), right_value.clone()],
195195
environment,
196196
) {
@@ -328,20 +328,17 @@ pub(crate) fn evaluate_expression(
328328
arguments,
329329
} => {
330330
let mut evaluated_args = Vec::new();
331-
let mut arg_types = Vec::new();
332331

333332
for argument in arguments {
334333
let arg = evaluate_expression(argument, environment)?;
335-
arg_types.push(arg.static_type());
336334
evaluated_args.push(arg);
337335
}
338336

339-
let function_as_value = evaluate_as_function(function, &arg_types, environment)?;
337+
let function_as_value = resolve_and_call(function, &arg_types, environment)?;
340338

341339
return if let Value::Function(function) = function_as_value {
342340
// Here we should be able to call without checking types
343341
function
344-
.borrow()
345342
.call(&mut evaluated_args, environment)
346343
.add_span(span)
347344
} else {
@@ -671,7 +668,7 @@ fn produce_default_value(
671668
) -> EvaluationResult {
672669
match default {
673670
Value::Function(function) => {
674-
match function.borrow().call_checked(&mut [], environment) {
671+
match function.call_checked(&mut [], environment) {
675672
Err(FunctionCarrier::FunctionTypeMismatch) => {
676673
Err(FunctionCarrier::EvaluationError(EvaluationError::new(
677674
"default function is not callable without arguments".to_string(),
@@ -981,26 +978,77 @@ fn execute_for_iterations(
981978
Ok(Value::unit())
982979
}
983980

984-
fn evaluate_as_function(
981+
// fn evaluate_as_function(
982+
// function_expression: &ExpressionLocation,
983+
// arg_types: &[StaticType],
984+
// environment: &Rc<RefCell<Environment>>,
985+
// ) -> EvaluationResult {
986+
// let ExpressionLocation { expression, .. } = function_expression;
987+
//
988+
// if let Expression::Identifier { resolved, .. } = expression {
989+
// resolve_dynamic_binding(resolved, arg_types, environment).ok_or_else(|| {
990+
// FunctionCarrier::EvaluationError(EvaluationError::new(
991+
// format!(
992+
// "Failed to find a function that can handle the arguments ({}) at runtime",
993+
// arg_types.iter().join(", ")
994+
// ),
995+
// function_expression.span,
996+
// ))
997+
// })
998+
// } else {
999+
// evaluate_expression(function_expression, environment)
1000+
// }
1001+
// }
1002+
1003+
fn resolve_and_call(
9851004
function_expression: &ExpressionLocation,
986-
arg_types: &[StaticType],
1005+
args: &mut [Value],
9871006
environment: &Rc<RefCell<Environment>>,
9881007
) -> EvaluationResult {
1008+
////////////////////////////
9891009
let ExpressionLocation { expression, .. } = function_expression;
9901010

991-
if let Expression::Identifier { resolved, .. } = expression {
992-
resolve_dynamic_binding(resolved, arg_types, environment).ok_or_else(|| {
1011+
let function = if let Expression::Identifier { resolved, .. } = expression {
1012+
let arg_types = args.iter().map(|arg| arg.static_type()).collect::<Vec<_>>();
1013+
1014+
let opt = match resolved {
1015+
Binding::None => None,
1016+
Binding::Resolved(var) => Some(environment.borrow().get(*var)),
1017+
Binding::Dynamic(dynamic_binding) => dynamic_binding
1018+
.iter() // TODO: should we consider the binding order?
1019+
.find_map(|binding| {
1020+
let value = environment.borrow().get(*binding);
1021+
1022+
let Value::Function(fun) = &value else {
1023+
panic!("dynamic binding resolved to non-function type at runtime");
1024+
};
1025+
1026+
// Find the first function that matches
1027+
if fun.static_type().is_fn_and_matches(&arg_types) {
1028+
return Some(value);
1029+
}
1030+
1031+
None
1032+
}),
1033+
};
1034+
opt.ok_or_else(|| {
9931035
FunctionCarrier::EvaluationError(EvaluationError::new(
9941036
format!(
9951037
"Failed to find a function that can handle the arguments ({}) at runtime",
9961038
arg_types.iter().join(", ")
9971039
),
9981040
function_expression.span,
9991041
))
1000-
})
1042+
})?
10011043
} else {
1002-
evaluate_expression(function_expression, environment)
1003-
}
1044+
evaluate_expression(function_expression, environment)?
1045+
};
1046+
1047+
////////////////////////////
1048+
////////////////////////////
1049+
////////////////////////////
1050+
1051+
todo!();
10041052
}
10051053

10061054
fn resolve_dynamic_binding(
@@ -1021,11 +1069,11 @@ fn resolve_dynamic_binding(
10211069
};
10221070

10231071
// Find the first function that matches
1024-
if fun.borrow().static_type().is_fn_and_matches(arg_types) {
1025-
Some(value)
1026-
} else {
1027-
None
1072+
if fun.static_type().is_fn_and_matches(arg_types) {
1073+
return Some(value);
10281074
}
1075+
1076+
None
10291077
}),
10301078
}
10311079
}

ndc_lib/src/interpreter/function.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ use std::rc::Rc;
1818
/// Callable is a wrapper around a `OverloadedFunction` pointer and the environment to make it
1919
/// easy to have an executable function as a method signature in the standard library
2020
pub struct Callable<'a> {
21-
pub function: Rc<RefCell<Function>>,
21+
pub function: Rc<Function>,
2222
pub environment: &'a Rc<RefCell<Environment>>,
2323
}
2424

2525
impl Callable<'_> {
2626
pub fn call(&self, args: &mut [Value]) -> EvaluationResult {
27-
self.function.borrow().call(args, self.environment)
27+
self.function.call(args, self.environment)
2828
}
2929
}
3030

ndc_lib/src/interpreter/value.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ pub enum Value {
2525
Number(Number),
2626
Bool(bool),
2727
Sequence(Sequence),
28-
Function(Rc<RefCell<Function>>),
28+
Function(Rc<Function>),
2929
}
3030

3131
impl Value {
3232
pub(crate) fn function(function: Function) -> Self {
33-
Self::Function(Rc::new(RefCell::new(function)))
33+
Self::Function(Rc::new(function))
3434
}
3535
pub(crate) fn string<S: Into<String>>(string: S) -> Self {
3636
Self::Sequence(Sequence::String(Rc::new(RefCell::new(string.into()))))
@@ -158,7 +158,7 @@ impl Value {
158158
Self::Bool(_) => StaticType::Bool,
159159

160160
Self::Sequence(s) => s.static_type(),
161-
Self::Function(fun) => fun.borrow().static_type(),
161+
Self::Function(fun) => fun.static_type(),
162162
}
163163
}
164164

ndc_lib/src/stdlib/value.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ mod inner {
1616
pub fn docs(func: &Callable<'_>) -> anyhow::Result<String> {
1717
let mut buf = String::new();
1818

19-
let sig = func.function.borrow().type_signature();
20-
let fun = func.function.borrow();
19+
let sig = func.function.type_signature();
20+
let fun = &func.function;
2121

2222
if fun.name().is_empty() {
2323
write!(buf, "fn({sig})")?;

0 commit comments

Comments
 (0)